summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.bzrignore2
-rw-r--r--BitKeeper/etc/collapsed4
-rw-r--r--client/mysql.cc67
-rw-r--r--client/mysqlbinlog.cc35
-rw-r--r--client/mysqldump.c22
-rw-r--r--client/mysqltest.c16
-rw-r--r--configure.in2
-rw-r--r--extra/Makefile.am13
-rw-r--r--extra/yassl/CMakeLists.txt2
-rw-r--r--extra/yassl/FLOSS-EXCEPTIONS3
-rw-r--r--extra/yassl/Makefile.am2
-rw-r--r--extra/yassl/README13
-rw-r--r--extra/yassl/examples/client/client.cpp31
-rw-r--r--extra/yassl/examples/echoclient/echoclient.cpp15
-rw-r--r--extra/yassl/examples/echoserver/echoserver.cpp35
-rw-r--r--extra/yassl/examples/server/server.cpp27
-rw-r--r--extra/yassl/include/buffer.hpp7
-rw-r--r--extra/yassl/include/cert_wrapper.hpp11
-rw-r--r--extra/yassl/include/crypto_wrapper.hpp12
-rw-r--r--extra/yassl/include/factory.hpp18
-rw-r--r--extra/yassl/include/openssl/ssl.h4
-rw-r--r--extra/yassl/include/socket_wrapper.hpp2
-rw-r--r--extra/yassl/include/yassl_error.hpp6
-rw-r--r--extra/yassl/include/yassl_imp.hpp7
-rw-r--r--extra/yassl/include/yassl_int.hpp106
-rw-r--r--extra/yassl/include/yassl_types.hpp38
-rw-r--r--extra/yassl/src/Makefile.am6
-rw-r--r--extra/yassl/src/cert_wrapper.cpp31
-rw-r--r--extra/yassl/src/crypto_wrapper.cpp35
-rw-r--r--extra/yassl/src/handshake.cpp83
-rw-r--r--extra/yassl/src/socket_wrapper.cpp12
-rw-r--r--extra/yassl/src/ssl.cpp209
-rw-r--r--extra/yassl/src/template_instnt.cpp18
-rw-r--r--extra/yassl/src/yassl.cpp12
-rw-r--r--extra/yassl/src/yassl_error.cpp14
-rw-r--r--extra/yassl/src/yassl_imp.cpp46
-rw-r--r--extra/yassl/src/yassl_int.cpp249
-rw-r--r--extra/yassl/taocrypt/CMakeLists.txt2
-rw-r--r--extra/yassl/taocrypt/COPYING340
-rw-r--r--extra/yassl/taocrypt/INSTALL229
-rw-r--r--extra/yassl/taocrypt/Makefile.am2
-rw-r--r--extra/yassl/taocrypt/README37
-rw-r--r--extra/yassl/taocrypt/benchmark/Makefile.am6
-rw-r--r--extra/yassl/taocrypt/include/asn.hpp6
-rw-r--r--extra/yassl/taocrypt/include/block.hpp12
-rw-r--r--extra/yassl/taocrypt/include/blowfish.hpp6
-rw-r--r--extra/yassl/taocrypt/include/error.hpp4
-rw-r--r--extra/yassl/taocrypt/include/file.hpp2
-rw-r--r--extra/yassl/taocrypt/include/integer.hpp2
-rw-r--r--extra/yassl/taocrypt/include/misc.hpp17
-rw-r--r--extra/yassl/taocrypt/include/pwdbased.hpp2
-rw-r--r--extra/yassl/taocrypt/include/twofish.hpp6
-rw-r--r--extra/yassl/taocrypt/mySTL/algorithm.hpp (renamed from extra/yassl/mySTL/algorithm.hpp)2
-rw-r--r--extra/yassl/taocrypt/mySTL/helpers.hpp (renamed from extra/yassl/mySTL/helpers.hpp)41
-rw-r--r--extra/yassl/taocrypt/mySTL/list.hpp (renamed from extra/yassl/mySTL/list.hpp)151
-rw-r--r--extra/yassl/taocrypt/mySTL/memory.hpp (renamed from extra/yassl/mySTL/memory.hpp)29
-rw-r--r--extra/yassl/taocrypt/mySTL/memory_array.hpp142
-rw-r--r--extra/yassl/taocrypt/mySTL/pair.hpp (renamed from extra/yassl/mySTL/pair.hpp)0
-rw-r--r--extra/yassl/taocrypt/mySTL/stdexcept.hpp (renamed from extra/yassl/mySTL/stdexcept.hpp)0
-rw-r--r--extra/yassl/taocrypt/mySTL/vector.hpp (renamed from extra/yassl/mySTL/vector.hpp)13
-rw-r--r--extra/yassl/taocrypt/src/Makefile.am6
-rw-r--r--extra/yassl/taocrypt/src/algebra.cpp15
-rw-r--r--extra/yassl/taocrypt/src/asn.cpp9
-rw-r--r--extra/yassl/taocrypt/src/blowfish.cpp2
-rw-r--r--extra/yassl/taocrypt/src/crypto.cpp39
-rw-r--r--extra/yassl/taocrypt/src/des.cpp9
-rw-r--r--extra/yassl/taocrypt/src/dh.cpp2
-rw-r--r--extra/yassl/taocrypt/src/integer.cpp12
-rw-r--r--extra/yassl/taocrypt/src/md4.cpp10
-rw-r--r--extra/yassl/taocrypt/src/md5.cpp11
-rw-r--r--extra/yassl/taocrypt/src/misc.cpp9
-rw-r--r--extra/yassl/taocrypt/src/random.cpp68
-rw-r--r--extra/yassl/taocrypt/src/ripemd.cpp10
-rw-r--r--extra/yassl/taocrypt/src/sha.cpp11
-rw-r--r--extra/yassl/taocrypt/src/template_instnt.cpp7
-rw-r--r--extra/yassl/taocrypt/test/Makefile.am6
-rw-r--r--extra/yassl/testsuite/Makefile.am11
-rw-r--r--extra/yassl/testsuite/test.hpp51
-rw-r--r--include/base64.h3
-rw-r--r--include/heap.h1
-rw-r--r--include/m_ctype.h15
-rw-r--r--include/m_string.h3
-rw-r--r--include/my_global.h42
-rw-r--r--include/my_sys.h5
-rw-r--r--include/mysql/plugin.h11
-rw-r--r--include/mysql_com.h13
-rw-r--r--mysql-test/Makefile.am14
-rw-r--r--mysql-test/extra/binlog_tests/binlog_insert_delayed.test42
-rw-r--r--mysql-test/extra/rpl_tests/rpl_insert_id.test146
-rw-r--r--mysql-test/extra/rpl_tests/rpl_row_basic.test (renamed from mysql-test/include/rpl_row_basic.inc)0
-rw-r--r--mysql-test/include/have_ndb.inc8
-rw-r--r--mysql-test/include/wait_until_connected_again.inc2
-rw-r--r--mysql-test/include/wait_until_rows_count.inc52
-rw-r--r--mysql-test/lib/mtr_cases.pl16
-rw-r--r--mysql-test/lib/mtr_im.pl761
-rw-r--r--mysql-test/lib/mtr_process.pl714
-rw-r--r--mysql-test/mysql-test-run-shell.sh (renamed from mysql-test/mysql-test-run.sh)0
-rwxr-xr-xmysql-test/mysql-test-run.pl186
-rw-r--r--mysql-test/r/analyse.result13
-rw-r--r--mysql-test/r/binlog_row_binlog.result35
-rw-r--r--mysql-test/r/binlog_row_mix_innodb_myisam.result18
-rw-r--r--mysql-test/r/binlog_statement_insert_delayed.result19
-rw-r--r--mysql-test/r/binlog_stm_binlog.result35
-rw-r--r--mysql-test/r/client_xml.result2
-rw-r--r--mysql-test/r/csv.result19
-rw-r--r--mysql-test/r/ctype_gbk.result10
-rw-r--r--mysql-test/r/ctype_ucs.result21
-rw-r--r--mysql-test/r/ctype_utf8.result43
-rw-r--r--mysql-test/r/delayed.result174
-rw-r--r--mysql-test/r/execution_constants.result12
-rw-r--r--mysql-test/r/func_gconcat.result9
-rw-r--r--mysql-test/r/func_group.result4
-rw-r--r--mysql-test/r/func_in.result68
-rw-r--r--mysql-test/r/func_time.result12
-rw-r--r--mysql-test/r/greedy_optimizer.result16
-rw-r--r--mysql-test/r/have_ndb_status_ok.require2
-rw-r--r--mysql-test/r/im_daemon_life_cycle.result14
-rw-r--r--mysql-test/r/join.result28
-rw-r--r--mysql-test/r/loaddata.result7
-rw-r--r--mysql-test/r/log_tables.result4
-rw-r--r--mysql-test/r/merge.result23
-rw-r--r--mysql-test/r/mysql.result10
-rw-r--r--mysql-test/r/mysqltest.result5
-rw-r--r--mysql-test/r/ndb_config.result4
-rw-r--r--mysql-test/r/order_by.result8
-rw-r--r--mysql-test/r/partition.result12
-rw-r--r--mysql-test/r/ps.result69
-rw-r--r--mysql-test/r/ps_2myisam.result48
-rw-r--r--mysql-test/r/ps_3innodb.result48
-rw-r--r--mysql-test/r/ps_4heap.result48
-rw-r--r--mysql-test/r/ps_5merge.result96
-rw-r--r--mysql-test/r/ps_7ndb.result48
-rw-r--r--mysql-test/r/range.result14
-rw-r--r--mysql-test/r/round.result272
-rw-r--r--mysql-test/r/rpl_insert_id.result152
-rw-r--r--mysql-test/r/rpl_rewrt_db.result7
-rw-r--r--mysql-test/r/rpl_row_basic_11bugs.result22
-rw-r--r--mysql-test/r/select.result2
-rw-r--r--mysql-test/r/sp-vars.result2
-rw-r--r--mysql-test/r/sp.result24
-rw-r--r--mysql-test/r/strict.result12
-rw-r--r--mysql-test/r/strict_autoinc_4bdb.result6
-rw-r--r--mysql-test/r/subselect.result101
-rw-r--r--mysql-test/r/temp_table.result17
-rw-r--r--mysql-test/r/trigger.result12
-rw-r--r--mysql-test/r/type_bit.result8
-rw-r--r--mysql-test/r/type_float.result7
-rw-r--r--mysql-test/r/view.result45
-rw-r--r--mysql-test/r/warnings.result116
-rw-r--r--mysql-test/r/windows.result28
-rw-r--r--mysql-test/r/xml.result28
-rw-r--r--mysql-test/t/analyse.test13
-rw-r--r--mysql-test/t/crash_commit_before-master.opt2
-rw-r--r--mysql-test/t/crash_commit_before.test5
-rw-r--r--mysql-test/t/csv.test23
-rw-r--r--mysql-test/t/ctype_gbk.test10
-rw-r--r--mysql-test/t/ctype_ucs.test21
-rw-r--r--mysql-test/t/ctype_utf8.test42
-rw-r--r--mysql-test/t/delayed.test148
-rw-r--r--mysql-test/t/disabled.def3
-rw-r--r--mysql-test/t/execution_constants.test74
-rw-r--r--mysql-test/t/func_gconcat.test15
-rw-r--r--mysql-test/t/func_in.test24
-rw-r--r--mysql-test/t/func_time.test19
-rw-r--r--mysql-test/t/im_daemon_life_cycle.imtest44
-rw-r--r--mysql-test/t/join.test21
-rwxr-xr-xmysql-test/t/kill_n_check.sh2
-rw-r--r--mysql-test/t/lowercase_fs_off.test1
-rw-r--r--mysql-test/t/merge.test26
-rw-r--r--mysql-test/t/mysql.test6
-rw-r--r--mysql-test/t/mysqltest.test12
-rw-r--r--mysql-test/t/ndb_config.test6
-rw-r--r--mysql-test/t/ps.test79
-rw-r--r--mysql-test/t/range.test27
-rw-r--r--mysql-test/t/round.test145
-rw-r--r--mysql-test/t/rpl_row_basic_11bugs.test22
-rw-r--r--mysql-test/t/rpl_row_basic_2myisam.test2
-rw-r--r--mysql-test/t/rpl_row_basic_3innodb.test2
-rw-r--r--mysql-test/t/rpl_row_basic_7ndb.test2
-rw-r--r--mysql-test/t/sp.test46
-rw-r--r--mysql-test/t/strict.test8
-rw-r--r--mysql-test/t/subselect.test72
-rw-r--r--mysql-test/t/temp_table.test49
-rw-r--r--mysql-test/t/trigger.test19
-rw-r--r--mysql-test/t/type_bit.test8
-rw-r--r--mysql-test/t/type_float.test11
-rw-r--r--mysql-test/t/view.test51
-rw-r--r--mysql-test/t/warnings.test58
-rw-r--r--mysql-test/t/windows.test39
-rw-r--r--mysql-test/t/xml.test16
-rw-r--r--mysql-test/valgrind.supp23
-rw-r--r--mysys/base64.c65
-rw-r--r--mysys/mf_iocache2.c48
-rw-r--r--mysys/my_chsize.c4
-rw-r--r--mysys/my_libwrap.c4
-rw-r--r--mysys/queues.c48
-rwxr-xr-xnetware/BUILD/mwccnlm9
-rwxr-xr-xnetware/BUILD/mwenv36
-rw-r--r--netware/Makefile.am19
-rw-r--r--netware/libmysql.imp85
-rw-r--r--plugin/fulltext/plugin_example.c1
-rw-r--r--scripts/mysqlhotcopy.sh7
-rw-r--r--server-tools/instance-manager/listener.cc42
-rw-r--r--sql-common/client.c6
-rw-r--r--sql/Makefile.am8
-rw-r--r--sql/field.cc206
-rw-r--r--sql/field.h2
-rw-r--r--sql/field_conv.cc18
-rw-r--r--sql/filesort.cc1
-rw-r--r--sql/ha_ndbcluster.cc110
-rw-r--r--sql/ha_ndbcluster.h2
-rw-r--r--sql/ha_ndbcluster_binlog.cc6
-rw-r--r--sql/ha_ndbcluster_binlog.h3
-rw-r--r--sql/ha_partition.cc21
-rw-r--r--sql/ha_partition.h4
-rw-r--r--sql/handler.cc97
-rw-r--r--sql/handler.h75
-rw-r--r--sql/item.cc7
-rw-r--r--sql/item_cmpfunc.cc296
-rw-r--r--sql/item_cmpfunc.h165
-rw-r--r--sql/item_strfunc.cc3
-rw-r--r--sql/item_sum.cc22
-rw-r--r--sql/item_timefunc.cc4
-rw-r--r--sql/item_xmlfunc.cc64
-rw-r--r--sql/key.cc44
-rw-r--r--sql/log.cc576
-rw-r--r--sql/log.h2
-rw-r--r--sql/log_event.cc601
-rw-r--r--sql/log_event.h30
-rw-r--r--sql/mysql_priv.h42
-rw-r--r--sql/mysqld.cc25
-rw-r--r--sql/opt_range.cc33
-rw-r--r--sql/opt_range.h11
-rw-r--r--sql/partition_info.cc6
-rw-r--r--sql/set_var.cc16
-rw-r--r--sql/share/errmsg.txt30
-rw-r--r--sql/slave.cc29
-rw-r--r--sql/slave.h5
-rw-r--r--sql/sp.cc22
-rw-r--r--sql/sp_head.cc6
-rw-r--r--sql/sql_acl.cc12
-rw-r--r--sql/sql_analyse.cc8
-rw-r--r--sql/sql_base.cc5
-rw-r--r--sql/sql_binlog.cc133
-rw-r--r--sql/sql_cache.cc4
-rw-r--r--sql/sql_class.cc17
-rw-r--r--sql/sql_class.h1
-rw-r--r--sql/sql_cursor.cc12
-rw-r--r--sql/sql_insert.cc203
-rw-r--r--sql/sql_lex.cc3
-rw-r--r--sql/sql_parse.cc17
-rw-r--r--sql/sql_partition.cc12
-rw-r--r--sql/sql_partition.h2
-rw-r--r--sql/sql_plugin.cc18
-rw-r--r--sql/sql_repl.h2
-rw-r--r--sql/sql_select.cc176
-rw-r--r--sql/sql_select.h14
-rw-r--r--sql/sql_show.cc21
-rw-r--r--sql/sql_table.cc5
-rw-r--r--sql/sql_tablespace.cc4
-rw-r--r--sql/sql_trigger.h5
-rw-r--r--sql/sql_update.cc42
-rw-r--r--sql/sql_view.cc2
-rw-r--r--sql/sql_yacc.yy18
-rw-r--r--sql/stacktrace.c2
-rw-r--r--sql/table.cc6
-rw-r--r--sql/unireg.cc39
-rw-r--r--storage/archive/ha_archive.cc24
-rw-r--r--storage/archive/ha_archive.h4
-rw-r--r--storage/blackhole/ha_blackhole.cc15
-rw-r--r--storage/blackhole/ha_blackhole.h2
-rw-r--r--storage/csv/ha_tina.cc61
-rw-r--r--storage/csv/ha_tina.h4
-rw-r--r--storage/example/ha_example.cc17
-rw-r--r--storage/example/ha_example.h2
-rw-r--r--storage/federated/ha_federated.cc49
-rw-r--r--storage/federated/ha_federated.h5
-rw-r--r--storage/heap/ha_heap.cc25
-rw-r--r--storage/heap/ha_heap.h2
-rw-r--r--storage/heap/hp_panic.c6
-rw-r--r--storage/heap/hp_test1.c2
-rw-r--r--storage/heap/hp_test2.c4
-rw-r--r--storage/innobase/btr/btr0btr.c443
-rw-r--r--storage/innobase/btr/btr0cur.c194
-rw-r--r--storage/innobase/btr/btr0pcur.c81
-rw-r--r--storage/innobase/btr/btr0sea.c171
-rw-r--r--storage/innobase/buf/buf0buf.c61
-rw-r--r--storage/innobase/buf/buf0flu.c4
-rw-r--r--storage/innobase/buf/buf0lru.c8
-rw-r--r--storage/innobase/buf/buf0rea.c16
-rw-r--r--storage/innobase/data/data0data.c8
-rw-r--r--storage/innobase/data/data0type.c56
-rw-r--r--storage/innobase/dict/dict0boot.c105
-rw-r--r--storage/innobase/dict/dict0crea.c75
-rw-r--r--storage/innobase/dict/dict0dict.c814
-rw-r--r--storage/innobase/dict/dict0load.c108
-rw-r--r--storage/innobase/dict/dict0mem.c104
-rw-r--r--storage/innobase/eval/eval0eval.c2
-rw-r--r--storage/innobase/eval/eval0proc.c4
-rw-r--r--storage/innobase/fil/fil0fil.c61
-rw-r--r--storage/innobase/fsp/fsp0fsp.c131
-rw-r--r--storage/innobase/handler/ha_innodb.cc251
-rw-r--r--storage/innobase/handler/ha_innodb.h34
-rw-r--r--storage/innobase/ibuf/ibuf0ibuf.c140
-rw-r--r--storage/innobase/include/btr0btr.h30
-rw-r--r--storage/innobase/include/btr0btr.ic2
-rw-r--r--storage/innobase/include/btr0cur.h12
-rw-r--r--storage/innobase/include/btr0cur.ic36
-rw-r--r--storage/innobase/include/btr0pcur.h12
-rw-r--r--storage/innobase/include/btr0sea.h49
-rw-r--r--storage/innobase/include/buf0buf.h7
-rw-r--r--storage/innobase/include/data0data.ic2
-rw-r--r--storage/innobase/include/data0type.h133
-rw-r--r--storage/innobase/include/data0type.ic268
-rw-r--r--storage/innobase/include/dict0boot.h2
-rw-r--r--storage/innobase/include/dict0dict.h224
-rw-r--r--storage/innobase/include/dict0dict.ic247
-rw-r--r--storage/innobase/include/dict0mem.h168
-rw-r--r--storage/innobase/include/dict0types.h1
-rw-r--r--storage/innobase/include/ibuf0ibuf.ic4
-rw-r--r--storage/innobase/include/page0page.h18
-rw-r--r--storage/innobase/include/page0page.ic50
-rw-r--r--storage/innobase/include/read0read.ic6
-rw-r--r--storage/innobase/include/rem0cmp.h23
-rw-r--r--storage/innobase/include/rem0cmp.ic18
-rw-r--r--storage/innobase/include/rem0rec.h5
-rw-r--r--storage/innobase/include/rem0rec.ic34
-rw-r--r--storage/innobase/include/rem0types.h4
-rw-r--r--storage/innobase/include/row0upd.ic4
-rw-r--r--storage/innobase/include/sync0rw.h23
-rw-r--r--storage/innobase/include/univ.i1
-rw-r--r--storage/innobase/lock/lock0lock.c117
-rw-r--r--storage/innobase/log/log0log.c95
-rw-r--r--storage/innobase/log/log0recv.c243
-rw-r--r--storage/innobase/mem/mem0dbg.c4
-rw-r--r--storage/innobase/mem/mem0pool.c4
-rw-r--r--storage/innobase/mtr/mtr0log.c32
-rw-r--r--storage/innobase/mtr/mtr0mtr.c6
-rw-r--r--storage/innobase/os/os0file.c12
-rw-r--r--storage/innobase/os/os0thread.c5
-rw-r--r--storage/innobase/page/page0cur.c40
-rw-r--r--storage/innobase/page/page0page.c6
-rw-r--r--storage/innobase/pars/pars0opt.c25
-rw-r--r--storage/innobase/pars/pars0pars.c97
-rw-r--r--storage/innobase/pars/pars0sym.c6
-rw-r--r--storage/innobase/read/read0read.c21
-rw-r--r--storage/innobase/rem/rem0cmp.c187
-rw-r--r--storage/innobase/rem/rem0rec.c84
-rw-r--r--storage/innobase/row/row0ins.c273
-rw-r--r--storage/innobase/row/row0mysql.c256
-rw-r--r--storage/innobase/row/row0purge.c22
-rw-r--r--storage/innobase/row/row0row.c88
-rw-r--r--storage/innobase/row/row0sel.c293
-rw-r--r--storage/innobase/row/row0uins.c4
-rw-r--r--storage/innobase/row/row0umod.c50
-rw-r--r--storage/innobase/row/row0upd.c175
-rw-r--r--storage/innobase/row/row0vers.c6
-rw-r--r--storage/innobase/srv/srv0srv.c30
-rw-r--r--storage/innobase/srv/srv0start.c61
-rw-r--r--storage/innobase/sync/sync0arr.c12
-rw-r--r--storage/innobase/sync/sync0rw.c5
-rw-r--r--storage/innobase/sync/sync0sync.c14
-rw-r--r--storage/innobase/trx/trx0purge.c22
-rw-r--r--storage/innobase/trx/trx0rec.c38
-rw-r--r--storage/innobase/trx/trx0rseg.c12
-rw-r--r--storage/innobase/trx/trx0sys.c91
-rw-r--r--storage/innobase/trx/trx0trx.c40
-rw-r--r--storage/innobase/trx/trx0undo.c20
-rw-r--r--storage/myisam/ha_myisam.cc29
-rw-r--r--storage/myisam/ha_myisam.h2
-rw-r--r--storage/myisam/mi_check.c9
-rw-r--r--storage/myisam/mi_delete.c2
-rw-r--r--storage/myisam/mi_locking.c16
-rw-r--r--storage/myisam/myisam_ftdump.c3
-rw-r--r--storage/myisam/myisamdef.h3
-rw-r--r--storage/myisammrg/ha_myisammrg.cc49
-rw-r--r--storage/myisammrg/ha_myisammrg.h2
-rw-r--r--storage/myisammrg/myrg_locking.c13
-rw-r--r--storage/myisammrg/myrg_open.c10
-rw-r--r--storage/myisammrg/myrg_queue.c2
-rw-r--r--storage/ndb/include/kernel/GlobalSignalNumbers.h1
-rw-r--r--storage/ndb/include/kernel/signaldata/CmRegSignalData.hpp6
-rw-r--r--storage/ndb/include/kernel/signaldata/CopyFrag.hpp13
-rw-r--r--storage/ndb/include/mgmapi/mgmapi.h40
-rw-r--r--storage/ndb/include/mgmapi/mgmapi_debug.h14
-rw-r--r--storage/ndb/include/mgmapi/ndbd_exit_codes.h2
-rw-r--r--storage/ndb/include/mgmcommon/ConfigRetriever.hpp3
-rw-r--r--storage/ndb/include/ndb_version.h.in4
-rw-r--r--storage/ndb/include/ndbapi/NdbDictionary.hpp41
-rw-r--r--storage/ndb/include/ndbapi/NdbScanOperation.hpp3
-rw-r--r--storage/ndb/include/ndbapi/NdbTransaction.hpp7
-rw-r--r--storage/ndb/include/util/File.hpp8
-rw-r--r--storage/ndb/include/util/InputStream.hpp11
-rw-r--r--storage/ndb/include/util/Parser.hpp5
-rw-r--r--storage/ndb/include/util/SocketClient.hpp3
-rw-r--r--storage/ndb/include/util/ndb_opts.h2
-rw-r--r--storage/ndb/include/util/socket_io.h7
-rw-r--r--storage/ndb/src/common/debugger/signaldata/SignalNames.cpp2
-rw-r--r--storage/ndb/src/common/logger/FileLogHandler.cpp11
-rw-r--r--storage/ndb/src/common/mgmcommon/ConfigRetriever.cpp12
-rw-r--r--storage/ndb/src/common/transporter/Transporter.cpp18
-rw-r--r--storage/ndb/src/common/util/File.cpp12
-rw-r--r--storage/ndb/src/common/util/InputStream.cpp39
-rw-r--r--storage/ndb/src/common/util/Parser.cpp38
-rw-r--r--storage/ndb/src/common/util/SocketClient.cpp73
-rw-r--r--storage/ndb/src/common/util/socket_io.cpp35
-rw-r--r--storage/ndb/src/cw/cpcd/main.cpp2
-rw-r--r--storage/ndb/src/kernel/blocks/dbdict/Dbdict.cpp4
-rw-r--r--storage/ndb/src/kernel/blocks/dbdih/DbdihMain.cpp181
-rw-r--r--storage/ndb/src/kernel/blocks/dbdih/Sysfile.hpp4
-rw-r--r--storage/ndb/src/kernel/blocks/dblqh/Dblqh.hpp1
-rw-r--r--storage/ndb/src/kernel/blocks/dblqh/DblqhInit.cpp3
-rw-r--r--storage/ndb/src/kernel/blocks/dblqh/DblqhMain.cpp62
-rw-r--r--storage/ndb/src/kernel/blocks/dbtc/DbtcMain.cpp30
-rw-r--r--storage/ndb/src/kernel/blocks/ndbcntr/NdbcntrMain.cpp26
-rw-r--r--storage/ndb/src/kernel/blocks/qmgr/QmgrMain.cpp51
-rw-r--r--storage/ndb/src/kernel/error/ndbd_exit_codes.c3
-rw-r--r--storage/ndb/src/kernel/vm/Configuration.cpp16
-rw-r--r--storage/ndb/src/mgmapi/mgmapi.cpp241
-rw-r--r--storage/ndb/src/mgmclient/CommandInterpreter.cpp835
-rw-r--r--storage/ndb/src/mgmclient/main.cpp8
-rw-r--r--storage/ndb/src/mgmclient/ndb_mgmclient.hpp4
-rw-r--r--storage/ndb/src/mgmsrv/ConfigInfo.cpp11
-rw-r--r--storage/ndb/src/mgmsrv/MgmtSrvr.cpp10
-rw-r--r--storage/ndb/src/mgmsrv/Services.cpp196
-rw-r--r--storage/ndb/src/mgmsrv/Services.hpp20
-rw-r--r--storage/ndb/src/mgmsrv/main.cpp4
-rw-r--r--storage/ndb/src/ndbapi/Ndb.cpp5
-rw-r--r--storage/ndb/src/ndbapi/NdbDictionary.cpp17
-rw-r--r--storage/ndb/src/ndbapi/NdbDictionaryImpl.cpp95
-rw-r--r--storage/ndb/src/ndbapi/NdbDictionaryImpl.hpp11
-rw-r--r--storage/ndb/src/ndbapi/NdbOperation.cpp22
-rw-r--r--storage/ndb/src/ndbapi/NdbScanOperation.cpp37
-rw-r--r--storage/ndb/src/ndbapi/NdbTransaction.cpp79
-rw-r--r--storage/ndb/src/ndbapi/ndberror.c4
-rw-r--r--storage/ndb/test/include/NDBT_Table.hpp5
-rw-r--r--storage/ndb/test/ndbapi/flexScan.cpp4
-rw-r--r--storage/ndb/test/ndbapi/testMgm.cpp45
-rw-r--r--storage/ndb/test/ndbapi/testTimeout.cpp50
-rw-r--r--storage/ndb/test/src/NDBT_Tables.cpp5
-rw-r--r--storage/ndb/tools/delete_all.cpp18
-rw-r--r--storage/ndb/tools/desc.cpp6
-rw-r--r--storage/ndb/tools/drop_index.cpp6
-rw-r--r--storage/ndb/tools/drop_tab.cpp8
-rw-r--r--storage/ndb/tools/listTables.cpp5
-rw-r--r--storage/ndb/tools/ndb_condig.cpp66
-rw-r--r--storage/ndb/tools/restore/consumer.hpp1
-rw-r--r--storage/ndb/tools/restore/consumer_restore.cpp6
-rw-r--r--storage/ndb/tools/restore/consumer_restore.hpp3
-rw-r--r--storage/ndb/tools/restore/restore_main.cpp15
-rw-r--r--storage/ndb/tools/select_all.cpp5
-rw-r--r--storage/ndb/tools/select_count.cpp6
-rw-r--r--storage/ndb/tools/waiter.cpp6
-rw-r--r--strings/ctype-big5.c1
-rw-r--r--strings/ctype-bin.c1
-rw-r--r--strings/ctype-cp932.c1
-rw-r--r--strings/ctype-euc_kr.c1
-rw-r--r--strings/ctype-eucjpms.c1
-rw-r--r--strings/ctype-gb2312.c1
-rw-r--r--strings/ctype-gbk.c1
-rw-r--r--strings/ctype-latin1.c1
-rw-r--r--strings/ctype-simple.c337
-rw-r--r--strings/ctype-sjis.c1
-rw-r--r--strings/ctype-tis620.c1
-rw-r--r--strings/ctype-ucs2.c30
-rw-r--r--strings/ctype-ujis.c1
-rw-r--r--strings/ctype-utf8.c1
-rw-r--r--strings/strtod.c67
-rw-r--r--strings/xml.c60
-rw-r--r--support-files/mysql.spec.sh1
-rw-r--r--tests/mysql_client_test.c42
-rw-r--r--unittest/mysys/base64-t.c2
-rw-r--r--vio/viossl.c10
-rw-r--r--zlib/Makefile.am2
474 files changed, 14725 insertions, 6994 deletions
diff --git a/.bzrignore b/.bzrignore
index af3106b98f3..6abf5d3eb8b 100644
--- a/.bzrignore
+++ b/.bzrignore
@@ -1242,6 +1242,7 @@ mysql-test/gmon.out
mysql-test/install_test_db
mysql-test/mtr
mysql-test/mysql-test-run
+mysql-test/mysql-test-run-shell
mysql-test/mysql-test-run.log
mysql-test/mysql_test_run_new
mysql-test/ndb/ndbcluster
@@ -1733,6 +1734,7 @@ netware/.deps/my_manage.Po
netware/.deps/mysql_install_db.Po
netware/.deps/mysql_test_run.Po
netware/.deps/mysqld_safe.Po
+netware/libmysql.imp
pack_isam/*.ds?
perror/*.ds?
perror/*.vcproj
diff --git a/BitKeeper/etc/collapsed b/BitKeeper/etc/collapsed
index fd33e4fc902..79836bb030e 100644
--- a/BitKeeper/etc/collapsed
+++ b/BitKeeper/etc/collapsed
@@ -2,4 +2,8 @@
44ec850ac2k4y2Omgr92GiWPBAVKGQ
44edb86b1iE5knJ97MbliK_3lCiAXA
44f33f3aj5KW5qweQeekY1LU0E9ZCg
+45001f7c3b2hhCXDKfUvzkX9TNe6VA
+45002051rHJfMEXAIMiAZV0clxvKSA
4513d8e4Af4dQWuk13sArwofRgFDQw
+4519a6c5BVUxEHTf5iJnjZkixMBs8g
+451ab499rgdjXyOnUDqHu-wBDoS-OQ
diff --git a/client/mysql.cc b/client/mysql.cc
index b5f28090283..1dbdeb8be97 100644
--- a/client/mysql.cc
+++ b/client/mysql.cc
@@ -49,6 +49,9 @@ const char *VER= "14.12";
/* Don't try to make a nice table if the data is too big */
#define MAX_COLUMN_LENGTH 1024
+/* Buffer to hold 'version' and 'version_comment' */
+#define MAX_SERVER_VERSION_LENGTH 128
+
gptr sql_alloc(unsigned size); // Don't use mysqld alloc for these
void sql_element_free(void *ptr);
#include "sql_string.h"
@@ -207,6 +210,7 @@ static int com_nopager(String *str, char*), com_pager(String *str, char*),
static int read_and_execute(bool interactive);
static int sql_connect(char *host,char *database,char *user,char *password,
uint silent);
+static const char *server_version_string(MYSQL *mysql);
static int put_info(const char *str,INFO_TYPE info,uint error=0,
const char *sql_state=0);
static int put_error(MYSQL *mysql);
@@ -430,8 +434,8 @@ int main(int argc,char *argv[])
put_info("Welcome to the MySQL monitor. Commands end with ; or \\g.",
INFO_INFO);
sprintf((char*) glob_buffer.ptr(),
- "Your MySQL connection id is %lu to server version: %s\n",
- mysql_thread_id(&mysql),mysql_get_server_info(&mysql));
+ "Your MySQL connection id is %lu\nServer version: %s\n",
+ mysql_thread_id(&mysql), server_version_string(&mysql));
put_info((char*) glob_buffer.ptr(),INFO_INFO);
#ifdef HAVE_READLINE
@@ -2493,9 +2497,14 @@ print_table_data_xml(MYSQL_RES *result)
{
tee_fprintf(PAGER, "\t<field name=\"");
xmlencode_print(fields[i].name, (uint) strlen(fields[i].name));
- tee_fprintf(PAGER, "\">");
- xmlencode_print(cur[i], lengths[i]);
- tee_fprintf(PAGER, "</field>\n");
+ if (cur[i])
+ {
+ tee_fprintf(PAGER, "\">");
+ xmlencode_print(cur[i], lengths[i]);
+ tee_fprintf(PAGER, "</field>\n");
+ }
+ else
+ tee_fprintf(PAGER, "\" xsi:nil=\"true\" />\n");
}
(void) tee_fputs(" </row>\n", PAGER);
}
@@ -2896,7 +2905,7 @@ com_connect(String *buffer, char *line)
bzero(buff, sizeof(buff));
if (buffer)
{
- strmake(buff, line, sizeof(buff));
+ strmake(buff, line, sizeof(buff) - 1);
tmp= get_arg(buff, 0);
if (tmp && *tmp)
{
@@ -3011,7 +3020,7 @@ com_use(String *buffer __attribute__((unused)), char *line)
int select_db;
bzero(buff, sizeof(buff));
- strmov(buff, line);
+ strmake(buff, line, sizeof(buff) - 1);
tmp= get_arg(buff, 0);
if (!tmp || !*tmp)
{
@@ -3321,16 +3330,13 @@ com_status(String *buffer __attribute__((unused)),
tee_fprintf(stdout, "Using outfile:\t\t'%s'\n", opt_outfile ? outfile : "");
#endif
tee_fprintf(stdout, "Using delimiter:\t%s\n", delimiter);
- tee_fprintf(stdout, "Server version:\t\t%s\n", mysql_get_server_info(&mysql));
+ tee_fprintf(stdout, "Server version:\t\t%s\n", server_version_string(&mysql));
tee_fprintf(stdout, "Protocol version:\t%d\n", mysql_get_proto_info(&mysql));
tee_fprintf(stdout, "Connection:\t\t%s\n", mysql_get_host_info(&mysql));
if ((id= mysql_insert_id(&mysql)))
tee_fprintf(stdout, "Insert id:\t\t%s\n", llstr(id, buff));
- /*
- Don't remove "limit 1",
- it is protection againts SQL_SELECT_LIMIT=0
- */
+ /* "limit 1" is protection against SQL_SELECT_LIMIT=0 */
if (!mysql_query(&mysql,"select @@character_set_client, @@character_set_connection, @@character_set_server, @@character_set_database limit 1") &&
(result=mysql_use_result(&mysql)))
{
@@ -3395,6 +3401,39 @@ select_limit, max_join_size);
return 0;
}
+static const char *
+server_version_string(MYSQL *mysql)
+{
+ static char buf[MAX_SERVER_VERSION_LENGTH] = "";
+
+ /* Only one thread calls this, so no synchronization is needed */
+ if (buf[0] == '\0')
+ {
+ char *bufp = buf;
+ MYSQL_RES *result;
+ MYSQL_ROW cur;
+
+ bufp = strnmov(buf, mysql_get_server_info(mysql), sizeof buf);
+
+ /* "limit 1" is protection against SQL_SELECT_LIMIT=0 */
+ if (!mysql_query(mysql, "select @@version_comment limit 1") &&
+ (result = mysql_use_result(mysql)))
+ {
+ MYSQL_ROW cur = mysql_fetch_row(result);
+ if (cur && cur[0])
+ {
+ bufp = strxnmov(bufp, sizeof buf - (bufp - buf), " ", cur[0], NullS);
+ }
+ mysql_free_result(result);
+ }
+
+ /* str*nmov doesn't guarantee NUL-termination */
+ if (bufp == buf + sizeof buf)
+ buf[sizeof buf - 1] = '\0';
+ }
+
+ return buf;
+}
static int
put_info(const char *str,INFO_TYPE info_type, uint error, const char *sqlstate)
@@ -3516,11 +3555,11 @@ void tee_puts(const char *s, FILE *file)
{
NETWARE_YIELD;
fputs(s, file);
- fputs("\n", file);
+ fputc('\n', file);
if (opt_outfile)
{
fputs(s, OUTFILE);
- fputs("\n", OUTFILE);
+ fputc('\n', OUTFILE);
}
}
diff --git a/client/mysqlbinlog.cc b/client/mysqlbinlog.cc
index 83385e9d005..ab94c415db7 100644
--- a/client/mysqlbinlog.cc
+++ b/client/mysqlbinlog.cc
@@ -476,6 +476,30 @@ static bool check_database(const char *log_dbname)
}
+
+static int
+write_event_header_and_base64(Log_event *ev, FILE *result_file,
+ PRINT_EVENT_INFO *print_event_info)
+{
+ DBUG_ENTER("write_event_header_and_base64");
+ /* Write header and base64 output to cache */
+ IO_CACHE result_cache;
+ if (init_io_cache(&result_cache, -1, 0, WRITE_CACHE, 0L, FALSE,
+ MYF(MY_WME | MY_NABP)))
+ {
+ return 1;
+ }
+
+ ev->print_header(&result_cache, print_event_info, FALSE);
+ ev->print_base64(&result_cache, print_event_info, FALSE);
+
+ /* Read data from cache and write to result file */
+ my_b_copy_to_file(&result_cache, result_file);
+ end_io_cache(&result_cache);
+ DBUG_RETURN(0);
+}
+
+
/*
Process an event
@@ -538,18 +562,18 @@ int process_event(PRINT_EVENT_INFO *print_event_info, Log_event *ev,
print_event_info->base64_output= opt_base64_output;
+ DBUG_PRINT("debug", ("event_type: %s", ev->get_type_str()));
+
switch (ev_type) {
case QUERY_EVENT:
if (check_database(((Query_log_event*)ev)->db))
goto end;
if (opt_base64_output)
- {
- ev->print_header(result_file, print_event_info);
- ev->print_base64(result_file, print_event_info);
- }
+ write_event_header_and_base64(ev, result_file, print_event_info);
else
ev->print(result_file, print_event_info);
break;
+
case CREATE_FILE_EVENT:
{
Create_file_log_event* ce= (Create_file_log_event*)ev;
@@ -570,8 +594,7 @@ int process_event(PRINT_EVENT_INFO *print_event_info, Log_event *ev,
*/
if (opt_base64_output)
{
- ce->print_header(result_file, print_event_info);
- ce->print_base64(result_file, print_event_info);
+ write_event_header_and_base64(ce, result_file, print_event_info);
}
else
ce->print(result_file, print_event_info, TRUE);
diff --git a/client/mysqldump.c b/client/mysqldump.c
index c32e2713fc9..2d2961e465c 100644
--- a/client/mysqldump.c
+++ b/client/mysqldump.c
@@ -2750,17 +2750,26 @@ static int dump_all_tablespaces()
MYSQL_RES *tableres;
char buf[FN_REFLEN];
int first;
+ /*
+ The following are used for parsing the EXTRA field
+ */
+ char extra_format[]= "UNDO_BUFFER_SIZE=";
+ char *ubs;
+ char *endsemi;
if (mysql_query_with_error_report(mysql, &tableres,
- "SELECT DISTINCT"
+ "SELECT"
" LOGFILE_GROUP_NAME,"
" FILE_NAME,"
" TOTAL_EXTENTS,"
" INITIAL_SIZE,"
- " ENGINE"
+ " ENGINE,"
+ " EXTRA"
" FROM INFORMATION_SCHEMA.FILES"
" WHERE FILE_TYPE = \"UNDO LOG\""
" AND FILE_NAME IS NOT NULL"
+ " GROUP BY LOGFILE_GROUP_NAME, FILE_NAME"
+ ", ENGINE"
" ORDER BY LOGFILE_GROUP_NAME"))
return 1;
@@ -2789,9 +2798,16 @@ static int dump_all_tablespaces()
row[1]);
if (first)
{
+ ubs= strstr(row[5],extra_format);
+ if(!ubs)
+ break;
+ ubs+= strlen(extra_format);
+ endsemi= strstr(ubs,";");
+ if(endsemi)
+ endsemi[0]= '\0';
fprintf(md_result_file,
" UNDO_BUFFER_SIZE %s\n",
- row[2]);
+ ubs);
}
fprintf(md_result_file,
" INITIAL_SIZE %s\n"
diff --git a/client/mysqltest.c b/client/mysqltest.c
index 27104282dd4..f9c4ae617fd 100644
--- a/client/mysqltest.c
+++ b/client/mysqltest.c
@@ -1784,8 +1784,12 @@ int do_save_master_pos()
int do_let(struct st_query *query)
{
+ int ret;
char *p= query->first_argument;
- char *var_name, *var_name_end, *var_val_start;
+ char *var_name, *var_name_end;
+ DYNAMIC_STRING let_rhs_expr;
+
+ init_dynamic_string(&let_rhs_expr, "", 512, 2048);
/* Find <var_name> */
if (!*p)
@@ -1805,10 +1809,16 @@ int do_let(struct st_query *query)
/* Find start of <var_val> */
while (*p && my_isspace(charset_info,*p))
p++;
- var_val_start= p;
+
+ do_eval(&let_rhs_expr, p, FALSE);
+
query->last_argument= query->end;
/* Assign var_val to var_name */
- return var_set(var_name, var_name_end, var_val_start, query->end);
+ ret= var_set(var_name, var_name_end, let_rhs_expr.str,
+ (let_rhs_expr.str + let_rhs_expr.length));
+ dynstr_free(&let_rhs_expr);
+
+ return(ret);
}
diff --git a/configure.in b/configure.in
index fbd12e2707e..22de4f2ff17 100644
--- a/configure.in
+++ b/configure.in
@@ -7,7 +7,7 @@ AC_INIT(sql/mysqld.cc)
AC_CANONICAL_SYSTEM
# The Docs Makefile.am parses this line!
# remember to also change ndb version below and update version.c in ndb
-AM_INIT_AUTOMAKE(mysql, 5.1.12-beta)
+AM_INIT_AUTOMAKE(mysql, 5.1.13-beta)
AM_CONFIG_HEADER(config.h)
PROTOCOL_VERSION=10
diff --git a/extra/Makefile.am b/extra/Makefile.am
index de8e519e641..81a6f5f5cb9 100644
--- a/extra/Makefile.am
+++ b/extra/Makefile.am
@@ -22,11 +22,15 @@ BUILT_SOURCES= $(top_builddir)/include/mysqld_error.h \
$(top_builddir)/include/sql_state.h \
$(top_builddir)/include/mysqld_ername.h
pkginclude_HEADERS= $(BUILT_SOURCES)
-CLEANFILES = $(BUILT_SOURCES)
+DISTCLEANFILES = $(BUILT_SOURCES)
SUBDIRS = @yassl_dir@
-# This will build mysqld_error.h and sql_state.h
-$(top_builddir)/include/mysqld_error.h: comp_err$(EXEEXT)
+# This will build mysqld_error.h, mysqld_ername.h and sql_state.h
+# NOTE Built files should depend on their sources to avoid
+# the built files being rebuilt in source dist
+$(top_builddir)/include/mysqld_error.h: comp_err.c \
+ $(top_srcdir)/sql/share/errmsg.txt
+ $(MAKE) $(AM_MAKEFLAGS) comp_err$(EXEEXT)
$(top_builddir)/extra/comp_err$(EXEEXT) \
--charset=$(top_srcdir)/sql/share/charsets \
--out-dir=$(top_builddir)/sql/share/ \
@@ -37,9 +41,10 @@ $(top_builddir)/include/mysqld_error.h: comp_err$(EXEEXT)
$(top_builddir)/include/mysqld_ername.h: $(top_builddir)/include/mysqld_error.h
$(top_builddir)/include/sql_state.h: $(top_builddir)/include/mysqld_error.h
-bin_PROGRAMS = replace comp_err perror resolveip my_print_defaults \
+bin_PROGRAMS = replace perror resolveip my_print_defaults \
resolve_stack_dump mysql_waitpid innochecksum
noinst_PROGRAMS = charset2html
+EXTRA_PROGRAMS = comp_err
EXTRA_DIST = CMakeLists.txt
perror.o: perror.c
diff --git a/extra/yassl/CMakeLists.txt b/extra/yassl/CMakeLists.txt
index e5429876072..09bd2b046da 100644
--- a/extra/yassl/CMakeLists.txt
+++ b/extra/yassl/CMakeLists.txt
@@ -1,6 +1,6 @@
ADD_DEFINITIONS("-DWIN32 -D_LIB -DYASSL_PREFIX")
-INCLUDE_DIRECTORIES(include taocrypt/include mySTL)
+INCLUDE_DIRECTORIES(include taocrypt/include taocrypt/mySTL)
ADD_LIBRARY(yassl src/buffer.cpp src/cert_wrapper.cpp src/crypto_wrapper.cpp src/handshake.cpp src/lock.cpp
src/log.cpp src/socket_wrapper.cpp src/ssl.cpp src/timer.cpp src/yassl_error.cpp
src/yassl_imp.cpp src/yassl_int.cpp)
diff --git a/extra/yassl/FLOSS-EXCEPTIONS b/extra/yassl/FLOSS-EXCEPTIONS
index 344083b0114..47f86ff65f2 100644
--- a/extra/yassl/FLOSS-EXCEPTIONS
+++ b/extra/yassl/FLOSS-EXCEPTIONS
@@ -1,7 +1,7 @@
yaSSL FLOSS License Exception
****************************************
-Version 0.1, 26 June 2006
+Version 0.2, 31 August 2006
The Sawtooth Consulting Ltd. Exception for Free/Libre and Open Source
Software-only Applications Using yaSSL Libraries (the "FLOSS Exception").
@@ -81,6 +81,7 @@ the GPL:
Python license (CNRI Python License) -
Python Software Foundation License 2.1.1
Sleepycat License "1999"
+ University of Illinois/NCSA Open Source License -
W3C License "2001"
X11 License "2001"
Zlib/libpng License -
diff --git a/extra/yassl/Makefile.am b/extra/yassl/Makefile.am
index e4a81019cd1..95efa656907 100644
--- a/extra/yassl/Makefile.am
+++ b/extra/yassl/Makefile.am
@@ -1,3 +1,3 @@
SUBDIRS = taocrypt src testsuite
-EXTRA_DIST = yassl.dsp yassl.dsw yassl.vcproj $(wildcard mySTL/*.hpp) \
+EXTRA_DIST = yassl.dsp yassl.dsw yassl.vcproj \
CMakeLists.txt
diff --git a/extra/yassl/README b/extra/yassl/README
index 25d4d94c306..2af4e98fe4c 100644
--- a/extra/yassl/README
+++ b/extra/yassl/README
@@ -1,4 +1,15 @@
-yaSSL Release notes, version 1.3.7 (06/26/06)
+yaSSL Release notes, version 1.4.0 (08/13/06)
+
+
+ This release of yaSSL contains bug fixes, portability enhancements,
+ nonblocking connect and accept, better OpenSSL error mapping, and
+ certificate caching for session resumption.
+
+See normal build instructions below under 1.0.6.
+See libcurl build instructions below under 1.3.0.
+
+
+********************yaSSL Release notes, version 1.3.7 (06/26/06)
This release of yaSSL contains bug fixes, portability enhancements,
diff --git a/extra/yassl/examples/client/client.cpp b/extra/yassl/examples/client/client.cpp
index 94bf753210b..d655011deb6 100644
--- a/extra/yassl/examples/client/client.cpp
+++ b/extra/yassl/examples/client/client.cpp
@@ -27,7 +27,13 @@ void client_test(void* args)
SSL_set_fd(ssl, sockfd);
- if (SSL_connect(ssl) != SSL_SUCCESS) err_sys("SSL_connect failed");
+ if (SSL_connect(ssl) != SSL_SUCCESS)
+ {
+ SSL_CTX_free(ctx);
+ SSL_free(ssl);
+ tcp_close(sockfd);
+ err_sys("SSL_connect failed");
+ }
showPeer(ssl);
const char* cipher = 0;
@@ -39,11 +45,16 @@ void client_test(void* args)
strncat(list, cipher, strlen(cipher) + 1);
}
printf("%s\n", list);
- printf("Using Cipher Suite %s\n", SSL_get_cipher(ssl));
+ printf("Using Cipher Suite: %s\n", SSL_get_cipher(ssl));
char msg[] = "hello yassl!";
if (SSL_write(ssl, msg, sizeof(msg)) != sizeof(msg))
+ {
+ SSL_CTX_free(ctx);
+ SSL_free(ssl);
+ tcp_close(sockfd);
err_sys("SSL_write failed");
+ }
char reply[1024];
reply[SSL_read(ssl, reply, sizeof(reply))] = 0;
@@ -56,22 +67,36 @@ void client_test(void* args)
SSL_shutdown(ssl);
SSL_free(ssl);
+ tcp_close(sockfd);
#ifdef TEST_RESUME
tcp_connect(sockfd);
SSL_set_fd(sslResume, sockfd);
SSL_set_session(sslResume, session);
- if (SSL_connect(sslResume) != SSL_SUCCESS) err_sys("SSL resume failed");
+ if (SSL_connect(sslResume) != SSL_SUCCESS)
+ {
+ SSL_CTX_free(ctx);
+ SSL_free(ssl);
+ tcp_close(sockfd);
+ err_sys("SSL resume failed");
+ }
+ showPeer(sslResume);
if (SSL_write(sslResume, msg, sizeof(msg)) != sizeof(msg))
+ {
+ SSL_CTX_free(ctx);
+ SSL_free(ssl);
+ tcp_close(sockfd);
err_sys("SSL_write failed");
+ }
reply[SSL_read(sslResume, reply, sizeof(reply))] = 0;
printf("Server response: %s\n", reply);
SSL_shutdown(sslResume);
SSL_free(sslResume);
+ tcp_close(sockfd);
#endif // TEST_RESUME
SSL_CTX_free(ctx);
diff --git a/extra/yassl/examples/echoclient/echoclient.cpp b/extra/yassl/examples/echoclient/echoclient.cpp
index fd3f7dd48a3..983254bf8a7 100644
--- a/extra/yassl/examples/echoclient/echoclient.cpp
+++ b/extra/yassl/examples/echoclient/echoclient.cpp
@@ -41,7 +41,14 @@ void echoclient_test(void* args)
SSL* ssl = SSL_new(ctx);
SSL_set_fd(ssl, sockfd);
- if (SSL_connect(ssl) != SSL_SUCCESS) err_sys("SSL_connect failed");
+
+ if (SSL_connect(ssl) != SSL_SUCCESS)
+ {
+ SSL_CTX_free(ctx);
+ SSL_free(ssl);
+ tcp_close(sockfd);
+ err_sys("SSL_connect failed");
+ }
char send[1024];
char reply[1024];
@@ -50,7 +57,12 @@ void echoclient_test(void* args)
int sendSz = strlen(send) + 1;
if (SSL_write(ssl, send, sendSz) != sendSz)
+ {
+ SSL_CTX_free(ctx);
+ SSL_free(ssl);
+ tcp_close(sockfd);
err_sys("SSL_write failed");
+ }
if (strncmp(send, "quit", 4) == 0) {
fputs("sending server shutdown command: quit!\n", fout);
@@ -63,6 +75,7 @@ void echoclient_test(void* args)
SSL_CTX_free(ctx);
SSL_free(ssl);
+ tcp_close(sockfd);
fflush(fout);
if (inCreated) fclose(fin);
diff --git a/extra/yassl/examples/echoserver/echoserver.cpp b/extra/yassl/examples/echoserver/echoserver.cpp
index 8e23ead20ab..cd31fedddd8 100644
--- a/extra/yassl/examples/echoserver/echoserver.cpp
+++ b/extra/yassl/examples/echoserver/echoserver.cpp
@@ -23,6 +23,18 @@
#endif // NO_MAIN_DRIVER
+
+void EchoError(SSL_CTX* ctx, SSL* ssl, SOCKET_T& s1, SOCKET_T& s2,
+ const char* msg)
+{
+ SSL_CTX_free(ctx);
+ SSL_free(ssl);
+ tcp_close(s1);
+ tcp_close(s2);
+ err_sys(msg);
+}
+
+
THREAD_RETURN YASSL_API echoserver_test(void* args)
{
#ifdef _WIN32
@@ -65,13 +77,18 @@ THREAD_RETURN YASSL_API echoserver_test(void* args)
while (!shutdown) {
sockaddr_in client;
socklen_t client_len = sizeof(client);
- int clientfd = accept(sockfd, (sockaddr*)&client,
+ SOCKET_T clientfd = accept(sockfd, (sockaddr*)&client,
(ACCEPT_THIRD_T)&client_len);
- if (clientfd == -1) err_sys("tcp accept failed");
+ if (clientfd == -1) {
+ SSL_CTX_free(ctx);
+ tcp_close(sockfd);
+ err_sys("tcp accept failed");
+ }
SSL* ssl = SSL_new(ctx);
SSL_set_fd(ssl, clientfd);
- if (SSL_accept(ssl) != SSL_SUCCESS) err_sys("SSL_accept failed");
+ if (SSL_accept(ssl) != SSL_SUCCESS)
+ EchoError(ctx, ssl, sockfd, clientfd, "SSL_accept failed");
char command[1024];
int echoSz(0);
@@ -100,7 +117,8 @@ THREAD_RETURN YASSL_API echoserver_test(void* args)
echoSz += sizeof(footer);
if (SSL_write(ssl, command, echoSz) != echoSz)
- err_sys("SSL_write failed");
+ EchoError(ctx, ssl, sockfd, clientfd, "SSL_write failed");
+
break;
}
command[echoSz] = 0;
@@ -110,16 +128,13 @@ THREAD_RETURN YASSL_API echoserver_test(void* args)
#endif
if (SSL_write(ssl, command, echoSz) != echoSz)
- err_sys("SSL_write failed");
+ EchoError(ctx, ssl, sockfd, clientfd, "SSL_write failed");
}
SSL_free(ssl);
+ tcp_close(clientfd);
}
-#ifdef _WIN32
- closesocket(sockfd);
-#else
- close(sockfd);
-#endif
+ tcp_close(sockfd);
DH_free(dh);
SSL_CTX_free(ctx);
diff --git a/extra/yassl/examples/server/server.cpp b/extra/yassl/examples/server/server.cpp
index 73cff19e371..d0bf70cd634 100644
--- a/extra/yassl/examples/server/server.cpp
+++ b/extra/yassl/examples/server/server.cpp
@@ -4,6 +4,15 @@
#include "../../testsuite/test.hpp"
+void ServerError(SSL_CTX* ctx, SSL* ssl, SOCKET_T& sockfd, const char* msg)
+{
+ SSL_CTX_free(ctx);
+ SSL_free(ssl);
+ tcp_close(sockfd);
+ err_sys(msg);
+}
+
+
THREAD_RETURN YASSL_API server_test(void* args)
{
#ifdef _WIN32
@@ -12,18 +21,14 @@ THREAD_RETURN YASSL_API server_test(void* args)
#endif
SOCKET_T sockfd = 0;
- int clientfd = 0;
+ SOCKET_T clientfd = 0;
int argc = 0;
char** argv = 0;
set_args(argc, argv, *static_cast<func_args*>(args));
tcp_accept(sockfd, clientfd, *static_cast<func_args*>(args));
-#ifdef _WIN32
- closesocket(sockfd);
-#else
- close(sockfd);
-#endif
+ tcp_close(sockfd);
SSL_METHOD* method = TLSv1_server_method();
SSL_CTX* ctx = SSL_CTX_new(method);
@@ -36,9 +41,11 @@ THREAD_RETURN YASSL_API server_test(void* args)
SSL* ssl = SSL_new(ctx);
SSL_set_fd(ssl, clientfd);
- if (SSL_accept(ssl) != SSL_SUCCESS) err_sys("SSL_accept failed");
+ if (SSL_accept(ssl) != SSL_SUCCESS)
+ ServerError(ctx, ssl, clientfd, "SSL_accept failed");
+
showPeer(ssl);
- printf("Using Cipher Suite %s\n", SSL_get_cipher(ssl));
+ printf("Using Cipher Suite: %s\n", SSL_get_cipher(ssl));
char command[1024];
command[SSL_read(ssl, command, sizeof(command))] = 0;
@@ -46,12 +53,14 @@ THREAD_RETURN YASSL_API server_test(void* args)
char msg[] = "I hear you, fa shizzle!";
if (SSL_write(ssl, msg, sizeof(msg)) != sizeof(msg))
- err_sys("SSL_write failed");
+ ServerError(ctx, ssl, clientfd, "SSL_write failed");
DH_free(dh);
SSL_CTX_free(ctx);
SSL_free(ssl);
+ tcp_close(clientfd);
+
((func_args*)args)->return_code = 0;
return 0;
}
diff --git a/extra/yassl/include/buffer.hpp b/extra/yassl/include/buffer.hpp
index 4816f79a9bc..c2709a8c847 100644
--- a/extra/yassl/include/buffer.hpp
+++ b/extra/yassl/include/buffer.hpp
@@ -34,7 +34,10 @@
#include <assert.h> // assert
#include "yassl_types.hpp" // ysDelete
#include "memory.hpp" // mySTL::auto_ptr
-#include "algorithm.hpp" // mySTL::swap
+#include STL_ALGORITHM_FILE
+
+
+namespace STL = STL_NAMESPACE;
#ifdef _MSC_VER
@@ -199,7 +202,7 @@ struct del_ptr_zero
void operator()(T*& p) const
{
T* tmp = 0;
- mySTL::swap(tmp, p);
+ STL::swap(tmp, p);
checked_delete(tmp);
}
};
diff --git a/extra/yassl/include/cert_wrapper.hpp b/extra/yassl/include/cert_wrapper.hpp
index 8b5b7491772..761be0e9b04 100644
--- a/extra/yassl/include/cert_wrapper.hpp
+++ b/extra/yassl/include/cert_wrapper.hpp
@@ -41,8 +41,12 @@
#include "yassl_types.hpp" // SignatureAlgorithm
#include "buffer.hpp" // input_buffer
#include "asn.hpp" // SignerList
-#include "list.hpp" // mySTL::list
-#include "algorithm.hpp" // mySTL::for_each
+#include STL_LIST_FILE
+#include STL_ALGORITHM_FILE
+
+
+namespace STL = STL_NAMESPACE;
+
namespace yaSSL {
@@ -72,7 +76,7 @@ private:
// Certificate Manager keeps a list of the cert chain and public key
class CertManager {
- typedef mySTL::list<x509*> CertList;
+ typedef STL::list<x509*> CertList;
CertList list_; // self
input_buffer privateKey_;
@@ -120,6 +124,7 @@ public:
void setVerifyNone();
void setFailNoCert();
void setSendVerify();
+ void setPeerX509(X509*);
private:
CertManager(const CertManager&); // hide copy
CertManager& operator=(const CertManager&); // and assign
diff --git a/extra/yassl/include/crypto_wrapper.hpp b/extra/yassl/include/crypto_wrapper.hpp
index 4c4e4d5da5b..83cf3d26398 100644
--- a/extra/yassl/include/crypto_wrapper.hpp
+++ b/extra/yassl/include/crypto_wrapper.hpp
@@ -416,7 +416,17 @@ private:
class x509;
-x509* PemToDer(FILE*, CertType);
+struct EncryptedInfo {
+ enum { IV_SZ = 32, NAME_SZ = 80 };
+ char name[NAME_SZ]; // max one line
+ byte iv[IV_SZ]; // in base16 rep
+ uint ivSz;
+ bool set;
+
+ EncryptedInfo() : ivSz(0), set(false) {}
+};
+
+x509* PemToDer(FILE*, CertType, EncryptedInfo* info = 0);
} // naemspace
diff --git a/extra/yassl/include/factory.hpp b/extra/yassl/include/factory.hpp
index 5619e90cd62..04d742431dc 100644
--- a/extra/yassl/include/factory.hpp
+++ b/extra/yassl/include/factory.hpp
@@ -35,10 +35,12 @@
#ifndef yaSSL_FACTORY_HPP
#define yaSSL_FACTORY_HPP
-#include "vector.hpp"
-#include "pair.hpp"
+#include STL_VECTOR_FILE
+#include STL_PAIR_FILE
+namespace STL = STL_NAMESPACE;
+
// VC60 workaround: it doesn't allow typename in some places
#if defined(_MSC_VER) && (_MSC_VER < 1300)
@@ -58,8 +60,8 @@ template<class AbstractProduct,
typename ProductCreator = AbstractProduct* (*)()
>
class Factory {
- typedef mySTL::pair<IdentifierType, ProductCreator> CallBack;
- typedef mySTL::vector<CallBack> CallBackVector;
+ typedef STL::pair<IdentifierType, ProductCreator> CallBack;
+ typedef STL::vector<CallBack> CallBackVector;
CallBackVector callbacks_;
public:
@@ -79,14 +81,16 @@ public:
// register callback
void Register(const IdentifierType& id, ProductCreator pc)
{
- callbacks_.push_back(mySTL::make_pair(id, pc));
+ callbacks_.push_back(STL::make_pair(id, pc));
}
// THE Creator, returns a new object of the proper type or 0
AbstractProduct* CreateObject(const IdentifierType& id) const
{
- const CallBack* first = callbacks_.begin();
- const CallBack* last = callbacks_.end();
+ typedef typename STL::vector<CallBack>::const_iterator cIter;
+
+ cIter first = callbacks_.begin();
+ cIter last = callbacks_.end();
while (first != last) {
if (first->first == id)
diff --git a/extra/yassl/include/openssl/ssl.h b/extra/yassl/include/openssl/ssl.h
index 47b4d075894..5e7290d2a7a 100644
--- a/extra/yassl/include/openssl/ssl.h
+++ b/extra/yassl/include/openssl/ssl.h
@@ -41,7 +41,7 @@
#include "rsa.h"
-#define YASSL_VERSION "1.3.7"
+#define YASSL_VERSION "1.4.3"
#if defined(__cplusplus)
@@ -505,6 +505,8 @@ ASN1_TIME* X509_get_notAfter(X509* x);
#define V_ASN1_UTF8STRING 12
#define GEN_DNS 2
+#define CERTFICATE_ERROR 0x14090086 /* SSLv3 error */
+
typedef struct MD4_CTX {
int buffer[32]; /* big enough to hold, check size in Init */
diff --git a/extra/yassl/include/socket_wrapper.hpp b/extra/yassl/include/socket_wrapper.hpp
index 1dd61b63148..9fc0d62f90e 100644
--- a/extra/yassl/include/socket_wrapper.hpp
+++ b/extra/yassl/include/socket_wrapper.hpp
@@ -71,6 +71,7 @@ typedef unsigned char byte;
class Socket {
socket_t socket_; // underlying socket descriptor
bool wouldBlock_; // for non-blocking data
+ bool blocking_; // is option set
public:
explicit Socket(socket_t s = INVALID_SOCKET);
~Socket();
@@ -84,6 +85,7 @@ public:
bool wait();
bool WouldBlock() const;
+ bool IsBlocking() const;
void closeSocket();
void shutDown(int how = SD_SEND);
diff --git a/extra/yassl/include/yassl_error.hpp b/extra/yassl/include/yassl_error.hpp
index 3c3d5fa5231..72b79b05dbd 100644
--- a/extra/yassl/include/yassl_error.hpp
+++ b/extra/yassl/include/yassl_error.hpp
@@ -54,7 +54,11 @@ enum YasslError {
verify_error = 112,
send_error = 113,
receive_error = 114,
- certificate_error = 115
+ certificate_error = 115,
+ privateKey_error = 116,
+ badVersion_error = 117
+
+ // !!!! add error message to .cpp !!!!
// 1000+ from TaoCrypt error.hpp
diff --git a/extra/yassl/include/yassl_imp.hpp b/extra/yassl/include/yassl_imp.hpp
index 6e475c23db8..180d7fe7fe1 100644
--- a/extra/yassl/include/yassl_imp.hpp
+++ b/extra/yassl/include/yassl_imp.hpp
@@ -39,7 +39,10 @@
#include "yassl_types.hpp"
#include "factory.hpp"
-#include "list.hpp" // mySTL::list
+#include STL_LIST_FILE
+
+
+namespace STL = STL_NAMESPACE;
namespace yaSSL {
@@ -427,7 +430,7 @@ private:
class CertificateRequest : public HandShakeBase {
ClientCertificateType certificate_types_[CERT_TYPES];
int typeTotal_;
- mySTL::list<DistinguishedName> certificate_authorities_;
+ STL::list<DistinguishedName> certificate_authorities_;
public:
CertificateRequest();
~CertificateRequest();
diff --git a/extra/yassl/include/yassl_int.hpp b/extra/yassl/include/yassl_int.hpp
index 26900aed3af..28e9d237622 100644
--- a/extra/yassl/include/yassl_int.hpp
+++ b/extra/yassl/include/yassl_int.hpp
@@ -40,6 +40,13 @@
#include "lock.hpp"
#include "openssl/ssl.h" // ASN1_STRING and DH
+#ifdef _POSIX_THREADS
+ #include <pthread.h>
+#endif
+
+
+namespace STL = STL_NAMESPACE;
+
namespace yaSSL {
@@ -80,12 +87,35 @@ enum ServerState {
};
+// client connect state for nonblocking restart
+enum ConnectState {
+ CONNECT_BEGIN = 0,
+ CLIENT_HELLO_SENT,
+ FIRST_REPLY_DONE,
+ FINISHED_DONE,
+ SECOND_REPLY_DONE
+};
+
+
+// server accpet state for nonblocking restart
+enum AcceptState {
+ ACCEPT_BEGIN = 0,
+ ACCEPT_FIRST_REPLY_DONE,
+ SERVER_HELLO_DONE,
+ ACCEPT_SECOND_REPLY_DONE,
+ ACCEPT_FINISHED_DONE,
+ ACCEPT_THIRD_REPLY_DONE
+};
+
+
// combines all states
class States {
RecordLayerState recordLayer_;
HandShakeState handshakeLayer_;
ClientState clientState_;
ServerState serverState_;
+ ConnectState connectState_;
+ AcceptState acceptState_;
char errorString_[MAX_ERROR_SZ];
YasslError what_;
public:
@@ -95,6 +125,8 @@ public:
const HandShakeState& getHandShake() const;
const ClientState& getClient() const;
const ServerState& getServer() const;
+ const ConnectState& GetConnect() const;
+ const AcceptState& GetAccept() const;
const char* getString() const;
YasslError What() const;
@@ -102,6 +134,8 @@ public:
HandShakeState& useHandShake();
ClientState& useClient();
ServerState& useServer();
+ ConnectState& UseConnect();
+ AcceptState& UseAccept();
char* useString();
void SetError(YasslError);
private:
@@ -142,8 +176,9 @@ public:
X509_NAME(const char*, size_t sz);
~X509_NAME();
- char* GetName();
+ const char* GetName() const;
ASN1_STRING* GetEntry(int i);
+ size_t GetLength() const;
private:
X509_NAME(const X509_NAME&); // hide copy
X509_NAME& operator=(const X509_NAME&); // and assign
@@ -157,6 +192,9 @@ public:
~StringHolder();
ASN1_STRING* GetString();
+private:
+ StringHolder(const StringHolder&); // hide copy
+ StringHolder& operator=(const StringHolder&); // and assign
};
@@ -176,6 +214,7 @@ public:
ASN1_STRING* GetBefore();
ASN1_STRING* GetAfter();
+
private:
X509(const X509&); // hide copy
X509& operator=(const X509&); // and assign
@@ -202,6 +241,7 @@ class SSL_SESSION {
uint bornOn_; // create time in seconds
uint timeout_; // timeout in seconds
RandomPool& random_; // will clean master secret
+ X509* peerX509_;
public:
explicit SSL_SESSION(RandomPool&);
SSL_SESSION(const SSL&, RandomPool&);
@@ -212,17 +252,20 @@ public:
const Cipher* GetSuite() const;
uint GetBornOn() const;
uint GetTimeOut() const;
+ X509* GetPeerX509() const;
void SetTimeOut(uint);
SSL_SESSION& operator=(const SSL_SESSION&); // allow assign for resumption
private:
SSL_SESSION(const SSL_SESSION&); // hide copy
+
+ void CopyX509(X509*);
};
// holds all sessions
class Sessions {
- mySTL::list<SSL_SESSION*> list_;
+ STL::list<SSL_SESSION*> list_;
RandomPool random_; // for session cleaning
Mutex mutex_; // no-op for single threaded
@@ -241,8 +284,42 @@ private:
};
+#ifdef _POSIX_THREADS
+ typedef pthread_t THREAD_ID_T;
+#else
+ typedef DWORD THREAD_ID_T;
+#endif
+
+// thread error data
+struct ThreadError {
+ THREAD_ID_T threadID_;
+ int errorID_;
+};
+
+
+// holds all errors
+class Errors {
+ STL::list<ThreadError> list_;
+ Mutex mutex_;
+
+ Errors() {} // only GetErrors can create
+public:
+ int Lookup(bool peek); // self lookup
+ void Add(int);
+ void Remove(); // remove self
+
+ ~Errors() {}
+
+ friend Errors& GetErrors(); // singleton creator
+private:
+ Errors(const Errors&); // hide copy
+ Errors& operator=(const Errors); // and assign
+};
+
+
Sessions& GetSessions(); // forward singletons
sslFactory& GetSSL_Factory();
+Errors& GetErrors();
// openSSL method and context types
@@ -252,8 +329,10 @@ class SSL_METHOD {
bool verifyPeer_; // request or send certificate
bool verifyNone_; // whether to verify certificate
bool failNoCert_;
+ bool multipleProtocol_; // for SSLv23 compatibility
public:
- explicit SSL_METHOD(ConnectionEnd ce, ProtocolVersion pv);
+ SSL_METHOD(ConnectionEnd ce, ProtocolVersion pv,
+ bool multipleProtocol = false);
ProtocolVersion getVersion() const;
ConnectionEnd getSide() const;
@@ -265,6 +344,7 @@ public:
bool verifyPeer() const;
bool verifyNone() const;
bool failNoCert() const;
+ bool multipleProtocol() const;
private:
SSL_METHOD(const SSL_METHOD&); // hide copy
SSL_METHOD& operator=(const SSL_METHOD&); // and assign
@@ -334,7 +414,7 @@ private:
// the SSL context
class SSL_CTX {
public:
- typedef mySTL::list<x509*> CertList;
+ typedef STL::list<x509*> CertList;
private:
SSL_METHOD* method_;
x509* certificate_;
@@ -342,6 +422,8 @@ private:
CertList caList_;
Ciphers ciphers_;
DH_Parms dhParms_;
+ pem_password_cb passwordCb_;
+ void* userData_;
Stats stats_;
Mutex mutex_; // for Stats
public:
@@ -354,12 +436,16 @@ public:
const Ciphers& GetCiphers() const;
const DH_Parms& GetDH_Parms() const;
const Stats& GetStats() const;
+ pem_password_cb GetPasswordCb() const;
+ void* GetUserData() const;
void setVerifyPeer();
void setVerifyNone();
void setFailNoCert();
bool SetCipherList(const char*);
bool SetDH(const DH&);
+ void SetPasswordCb(pem_password_cb cb);
+ void SetUserData(void*);
void IncrementStats(StatsField);
void AddCA(x509* ca);
@@ -434,13 +520,14 @@ private:
// holds input and output buffers
class Buffers {
public:
- typedef mySTL::list<input_buffer*> inputList;
- typedef mySTL::list<output_buffer*> outputList;
+ typedef STL::list<input_buffer*> inputList;
+ typedef STL::list<output_buffer*> outputList;
private:
inputList dataList_; // list of users app data / handshake
outputList handShakeList_; // buffered handshake msgs
+ input_buffer* rawInput_; // buffered raw input yet to process
public:
- Buffers() {}
+ Buffers();
~Buffers();
const inputList& getData() const;
@@ -448,6 +535,9 @@ public:
inputList& useData();
outputList& useHandShake();
+
+ void SetRawInput(input_buffer*); // takes ownership
+ input_buffer* TakeRawInput(); // takes ownership
private:
Buffers(const Buffers&); // hide copy
Buffers& operator=(const Buffers&); // and assign
@@ -502,6 +592,7 @@ public:
const sslFactory& getFactory() const;
const Socket& getSocket() const;
YasslError GetError() const;
+ bool GetMultiProtocol() const;
Crypto& useCrypto();
Security& useSecurity();
@@ -509,6 +600,7 @@ public:
sslHashes& useHashes();
Socket& useSocket();
Log& useLog();
+ Buffers& useBuffers();
// sets
void set_pending(Cipher suite);
diff --git a/extra/yassl/include/yassl_types.hpp b/extra/yassl/include/yassl_types.hpp
index b75a2a45302..e602ee180bf 100644
--- a/extra/yassl/include/yassl_types.hpp
+++ b/extra/yassl/include/yassl_types.hpp
@@ -38,6 +38,8 @@
namespace yaSSL {
+#define YASSL_LIB
+
#ifdef YASSL_PURE_C
@@ -76,7 +78,7 @@ namespace yaSSL {
::operator delete[](ptr, yaSSL::ys);
}
- #define NEW_YS new (ys)
+ #define NEW_YS new (yaSSL::ys)
// to resolve compiler generated operator delete on base classes with
// virtual destructors (when on stack), make sure doesn't get called
@@ -122,6 +124,39 @@ typedef opaque byte;
typedef unsigned int uint;
+#ifdef USE_SYS_STL
+ // use system STL
+ #define STL_VECTOR_FILE <vector>
+ #define STL_LIST_FILE <list>
+ #define STL_ALGORITHM_FILE <algorithm>
+ #define STL_MEMORY_FILE <memory>
+ #define STL_PAIR_FILE <utility>
+
+ #define STL_NAMESPACE std
+#else
+ // use mySTL
+ #define STL_VECTOR_FILE "vector.hpp"
+ #define STL_LIST_FILE "list.hpp"
+ #define STL_ALGORITHM_FILE "algorithm.hpp"
+ #define STL_MEMORY_FILE "memory.hpp"
+ #define STL_PAIR_FILE "pair.hpp"
+
+ #define STL_NAMESPACE mySTL
+#endif
+
+
+#ifdef min
+ #undef min
+#endif
+
+template <typename T>
+T min(T a, T b)
+{
+ return a < b ? a : b;
+}
+
+
+
// all length constants in bytes
const int ID_LEN = 32; // session id length
const int SUITE_LEN = 2; // cipher suite length
@@ -163,6 +198,7 @@ const int DES_BLOCK = 8; // DES is always fixed block size 8
const int DES_IV_SZ = DES_BLOCK; // Init Vector length for DES
const int RC4_KEY_SZ = 16; // RC4 Key length
const int AES_128_KEY_SZ = 16; // AES 128bit Key length
+const int AES_192_KEY_SZ = 24; // AES 192bit Key length
const int AES_256_KEY_SZ = 32; // AES 256bit Key length
const int AES_BLOCK_SZ = 16; // AES 128bit block size, rfc 3268
const int AES_IV_SZ = AES_BLOCK_SZ; // AES Init Vector length
diff --git a/extra/yassl/src/Makefile.am b/extra/yassl/src/Makefile.am
index 2b3e1aea5f5..910bbbdd13f 100644
--- a/extra/yassl/src/Makefile.am
+++ b/extra/yassl/src/Makefile.am
@@ -1,4 +1,4 @@
-INCLUDES = -I../include -I../taocrypt/include -I../mySTL
+INCLUDES = -I../include -I../taocrypt/include -I../taocrypt/mySTL
noinst_LTLIBRARIES = libyassl.la
libyassl_la_SOURCES = buffer.cpp cert_wrapper.cpp crypto_wrapper.cpp \
@@ -6,3 +6,7 @@ libyassl_la_SOURCES = buffer.cpp cert_wrapper.cpp crypto_wrapper.cpp \
template_instnt.cpp timer.cpp yassl_imp.cpp yassl_error.cpp yassl_int.cpp
EXTRA_DIST = $(wildcard ../include/*.hpp) $(wildcard ../include/openssl/*.h)
AM_CXXFLAGS = -DYASSL_PURE_C -DYASSL_PREFIX
+
+# Don't update the files from bitkeeper
+%::SCCS/s.%
+
diff --git a/extra/yassl/src/cert_wrapper.cpp b/extra/yassl/src/cert_wrapper.cpp
index 6ad0aa568ed..c3ae9c0c561 100644
--- a/extra/yassl/src/cert_wrapper.cpp
+++ b/extra/yassl/src/cert_wrapper.cpp
@@ -63,8 +63,8 @@ x509::x509(const x509& that) : length_(that.length_),
void x509::Swap(x509& that)
{
- mySTL::swap(length_, that.length_);
- mySTL::swap(buffer_, that.buffer_);
+ STL::swap(length_, that.length_);
+ STL::swap(buffer_, that.buffer_);
}
@@ -105,11 +105,11 @@ CertManager::~CertManager()
{
ysDelete(peerX509_);
- mySTL::for_each(signers_.begin(), signers_.end(), del_ptr_zero()) ;
+ STL::for_each(signers_.begin(), signers_.end(), del_ptr_zero()) ;
- mySTL::for_each(peerList_.begin(), peerList_.end(), del_ptr_zero()) ;
+ STL::for_each(peerList_.begin(), peerList_.end(), del_ptr_zero()) ;
- mySTL::for_each(list_.begin(), list_.end(), del_ptr_zero()) ;
+ STL::for_each(list_.begin(), list_.end(), del_ptr_zero()) ;
}
@@ -242,7 +242,7 @@ uint CertManager::get_privateKeyLength() const
// Validate the peer's certificate list, from root to peer (last to first)
int CertManager::Validate()
{
- CertList::iterator last = peerList_.rbegin(); // fix this
+ CertList::reverse_iterator last = peerList_.rbegin();
int count = peerList_.size();
while ( count > 1 ) {
@@ -255,7 +255,7 @@ int CertManager::Validate()
const TaoCrypt::PublicKey& key = cert.GetPublicKey();
signers_.push_back(NEW_YS TaoCrypt::Signer(key.GetKey(), key.size(),
cert.GetCommonName(), cert.GetHash()));
- --last;
+ ++last;
--count;
}
@@ -310,6 +310,23 @@ int CertManager::SetPrivateKey(const x509& key)
}
+// Store OpenSSL type peer's cert
+void CertManager::setPeerX509(X509* x)
+{
+ assert(peerX509_ == 0);
+ if (x == 0) return;
+
+ X509_NAME* issuer = x->GetIssuer();
+ X509_NAME* subject = x->GetSubject();
+ ASN1_STRING* before = x->GetBefore();
+ ASN1_STRING* after = x->GetAfter();
+
+ peerX509_ = NEW_YS X509(issuer->GetName(), issuer->GetLength(),
+ subject->GetName(), subject->GetLength(), (const char*) before->data,
+ before->length, (const char*) after->data, after->length);
+}
+
+
#if defined(USE_CML_LIB)
// Get the peer's certificate, extract and save public key
diff --git a/extra/yassl/src/crypto_wrapper.cpp b/extra/yassl/src/crypto_wrapper.cpp
index 799106ec7c0..7344a70b367 100644
--- a/extra/yassl/src/crypto_wrapper.cpp
+++ b/extra/yassl/src/crypto_wrapper.cpp
@@ -908,7 +908,7 @@ void DiffieHellman::get_parms(byte* bp, byte* bg, byte* bpub) const
// convert PEM file to DER x509 type
-x509* PemToDer(FILE* file, CertType type)
+x509* PemToDer(FILE* file, CertType type, EncryptedInfo* info)
{
using namespace TaoCrypt;
@@ -935,6 +935,37 @@ x509* PemToDer(FILE* file, CertType type)
break;
}
+ // remove encrypted header if there
+ if (fgets(line, sizeof(line), file)) {
+ char encHeader[] = "Proc-Type";
+ if (strncmp(encHeader, line, strlen(encHeader)) == 0 &&
+ fgets(line,sizeof(line), file)) {
+
+ char* start = strstr(line, "DES");
+ char* finish = strstr(line, ",");
+ if (!start)
+ start = strstr(line, "AES");
+
+ if (!info) return 0;
+
+ if ( start && finish && (start < finish)) {
+ memcpy(info->name, start, finish - start);
+ info->name[finish - start] = 0;
+ memcpy(info->iv, finish + 1, sizeof(info->iv));
+
+ char* newline = strstr(line, "\r");
+ if (!newline) newline = strstr(line, "\n");
+ if (newline && (newline > finish)) {
+ info->ivSz = newline - (finish + 1);
+ info->set = true;
+ }
+ }
+ fgets(line,sizeof(line), file); // get blank line
+ begin = ftell(file);
+ }
+
+ }
+
while(fgets(line, sizeof(line), file))
if (strncmp(footer, line, strlen(footer)) == 0) {
foundEnd = true;
@@ -956,7 +987,7 @@ x509* PemToDer(FILE* file, CertType type)
Base64Decoder b64Dec(der);
uint sz = der.size();
- mySTL::auto_ptr<x509> x(NEW_YS x509(sz), ysDelete);
+ mySTL::auto_ptr<x509> x(NEW_YS x509(sz));
memcpy(x->use_buffer(), der.get_buffer(), sz);
return x.release();
diff --git a/extra/yassl/src/handshake.cpp b/extra/yassl/src/handshake.cpp
index e93f5385b3d..25f36c4ea8c 100644
--- a/extra/yassl/src/handshake.cpp
+++ b/extra/yassl/src/handshake.cpp
@@ -37,7 +37,6 @@
namespace yaSSL {
-using mySTL::min;
// Build a client hello message from cipher suites and compression method
@@ -363,7 +362,7 @@ void p_hash(output_buffer& result, const output_buffer& secret,
uint lastLen = result.get_capacity() % len;
opaque previous[SHA_LEN]; // max size
opaque current[SHA_LEN]; // max size
- mySTL::auto_ptr<Digest> hmac(ysDelete);
+ mySTL::auto_ptr<Digest> hmac;
if (lastLen) times += 1;
@@ -582,7 +581,7 @@ void hmac(SSL& ssl, byte* digest, const byte* buffer, uint sz,
void TLS_hmac(SSL& ssl, byte* digest, const byte* buffer, uint sz,
ContentType content, bool verify)
{
- mySTL::auto_ptr<Digest> hmac(ysDelete);
+ mySTL::auto_ptr<Digest> hmac;
opaque seq[SEQ_SZ] = { 0x00, 0x00, 0x00, 0x00 };
opaque length[LENGTH_SZ];
opaque inner[SIZEOF_ENUM + VERSION_SZ + LENGTH_SZ]; // type + version + len
@@ -660,25 +659,25 @@ void build_certHashes(SSL& ssl, Hashes& hashes)
-// do process input requests
-mySTL::auto_ptr<input_buffer>
-DoProcessReply(SSL& ssl, mySTL::auto_ptr<input_buffer> buffered)
+// do process input requests, return 0 is done, 1 is call again to complete
+int DoProcessReply(SSL& ssl)
{
// wait for input if blocking
if (!ssl.useSocket().wait()) {
ssl.SetError(receive_error);
- buffered.reset(0);
- return buffered;
+ return 0;
}
uint ready = ssl.getSocket().get_ready();
- if (!ready) return buffered;
+ if (!ready) return 1;
// add buffered data if its there
- uint buffSz = buffered.get() ? buffered.get()->get_size() : 0;
+ input_buffer* buffered = ssl.useBuffers().TakeRawInput();
+ uint buffSz = buffered ? buffered->get_size() : 0;
input_buffer buffer(buffSz + ready);
if (buffSz) {
- buffer.assign(buffered.get()->get_buffer(), buffSz);
- buffered.reset(0);
+ buffer.assign(buffered->get_buffer(), buffSz);
+ ysDelete(buffered);
+ buffered = 0;
}
// add new data
@@ -692,10 +691,8 @@ DoProcessReply(SSL& ssl, mySTL::auto_ptr<input_buffer> buffered)
ssl.getStates().getServer() == clientNull)
if (buffer.peek() != handshake) {
ProcessOldClientHello(buffer, ssl);
- if (ssl.GetError()) {
- buffered.reset(0);
- return buffered;
- }
+ if (ssl.GetError())
+ return 0;
}
while(!buffer.eof()) {
@@ -715,31 +712,28 @@ DoProcessReply(SSL& ssl, mySTL::auto_ptr<input_buffer> buffered)
// put header in front for next time processing
uint extra = needHdr ? 0 : RECORD_HEADER;
uint sz = buffer.get_remaining() + extra;
- buffered.reset(NEW_YS input_buffer(sz, buffer.get_buffer() +
- buffer.get_current() - extra, sz));
- break;
+ ssl.useBuffers().SetRawInput(NEW_YS input_buffer(sz,
+ buffer.get_buffer() + buffer.get_current() - extra, sz));
+ return 1;
}
while (buffer.get_current() < hdr.length_ + RECORD_HEADER + offset) {
// each message in record, can be more than 1 if not encrypted
if (ssl.getSecurity().get_parms().pending_ == false) // cipher on
decrypt_message(ssl, buffer, hdr.length_);
- mySTL::auto_ptr<Message> msg(mf.CreateObject(hdr.type_), ysDelete);
+ mySTL::auto_ptr<Message> msg(mf.CreateObject(hdr.type_));
if (!msg.get()) {
ssl.SetError(factory_error);
- buffered.reset(0);
- return buffered;
+ return 0;
}
buffer >> *msg;
msg->Process(buffer, ssl);
- if (ssl.GetError()) {
- buffered.reset(0);
- return buffered;
- }
+ if (ssl.GetError())
+ return 0;
}
offset += hdr.length_ + RECORD_HEADER;
}
- return buffered;
+ return 0;
}
@@ -747,16 +741,17 @@ DoProcessReply(SSL& ssl, mySTL::auto_ptr<input_buffer> buffered)
void processReply(SSL& ssl)
{
if (ssl.GetError()) return;
- mySTL::auto_ptr<input_buffer> buffered(ysDelete);
- for (;;) {
- mySTL::auto_ptr<input_buffer> tmp(DoProcessReply(ssl, buffered));
- if (tmp.get()) // had only part of a record's data, call again
- buffered = tmp;
- else
- break;
- if (ssl.GetError()) return;
+ if (DoProcessReply(ssl))
+ // didn't complete process
+ if (!ssl.getSocket().IsBlocking()) {
+ // keep trying now
+ while (!ssl.GetError())
+ if (DoProcessReply(ssl) == 0) break;
}
+ else
+ // user will have try again later
+ ssl.SetError(YasslError(SSL_ERROR_WANT_READ));
}
@@ -793,7 +788,7 @@ void sendClientKeyExchange(SSL& ssl, BufferOutput buffer)
RecordLayerHeader rlHeader;
HandShakeHeader hsHeader;
- mySTL::auto_ptr<output_buffer> out(NEW_YS output_buffer, ysDelete);
+ mySTL::auto_ptr<output_buffer> out(NEW_YS output_buffer);
buildHeaders(ssl, hsHeader, rlHeader, ck);
buildOutput(*out.get(), rlHeader, hsHeader, ck);
hashHandShake(ssl, *out.get());
@@ -814,7 +809,7 @@ void sendServerKeyExchange(SSL& ssl, BufferOutput buffer)
RecordLayerHeader rlHeader;
HandShakeHeader hsHeader;
- mySTL::auto_ptr<output_buffer> out(NEW_YS output_buffer, ysDelete);
+ mySTL::auto_ptr<output_buffer> out(NEW_YS output_buffer);
buildHeaders(ssl, hsHeader, rlHeader, sk);
buildOutput(*out.get(), rlHeader, hsHeader, sk);
hashHandShake(ssl, *out.get());
@@ -839,7 +834,7 @@ void sendChangeCipher(SSL& ssl, BufferOutput buffer)
ChangeCipherSpec ccs;
RecordLayerHeader rlHeader;
buildHeader(ssl, rlHeader, ccs);
- mySTL::auto_ptr<output_buffer> out(NEW_YS output_buffer, ysDelete);
+ mySTL::auto_ptr<output_buffer> out(NEW_YS output_buffer);
buildOutput(*out.get(), rlHeader, ccs);
if (buffer == buffered)
@@ -856,7 +851,7 @@ void sendFinished(SSL& ssl, ConnectionEnd side, BufferOutput buffer)
Finished fin;
buildFinished(ssl, fin, side == client_end ? client : server);
- mySTL::auto_ptr<output_buffer> out(NEW_YS output_buffer, ysDelete);
+ mySTL::auto_ptr<output_buffer> out(NEW_YS output_buffer);
cipherFinished(ssl, fin, *out.get()); // hashes handshake
if (ssl.getSecurity().get_resuming()) {
@@ -955,7 +950,7 @@ void sendServerHello(SSL& ssl, BufferOutput buffer)
ServerHello sh(ssl.getSecurity().get_connection().version_);
RecordLayerHeader rlHeader;
HandShakeHeader hsHeader;
- mySTL::auto_ptr<output_buffer> out(NEW_YS output_buffer, ysDelete);
+ mySTL::auto_ptr<output_buffer> out(NEW_YS output_buffer);
buildServerHello(ssl, sh);
ssl.set_random(sh.get_random(), server_end);
@@ -978,7 +973,7 @@ void sendServerHelloDone(SSL& ssl, BufferOutput buffer)
ServerHelloDone shd;
RecordLayerHeader rlHeader;
HandShakeHeader hsHeader;
- mySTL::auto_ptr<output_buffer> out(NEW_YS output_buffer, ysDelete);
+ mySTL::auto_ptr<output_buffer> out(NEW_YS output_buffer);
buildHeaders(ssl, hsHeader, rlHeader, shd);
buildOutput(*out.get(), rlHeader, hsHeader, shd);
@@ -999,7 +994,7 @@ void sendCertificate(SSL& ssl, BufferOutput buffer)
Certificate cert(ssl.getCrypto().get_certManager().get_cert());
RecordLayerHeader rlHeader;
HandShakeHeader hsHeader;
- mySTL::auto_ptr<output_buffer> out(NEW_YS output_buffer, ysDelete);
+ mySTL::auto_ptr<output_buffer> out(NEW_YS output_buffer);
buildHeaders(ssl, hsHeader, rlHeader, cert);
buildOutput(*out.get(), rlHeader, hsHeader, cert);
@@ -1021,7 +1016,7 @@ void sendCertificateRequest(SSL& ssl, BufferOutput buffer)
request.Build();
RecordLayerHeader rlHeader;
HandShakeHeader hsHeader;
- mySTL::auto_ptr<output_buffer> out(NEW_YS output_buffer, ysDelete);
+ mySTL::auto_ptr<output_buffer> out(NEW_YS output_buffer);
buildHeaders(ssl, hsHeader, rlHeader, request);
buildOutput(*out.get(), rlHeader, hsHeader, request);
@@ -1043,7 +1038,7 @@ void sendCertificateVerify(SSL& ssl, BufferOutput buffer)
verify.Build(ssl);
RecordLayerHeader rlHeader;
HandShakeHeader hsHeader;
- mySTL::auto_ptr<output_buffer> out(NEW_YS output_buffer, ysDelete);
+ mySTL::auto_ptr<output_buffer> out(NEW_YS output_buffer);
buildHeaders(ssl, hsHeader, rlHeader, verify);
buildOutput(*out.get(), rlHeader, hsHeader, verify);
diff --git a/extra/yassl/src/socket_wrapper.cpp b/extra/yassl/src/socket_wrapper.cpp
index 7790001fc2d..70944831884 100644
--- a/extra/yassl/src/socket_wrapper.cpp
+++ b/extra/yassl/src/socket_wrapper.cpp
@@ -41,9 +41,10 @@
#include <netinet/in.h>
#include <sys/ioctl.h>
#include <string.h>
+ #include <fcntl.h>
#endif // _WIN32
-#if defined(__sun) || defined(__SCO_VERSION__)
+#if defined(__sun) || defined(__SCO_VERSION__) || defined(__NETWARE__)
#include <sys/filio.h>
#endif
@@ -62,7 +63,7 @@ namespace yaSSL {
Socket::Socket(socket_t s)
- : socket_(s), wouldBlock_(false)
+ : socket_(s), wouldBlock_(false), blocking_(false)
{}
@@ -148,6 +149,7 @@ uint Socket::receive(byte* buf, unsigned int sz, int flags)
if (get_lastError() == SOCKET_EWOULDBLOCK ||
get_lastError() == SOCKET_EAGAIN) {
wouldBlock_ = true;
+ blocking_ = true; // socket can block, only way to tell for win32
return 0;
}
}
@@ -189,6 +191,12 @@ bool Socket::WouldBlock() const
}
+bool Socket::IsBlocking() const
+{
+ return blocking_;
+}
+
+
void Socket::set_lastError(int errorCode)
{
#ifdef _WIN32
diff --git a/extra/yassl/src/ssl.cpp b/extra/yassl/src/ssl.cpp
index 81e585ff735..a008ea7228b 100644
--- a/extra/yassl/src/ssl.cpp
+++ b/extra/yassl/src/ssl.cpp
@@ -42,6 +42,9 @@
#include "yassl_int.hpp"
#include "md5.hpp" // for TaoCrypt MD5 size assert
#include "md4.hpp" // for TaoCrypt MD4 size assert
+#include "file.hpp" // for TaoCrypt Source
+#include "coding.hpp" // HexDecoder
+#include "helpers.hpp" // for placement new hack
#include <stdio.h>
#ifdef _WIN32
@@ -55,7 +58,6 @@
namespace yaSSL {
-using mySTL::min;
int read_file(SSL_CTX* ctx, const char* file, int format, CertType type)
@@ -93,11 +95,55 @@ int read_file(SSL_CTX* ctx, const char* file, int format, CertType type)
}
}
else {
- x = PemToDer(input, type);
+ EncryptedInfo info;
+ x = PemToDer(input, type, &info);
if (!x) {
fclose(input);
return SSL_BAD_FILE;
}
+ if (info.set) {
+ // decrypt
+ char password[80];
+ pem_password_cb cb = ctx->GetPasswordCb();
+ if (!cb) {
+ fclose(input);
+ return SSL_BAD_FILE;
+ }
+ int passwordSz = cb(password, sizeof(password), 0,
+ ctx->GetUserData());
+ byte key[AES_256_KEY_SZ]; // max sizes
+ byte iv[AES_IV_SZ];
+
+ // use file's salt for key derivation, but not real iv
+ TaoCrypt::Source source(info.iv, info.ivSz);
+ TaoCrypt::HexDecoder dec(source);
+ memcpy(info.iv, source.get_buffer(), min((uint)sizeof(info.iv),
+ source.size()));
+ EVP_BytesToKey(info.name, "MD5", info.iv, (byte*)password,
+ passwordSz, 1, key, iv);
+
+ STL::auto_ptr<BulkCipher> cipher;
+ if (strncmp(info.name, "DES-CBC", 7) == 0)
+ cipher.reset(NEW_YS DES);
+ else if (strncmp(info.name, "DES-EDE3-CBC", 13) == 0)
+ cipher.reset(NEW_YS DES_EDE);
+ else if (strncmp(info.name, "AES-128-CBC", 13) == 0)
+ cipher.reset(NEW_YS AES(AES_128_KEY_SZ));
+ else if (strncmp(info.name, "AES-192-CBC", 13) == 0)
+ cipher.reset(NEW_YS AES(AES_192_KEY_SZ));
+ else if (strncmp(info.name, "AES-256-CBC", 13) == 0)
+ cipher.reset(NEW_YS AES(AES_256_KEY_SZ));
+ else {
+ fclose(input);
+ return SSL_BAD_FILE;
+ }
+ cipher->set_decryptKey(key, info.iv);
+ STL::auto_ptr<x509> newx(NEW_YS x509(x->get_length()));
+ cipher->decrypt(newx->use_buffer(), x->get_buffer(),
+ x->get_length());
+ ysDelete(x);
+ x = newx.release();
+ }
}
}
fclose(input);
@@ -140,8 +186,17 @@ SSL_METHOD* TLSv1_client_method()
SSL_METHOD* SSLv23_server_method()
{
- // compatibility only, no version 2 support
- return SSLv3_server_method();
+ // compatibility only, no version 2 support, but does SSL 3 and TLS 1
+ return NEW_YS SSL_METHOD(server_end, ProtocolVersion(3,1), true);
+}
+
+
+SSL_METHOD* SSLv23_client_method()
+{
+ // compatibility only, no version 2 support, but does SSL 3 and TLS 1
+ // though it sends TLS1 hello not SSLv2 so SSLv3 only servers will decline
+ // TODO: maybe add support to send SSLv2 hello ???
+ return NEW_YS SSL_METHOD(client_end, ProtocolVersion(3,1), true);
}
@@ -178,14 +233,29 @@ int SSL_set_fd(SSL* ssl, int fd)
int SSL_connect(SSL* ssl)
{
+ if (ssl->GetError() == YasslError(SSL_ERROR_WANT_READ))
+ ssl->SetError(no_error);
+
+ ClientState neededState;
+
+ switch (ssl->getStates().GetConnect()) {
+
+ case CONNECT_BEGIN :
sendClientHello(*ssl);
- ClientState neededState = ssl->getSecurity().get_resuming() ?
+ if (!ssl->GetError())
+ ssl->useStates().UseConnect() = CLIENT_HELLO_SENT;
+
+ case CLIENT_HELLO_SENT :
+ neededState = ssl->getSecurity().get_resuming() ?
serverFinishedComplete : serverHelloDoneComplete;
while (ssl->getStates().getClient() < neededState) {
if (ssl->GetError()) break;
processReply(*ssl);
}
+ if (!ssl->GetError())
+ ssl->useStates().UseConnect() = FIRST_REPLY_DONE;
+ case FIRST_REPLY_DONE :
if(ssl->getCrypto().get_certManager().sendVerify())
sendCertificate(*ssl);
@@ -198,18 +268,32 @@ int SSL_connect(SSL* ssl)
sendChangeCipher(*ssl);
sendFinished(*ssl, client_end);
ssl->flushBuffer();
+
+ if (!ssl->GetError())
+ ssl->useStates().UseConnect() = FINISHED_DONE;
+
+ case FINISHED_DONE :
if (!ssl->getSecurity().get_resuming())
while (ssl->getStates().getClient() < serverFinishedComplete) {
if (ssl->GetError()) break;
processReply(*ssl);
}
+ if (!ssl->GetError())
+ ssl->useStates().UseConnect() = SECOND_REPLY_DONE;
+ case SECOND_REPLY_DONE :
ssl->verifyState(serverFinishedComplete);
ssl->useLog().ShowTCP(ssl->getSocket().get_fd());
- if (ssl->GetError())
+ if (ssl->GetError()) {
+ GetErrors().Add(ssl->GetError());
return SSL_FATAL_ERROR;
+ }
return SSL_SUCCESS;
+
+ default :
+ return SSL_FATAL_ERROR; // unkown state
+ }
}
@@ -228,7 +312,17 @@ int SSL_read(SSL* ssl, void* buffer, int sz)
int SSL_accept(SSL* ssl)
{
+ if (ssl->GetError() == YasslError(SSL_ERROR_WANT_READ))
+ ssl->SetError(no_error);
+
+ switch (ssl->getStates().GetAccept()) {
+
+ case ACCEPT_BEGIN :
processReply(*ssl);
+ if (!ssl->GetError())
+ ssl->useStates().UseAccept() = ACCEPT_FIRST_REPLY_DONE;
+
+ case ACCEPT_FIRST_REPLY_DONE :
sendServerHello(*ssl);
if (!ssl->getSecurity().get_resuming()) {
@@ -242,27 +336,51 @@ int SSL_accept(SSL* ssl)
sendServerHelloDone(*ssl);
ssl->flushBuffer();
+ }
+
+ if (!ssl->GetError())
+ ssl->useStates().UseAccept() = SERVER_HELLO_DONE;
+ case SERVER_HELLO_DONE :
+ if (!ssl->getSecurity().get_resuming()) {
while (ssl->getStates().getServer() < clientFinishedComplete) {
if (ssl->GetError()) break;
processReply(*ssl);
}
}
+ if (!ssl->GetError())
+ ssl->useStates().UseAccept() = ACCEPT_SECOND_REPLY_DONE;
+
+ case ACCEPT_SECOND_REPLY_DONE :
sendChangeCipher(*ssl);
sendFinished(*ssl, server_end);
ssl->flushBuffer();
+
+ if (!ssl->GetError())
+ ssl->useStates().UseAccept() = ACCEPT_FINISHED_DONE;
+
+ case ACCEPT_FINISHED_DONE :
if (ssl->getSecurity().get_resuming()) {
while (ssl->getStates().getServer() < clientFinishedComplete) {
if (ssl->GetError()) break;
processReply(*ssl);
}
}
+ if (!ssl->GetError())
+ ssl->useStates().UseAccept() = ACCEPT_THIRD_REPLY_DONE;
+ case ACCEPT_THIRD_REPLY_DONE :
ssl->useLog().ShowTCP(ssl->getSocket().get_fd());
- if (ssl->GetError())
+ if (ssl->GetError()) {
+ GetErrors().Add(ssl->GetError());
return SSL_FATAL_ERROR;
+ }
return SSL_SUCCESS;
+
+ default:
+ return SSL_FATAL_ERROR; // unknown state
+ }
}
@@ -278,6 +396,8 @@ int SSL_do_handshake(SSL* ssl)
int SSL_clear(SSL* ssl)
{
ssl->useSocket().closeSocket();
+ GetErrors().Remove();
+
return SSL_SUCCESS;
}
@@ -289,6 +409,8 @@ int SSL_shutdown(SSL* ssl)
ssl->useLog().ShowTCP(ssl->getSocket().get_fd(), true);
ssl->useSocket().closeSocket();
+ GetErrors().Remove();
+
return SSL_SUCCESS;
}
@@ -762,9 +884,8 @@ void DH_free(DH* dh)
// be created
BIGNUM* BN_bin2bn(const unsigned char* num, int sz, BIGNUM* retVal)
{
- using mySTL::auto_ptr;
bool created = false;
- auto_ptr<BIGNUM> bn(ysDelete);
+ mySTL::auto_ptr<BIGNUM> bn;
if (!retVal) {
created = true;
@@ -825,7 +946,7 @@ const EVP_MD* EVP_md5(void)
const EVP_CIPHER* EVP_des_ede3_cbc(void)
{
- static const char* type = "DES_EDE3_CBC";
+ static const char* type = "DES-EDE3-CBC";
return type;
}
@@ -836,16 +957,37 @@ int EVP_BytesToKey(const EVP_CIPHER* type, const EVP_MD* md, const byte* salt,
// only support MD5 for now
if (strncmp(md, "MD5", 3)) return 0;
- // only support DES_EDE3_CBC for now
- if (strncmp(type, "DES_EDE3_CBC", 12)) return 0;
+ int keyLen = 0;
+ int ivLen = 0;
+
+ // only support CBC DES and AES for now
+ if (strncmp(type, "DES-CBC", 7) == 0) {
+ keyLen = DES_KEY_SZ;
+ ivLen = DES_IV_SZ;
+ }
+ else if (strncmp(type, "DES-EDE3-CBC", 12) == 0) {
+ keyLen = DES_EDE_KEY_SZ;
+ ivLen = DES_IV_SZ;
+ }
+ else if (strncmp(type, "AES-128-CBC", 11) == 0) {
+ keyLen = AES_128_KEY_SZ;
+ ivLen = AES_IV_SZ;
+ }
+ else if (strncmp(type, "AES-192-CBC", 11) == 0) {
+ keyLen = AES_192_KEY_SZ;
+ ivLen = AES_IV_SZ;
+ }
+ else if (strncmp(type, "AES-256-CBC", 11) == 0) {
+ keyLen = AES_256_KEY_SZ;
+ ivLen = AES_IV_SZ;
+ }
+ else
+ return 0;
yaSSL::MD5 myMD;
uint digestSz = myMD.get_digestSize();
byte digest[SHA_LEN]; // max size
- yaSSL::DES_EDE cipher;
- int keyLen = cipher.get_keySize();
- int ivLen = cipher.get_ivSize();
int keyLeft = keyLen;
int ivLeft = ivLen;
int keyOutput = 0;
@@ -878,7 +1020,7 @@ int EVP_BytesToKey(const EVP_CIPHER* type, const EVP_MD* md, const byte* salt,
if (ivLeft && digestLeft) {
int store = min(ivLeft, digestLeft);
- memcpy(&iv[ivLen - ivLeft], digest, store);
+ memcpy(&iv[ivLen - ivLeft], &digest[digestSz - digestLeft], store);
keyOutput += store;
ivLeft -= store;
@@ -954,10 +1096,9 @@ void DES_ecb_encrypt(DES_cblock* input, DES_cblock* output,
}
-void SSL_CTX_set_default_passwd_cb_userdata(SSL_CTX*, void* userdata)
+void SSL_CTX_set_default_passwd_cb_userdata(SSL_CTX* ctx, void* userdata)
{
- // yaSSL doesn't support yet, unencrypt your PEM file with userdata
- // before handing off to yaSSL
+ ctx->SetUserData(userdata);
}
@@ -1034,12 +1175,6 @@ ASN1_TIME* X509_get_notAfter(X509* x)
}
-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;
@@ -1363,9 +1498,9 @@ int SSL_pending(SSL* ssl)
}
- void SSL_CTX_set_default_passwd_cb(SSL_CTX*, pem_password_cb)
+ void SSL_CTX_set_default_passwd_cb(SSL_CTX* ctx, pem_password_cb cb)
{
- // TDOD:
+ ctx->SetPasswordCb(cb);
}
@@ -1428,7 +1563,7 @@ int SSL_pending(SSL* ssl)
void ERR_remove_state(unsigned long)
{
- // TODO:
+ GetErrors().Remove();
}
@@ -1437,16 +1572,30 @@ int SSL_pending(SSL* ssl)
return l & 0xfff;
}
+ unsigned long err_helper(bool peek = false)
+ {
+ int ysError = GetErrors().Lookup(peek);
+
+ // translate cert error for libcurl, it uses OpenSSL hex code
+ switch (ysError) {
+ case TaoCrypt::SIG_OTHER_E:
+ return CERTFICATE_ERROR;
+ break;
+ default :
+ return 0;
+ }
+ }
+
unsigned long ERR_peek_error()
{
- return 0; // TODO:
+ return err_helper(true);
}
unsigned long ERR_get_error()
{
- return ERR_peek_error();
+ return err_helper();
}
diff --git a/extra/yassl/src/template_instnt.cpp b/extra/yassl/src/template_instnt.cpp
index c5fc23dabdb..fb488e47672 100644
--- a/extra/yassl/src/template_instnt.cpp
+++ b/extra/yassl/src/template_instnt.cpp
@@ -65,6 +65,19 @@ template yaSSL::del_ptr_zero for_each<mySTL::list<yaSSL::output_buffer*>::iterat
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);
+template bool list<yaSSL::ThreadError>::erase(list<yaSSL::ThreadError>::iterator);
+template void list<yaSSL::ThreadError>::push_back(yaSSL::ThreadError);
+template void list<yaSSL::ThreadError>::pop_front();
+template void list<yaSSL::ThreadError>::pop_back();
+template list<yaSSL::ThreadError>::~list();
+template pair<int, yaSSL::Message* (*)()>* GetArrayMemory<pair<int, yaSSL::Message* (*)()> >(size_t);
+template void FreeArrayMemory<pair<int, yaSSL::Message* (*)()> >(pair<int, yaSSL::Message* (*)()>*);
+template pair<int, yaSSL::HandShakeBase* (*)()>* GetArrayMemory<pair<int, yaSSL::HandShakeBase* (*)()> >(size_t);
+template void FreeArrayMemory<pair<int, yaSSL::HandShakeBase* (*)()> >(pair<int, yaSSL::HandShakeBase* (*)()>*);
+template pair<int, yaSSL::ServerKeyBase* (*)()>* GetArrayMemory<pair<int, yaSSL::ServerKeyBase* (*)()> >(size_t);
+template void FreeArrayMemory<pair<int, yaSSL::ServerKeyBase* (*)()> >(pair<int, yaSSL::ServerKeyBase* (*)()>*);
+template pair<int, yaSSL::ClientKeyBase* (*)()>* GetArrayMemory<pair<int, yaSSL::ClientKeyBase* (*)()> >(size_t);
+template void FreeArrayMemory<pair<int, yaSSL::ClientKeyBase* (*)()> >(pair<int, yaSSL::ClientKeyBase* (*)()>*);
}
namespace yaSSL {
@@ -90,8 +103,13 @@ template void ysDelete<X509>(X509*);
template void ysDelete<Message>(Message*);
template void ysDelete<sslFactory>(sslFactory*);
template void ysDelete<Sessions>(Sessions*);
+template void ysDelete<Errors>(Errors*);
template void ysArrayDelete<unsigned char>(unsigned char*);
template void ysArrayDelete<char>(char*);
+
+template int min<int>(int, int);
+template unsigned int min<unsigned int>(unsigned int, unsigned int);
+template unsigned long min<unsigned long>(unsigned long, unsigned long);
}
#endif // HAVE_EXPLICIT_TEMPLATE_INSTANTIATION
diff --git a/extra/yassl/src/yassl.cpp b/extra/yassl/src/yassl.cpp
index 5bc8bad8bbc..e253ef84bb5 100644
--- a/extra/yassl/src/yassl.cpp
+++ b/extra/yassl/src/yassl.cpp
@@ -36,21 +36,9 @@
#include "openssl/ssl.h" // get rid of this
-// yaSSL overloads hide these
-void* operator new[](size_t sz)
-{
- return ::operator new(sz);
-}
-
-void operator delete[](void* ptr)
-{
- ::operator delete(ptr);
-}
-
namespace yaSSL {
-using mySTL::min;
struct Base {
diff --git a/extra/yassl/src/yassl_error.cpp b/extra/yassl/src/yassl_error.cpp
index 4f75de34a98..3531c0a2c74 100644
--- a/extra/yassl/src/yassl_error.cpp
+++ b/extra/yassl/src/yassl_error.cpp
@@ -125,13 +125,21 @@ void SetErrorString(YasslError error, char* buffer)
strncpy(buffer, "unable to proccess cerificate", max);
break;
+ case privateKey_error :
+ strncpy(buffer, "unable to proccess private key, bad format", max);
+ break;
+
+ case badVersion_error :
+ strncpy(buffer, "protocl version mismatch", max);
+ break;
+
// openssl errors
case SSL_ERROR_WANT_READ :
strncpy(buffer, "the read operation would block", max);
break;
// TaoCrypt errors
- case NO_ERROR :
+ case NO_ERROR_E :
strncpy(buffer, "not in error state", max);
break;
@@ -235,6 +243,10 @@ void SetErrorString(YasslError error, char* buffer)
strncpy(buffer, "ASN: bad other signature confirmation", max);
break;
+ case CERTFICATE_ERROR :
+ strncpy(buffer, "Unable to verify certificate", max);
+ break;
+
default :
strncpy(buffer, "unknown error number", max);
}
diff --git a/extra/yassl/src/yassl_imp.cpp b/extra/yassl/src/yassl_imp.cpp
index 98f8035732e..bd07f8b70f2 100644
--- a/extra/yassl/src/yassl_imp.cpp
+++ b/extra/yassl/src/yassl_imp.cpp
@@ -139,7 +139,7 @@ void DH_Server::build(SSL& ssl)
parms_.alloc_pub(pubSz));
short sigSz = 0;
- mySTL::auto_ptr<Auth> auth(ysDelete);
+ mySTL::auto_ptr<Auth> auth;
const CertManager& cert = ssl.getCrypto().get_certManager();
if (ssl.getSecurity().get_parms().sig_algo_ == rsa_sa_algo)
@@ -151,9 +151,11 @@ void DH_Server::build(SSL& ssl)
sigSz += DSS_ENCODED_EXTRA;
}
-
sigSz += auth->get_signatureLength();
-
+ if (!sigSz) {
+ ssl.SetError(privateKey_error);
+ return;
+ }
length_ = 8; // pLen + gLen + YsLen + SigLen
length_ += pSz + gSz + pubSz + sigSz;
@@ -612,7 +614,7 @@ void HandShakeHeader::Process(input_buffer& input, SSL& ssl)
{
ssl.verifyState(*this);
const HandShakeFactory& hsf = ssl.getFactory().getHandShake();
- mySTL::auto_ptr<HandShakeBase> hs(hsf.CreateObject(type_), ysDelete);
+ mySTL::auto_ptr<HandShakeBase> hs(hsf.CreateObject(type_));
if (!hs.get()) {
ssl.SetError(factory_error);
return;
@@ -1214,6 +1216,20 @@ output_buffer& operator<<(output_buffer& output, const ServerHello& hello)
// Server Hello processing handler
void ServerHello::Process(input_buffer&, SSL& ssl)
{
+ if (ssl.GetMultiProtocol()) { // SSLv23 support
+ if (ssl.isTLS() && server_version_.minor_ < 1)
+ // downgrade to SSLv3
+ ssl.useSecurity().use_connection().TurnOffTLS();
+ }
+ else if (ssl.isTLS() && server_version_.minor_ < 1) {
+ ssl.SetError(badVersion_error);
+ return;
+ }
+ else if (!ssl.isTLS() && (server_version_.major_ == 3 &&
+ server_version_.minor_ >= 1)) {
+ ssl.SetError(badVersion_error);
+ return;
+ }
ssl.set_pending(cipher_suite_[1]);
ssl.set_random(random_, server_end);
if (id_len_)
@@ -1384,11 +1400,23 @@ output_buffer& operator<<(output_buffer& output, const ClientHello& hello)
// Client Hello processing handler
void ClientHello::Process(input_buffer&, SSL& ssl)
{
- if (ssl.isTLS() && client_version_.minor_ == 0) {
+ if (ssl.GetMultiProtocol()) { // SSLv23 support
+ if (ssl.isTLS() && client_version_.minor_ < 1) {
+ // downgrade to SSLv3
ssl.useSecurity().use_connection().TurnOffTLS();
ProtocolVersion pv = ssl.getSecurity().get_connection().version_;
ssl.useSecurity().use_parms().SetSuites(pv); // reset w/ SSL suites
}
+ }
+ else if (ssl.isTLS() && client_version_.minor_ < 1) {
+ ssl.SetError(badVersion_error);
+ return;
+ }
+ else if (!ssl.isTLS() && (client_version_.major_ == 3 &&
+ client_version_.minor_ >= 1)) {
+ ssl.SetError(badVersion_error);
+ return;
+ }
ssl.set_random(random_, client_end);
while (id_len_) { // trying to resume
@@ -1541,7 +1569,7 @@ CertificateRequest::CertificateRequest()
CertificateRequest::~CertificateRequest()
{
- mySTL::for_each(certificate_authorities_.begin(),
+ STL::for_each(certificate_authorities_.begin(),
certificate_authorities_.end(),
del_ptr_zero()) ;
}
@@ -1634,9 +1662,9 @@ output_buffer& operator<<(output_buffer& output,
request.typeTotal_ - REQUEST_HEADER, tmp);
output.write(tmp, sizeof(tmp));
- mySTL::list<DistinguishedName>::const_iterator first =
+ STL::list<DistinguishedName>::const_iterator first =
request.certificate_authorities_.begin();
- mySTL::list<DistinguishedName>::const_iterator last =
+ STL::list<DistinguishedName>::const_iterator last =
request.certificate_authorities_.end();
while (first != last) {
uint16 sz;
@@ -1684,7 +1712,7 @@ void CertificateVerify::Build(SSL& ssl)
uint16 sz = 0;
byte len[VERIFY_HEADER];
- mySTL::auto_ptr<byte> sig(ysArrayDelete);
+ mySTL::auto_array<byte> sig;
// sign
const CertManager& cert = ssl.getCrypto().get_certManager();
diff --git a/extra/yassl/src/yassl_int.cpp b/extra/yassl/src/yassl_int.cpp
index 9b83f964348..5288acb2bcd 100644
--- a/extra/yassl/src/yassl_int.cpp
+++ b/extra/yassl/src/yassl_int.cpp
@@ -33,6 +33,10 @@
#include "handshake.hpp"
#include "timer.hpp"
+#ifdef _POSIX_THREADS
+ #include "pthread.h"
+#endif
+
#ifdef YASSL_PURE_C
@@ -74,7 +78,6 @@
namespace yaSSL {
-using mySTL::min;
@@ -155,6 +158,7 @@ void c32toa(uint32 u32, opaque* c)
States::States() : recordLayer_(recordReady), handshakeLayer_(preHandshake),
clientState_(serverNull), serverState_(clientNull),
+ connectState_(CONNECT_BEGIN), acceptState_(ACCEPT_BEGIN),
what_(no_error) {}
const RecordLayerState& States::getRecord() const
@@ -181,6 +185,18 @@ const ServerState& States::getServer() const
}
+const ConnectState& States::GetConnect() const
+{
+ return connectState_;
+}
+
+
+const AcceptState& States::GetAccept() const
+{
+ return acceptState_;
+}
+
+
const char* States::getString() const
{
return errorString_;
@@ -217,6 +233,18 @@ ServerState& States::useServer()
}
+ConnectState& States::UseConnect()
+{
+ return connectState_;
+}
+
+
+AcceptState& States::UseAccept()
+{
+ return acceptState_;
+}
+
+
char* States::useString()
{
return errorString_;
@@ -722,6 +750,12 @@ void SSL::SetError(YasslError ye)
}
+Buffers& SSL::useBuffers()
+{
+ return buffers_;
+}
+
+
// locals
namespace {
@@ -959,7 +993,7 @@ using namespace yassl_int_cpp_local1;
uint SSL::bufferedData()
{
- return mySTL::for_each(buffers_.getData().begin(),buffers_.getData().end(),
+ return STL::for_each(buffers_.getData().begin(),buffers_.getData().end(),
SumData()).total_;
}
@@ -1002,7 +1036,7 @@ void SSL::PeekData(Data& data)
data.set_length(0); // output, actual data filled
dataSz = min(dataSz, bufferedData());
- Buffers::inputList::iterator front = buffers_.getData().begin();
+ Buffers::inputList::iterator front = buffers_.useData().begin();
while (elements) {
uint frontSz = (*front)->get_remaining();
@@ -1027,7 +1061,7 @@ void SSL::flushBuffer()
{
if (GetError()) return;
- uint sz = mySTL::for_each(buffers_.getHandShake().begin(),
+ uint sz = STL::for_each(buffers_.getHandShake().begin(),
buffers_.getHandShake().end(),
SumBuffer()).total_;
output_buffer out(sz);
@@ -1213,8 +1247,10 @@ void SSL::matchSuite(const opaque* peer, uint length)
void SSL::set_session(SSL_SESSION* s)
{
- if (s && GetSessions().lookup(s->GetID(), &secure_.use_resume()))
+ if (s && GetSessions().lookup(s->GetID(), &secure_.use_resume())) {
secure_.set_resuming(true);
+ crypto_.use_certManager().setPeerX509(s->GetPeerX509());
+ }
}
@@ -1260,6 +1296,12 @@ YasslError SSL::GetError() const
}
+bool SSL::GetMultiProtocol() const
+{
+ return secure_.GetContext()->getMethod()->multipleProtocol();
+}
+
+
Crypto& SSL::useCrypto()
{
return crypto_;
@@ -1314,9 +1356,25 @@ void SSL::addBuffer(output_buffer* b)
}
+void SSL_SESSION::CopyX509(X509* x)
+{
+ assert(peerX509_ == 0);
+ if (x == 0) return;
+
+ X509_NAME* issuer = x->GetIssuer();
+ X509_NAME* subject = x->GetSubject();
+ ASN1_STRING* before = x->GetBefore();
+ ASN1_STRING* after = x->GetAfter();
+
+ peerX509_ = NEW_YS X509(issuer->GetName(), issuer->GetLength(),
+ subject->GetName(), subject->GetLength(), (const char*) before->data,
+ before->length, (const char*) after->data, after->length);
+}
+
+
// store connection parameters
SSL_SESSION::SSL_SESSION(const SSL& ssl, RandomPool& ran)
- : timeout_(DEFAULT_TIMEOUT), random_(ran)
+ : timeout_(DEFAULT_TIMEOUT), random_(ran), peerX509_(0)
{
const Connection& conn = ssl.getSecurity().get_connection();
@@ -1325,12 +1383,14 @@ SSL_SESSION::SSL_SESSION(const SSL& ssl, RandomPool& ran)
memcpy(suite_, ssl.getSecurity().get_parms().suite_, SUITE_LEN);
bornOn_ = lowResTimer();
+
+ CopyX509(ssl.getCrypto().get_certManager().get_peerX509());
}
// for resumption copy in ssl::parameters
SSL_SESSION::SSL_SESSION(RandomPool& ran)
- : bornOn_(0), timeout_(0), random_(ran)
+ : bornOn_(0), timeout_(0), random_(ran), peerX509_(0)
{
memset(sessionID_, 0, ID_LEN);
memset(master_secret_, 0, SECRET_LEN);
@@ -1347,6 +1407,12 @@ SSL_SESSION& SSL_SESSION::operator=(const SSL_SESSION& that)
bornOn_ = that.bornOn_;
timeout_ = that.timeout_;
+ if (peerX509_) {
+ ysDelete(peerX509_);
+ peerX509_ = 0;
+ }
+ CopyX509(that.peerX509_);
+
return *this;
}
@@ -1369,6 +1435,12 @@ const Cipher* SSL_SESSION::GetSuite() const
}
+X509* SSL_SESSION::GetPeerX509() const
+{
+ return peerX509_;
+}
+
+
uint SSL_SESSION::GetBornOn() const
{
return bornOn_;
@@ -1395,6 +1467,8 @@ SSL_SESSION::~SSL_SESSION()
{
volatile opaque* p = master_secret_;
clean(p, SECRET_LEN, random_);
+
+ ysDelete(peerX509_);
}
@@ -1418,6 +1492,15 @@ sslFactory& GetSSL_Factory()
}
+static Errors* errorsInstance = 0;
+
+Errors& GetErrors()
+{
+ if (!errorsInstance)
+ errorsInstance = NEW_YS Errors;
+ return *errorsInstance;
+}
+
typedef Mutex::Lock Lock;
@@ -1433,14 +1516,15 @@ void Sessions::add(const SSL& ssl)
Sessions::~Sessions()
{
- mySTL::for_each(list_.begin(), list_.end(), del_ptr_zero());
+ STL::for_each(list_.begin(), list_.end(), del_ptr_zero());
}
// locals
namespace yassl_int_cpp_local2 { // for explicit templates
-typedef mySTL::list<SSL_SESSION*>::iterator iterator;
+typedef STL::list<SSL_SESSION*>::iterator sess_iterator;
+typedef STL::list<ThreadError>::iterator thr_iterator;
struct sess_match {
const opaque* id_;
@@ -1455,6 +1539,28 @@ struct sess_match {
};
+THREAD_ID_T GetSelf()
+{
+#ifndef _POSIX_THREADS
+ return GetCurrentThreadId();
+#else
+ return pthread_self();
+#endif
+}
+
+struct thr_match {
+ THREAD_ID_T id_;
+ explicit thr_match() : id_(GetSelf()) {}
+
+ bool operator()(ThreadError thr)
+ {
+ if (thr.threadID_ == id_)
+ return true;
+ return false;
+ }
+};
+
+
} // local namespace
using namespace yassl_int_cpp_local2;
@@ -1463,8 +1569,8 @@ using namespace yassl_int_cpp_local2;
SSL_SESSION* Sessions::lookup(const opaque* id, SSL_SESSION* copy)
{
Lock guard(mutex_);
- iterator find = mySTL::find_if(list_.begin(), list_.end(), sess_match(id));
-
+ sess_iterator find = STL::find_if(list_.begin(), list_.end(),
+ sess_match(id));
if (find != list_.end()) {
uint current = lowResTimer();
if ( ((*find)->GetBornOn() + (*find)->GetTimeOut()) < current) {
@@ -1484,8 +1590,8 @@ SSL_SESSION* Sessions::lookup(const opaque* id, SSL_SESSION* copy)
void Sessions::remove(const opaque* id)
{
Lock guard(mutex_);
- iterator find = mySTL::find_if(list_.begin(), list_.end(), sess_match(id));
-
+ sess_iterator find = STL::find_if(list_.begin(), list_.end(),
+ sess_match(id));
if (find != list_.end()) {
del_ptr_zero()(*find);
list_.erase(find);
@@ -1493,9 +1599,51 @@ void Sessions::remove(const opaque* id)
}
-SSL_METHOD::SSL_METHOD(ConnectionEnd ce, ProtocolVersion pv)
+// remove a self thread error
+void Errors::Remove()
+{
+ Lock guard(mutex_);
+ thr_iterator find = STL::find_if(list_.begin(), list_.end(),
+ thr_match());
+ if (find != list_.end())
+ list_.erase(find);
+}
+
+
+// lookup self error code
+int Errors::Lookup(bool peek)
+{
+ Lock guard(mutex_);
+ thr_iterator find = STL::find_if(list_.begin(), list_.end(),
+ thr_match());
+ if (find != list_.end()) {
+ int ret = find->errorID_;
+ if (!peek)
+ list_.erase(find);
+ return ret;
+ }
+ else
+ return 0;
+}
+
+
+// add a new error code for self
+void Errors::Add(int error)
+{
+ ThreadError add;
+ add.errorID_ = error;
+ add.threadID_ = GetSelf();
+
+ Remove(); // may have old error
+
+ Lock guard(mutex_);
+ list_.push_back(add);
+}
+
+
+SSL_METHOD::SSL_METHOD(ConnectionEnd ce, ProtocolVersion pv, bool multiProto)
: version_(pv), side_(ce), verifyPeer_(false), verifyNone_(false),
- failNoCert_(false)
+ failNoCert_(false), multipleProtocol_(multiProto)
{}
@@ -1547,8 +1695,15 @@ bool SSL_METHOD::failNoCert() const
}
+bool SSL_METHOD::multipleProtocol() const
+{
+ return multipleProtocol_;
+}
+
+
SSL_CTX::SSL_CTX(SSL_METHOD* meth)
- : method_(meth), certificate_(0), privateKey_(0)
+ : method_(meth), certificate_(0), privateKey_(0), passwordCb_(0),
+ userData_(0)
{}
@@ -1558,7 +1713,7 @@ SSL_CTX::~SSL_CTX()
ysDelete(certificate_);
ysDelete(privateKey_);
- mySTL::for_each(caList_.begin(), caList_.end(), del_ptr_zero());
+ STL::for_each(caList_.begin(), caList_.end(), del_ptr_zero());
}
@@ -1611,6 +1766,30 @@ const Stats& SSL_CTX::GetStats() const
}
+pem_password_cb SSL_CTX::GetPasswordCb() const
+{
+ return passwordCb_;
+}
+
+
+void SSL_CTX::SetPasswordCb(pem_password_cb cb)
+{
+ passwordCb_ = cb;
+}
+
+
+void* SSL_CTX::GetUserData() const
+{
+ return userData_;
+}
+
+
+void SSL_CTX::SetUserData(void* data)
+{
+ userData_ = data;
+}
+
+
void SSL_CTX::setVerifyPeer()
{
method_->setVerifyPeer();
@@ -1914,12 +2093,33 @@ Hashes& sslHashes::use_certVerify()
}
+Buffers::Buffers() : rawInput_(0)
+{}
+
+
Buffers::~Buffers()
{
- mySTL::for_each(handShakeList_.begin(), handShakeList_.end(),
+ STL::for_each(handShakeList_.begin(), handShakeList_.end(),
del_ptr_zero()) ;
- mySTL::for_each(dataList_.begin(), dataList_.end(),
+ STL::for_each(dataList_.begin(), dataList_.end(),
del_ptr_zero()) ;
+ ysDelete(rawInput_);
+}
+
+
+void Buffers::SetRawInput(input_buffer* ib)
+{
+ assert(rawInput_ == 0);
+ rawInput_ = ib;
+}
+
+
+input_buffer* Buffers::TakeRawInput()
+{
+ input_buffer* ret = rawInput_;
+ rawInput_ = 0;
+
+ return ret;
}
@@ -2026,12 +2226,18 @@ X509_NAME::~X509_NAME()
}
-char* X509_NAME::GetName()
+const char* X509_NAME::GetName() const
{
return name_;
}
+size_t X509_NAME::GetLength() const
+{
+ return sz_;
+}
+
+
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),
@@ -2114,10 +2320,12 @@ extern "C" void yaSSL_CleanUp()
TaoCrypt::CleanUp();
yaSSL::ysDelete(yaSSL::sslFactoryInstance);
yaSSL::ysDelete(yaSSL::sessionsInstance);
+ yaSSL::ysDelete(yaSSL::errorsInstance);
// In case user calls more than once, prevent seg fault
yaSSL::sslFactoryInstance = 0;
yaSSL::sessionsInstance = 0;
+ yaSSL::errorsInstance = 0;
}
@@ -2126,6 +2334,7 @@ namespace mySTL {
template yaSSL::yassl_int_cpp_local1::SumData for_each<mySTL::list<yaSSL::input_buffer*>::iterator, yaSSL::yassl_int_cpp_local1::SumData>(mySTL::list<yaSSL::input_buffer*>::iterator, mySTL::list<yaSSL::input_buffer*>::iterator, yaSSL::yassl_int_cpp_local1::SumData);
template yaSSL::yassl_int_cpp_local1::SumBuffer for_each<mySTL::list<yaSSL::output_buffer*>::iterator, yaSSL::yassl_int_cpp_local1::SumBuffer>(mySTL::list<yaSSL::output_buffer*>::iterator, mySTL::list<yaSSL::output_buffer*>::iterator, yaSSL::yassl_int_cpp_local1::SumBuffer);
template mySTL::list<yaSSL::SSL_SESSION*>::iterator find_if<mySTL::list<yaSSL::SSL_SESSION*>::iterator, yaSSL::yassl_int_cpp_local2::sess_match>(mySTL::list<yaSSL::SSL_SESSION*>::iterator, mySTL::list<yaSSL::SSL_SESSION*>::iterator, yaSSL::yassl_int_cpp_local2::sess_match);
+template mySTL::list<yaSSL::ThreadError>::iterator find_if<mySTL::list<yaSSL::ThreadError>::iterator, yaSSL::yassl_int_cpp_local2::thr_match>(mySTL::list<yaSSL::ThreadError>::iterator, mySTL::list<yaSSL::ThreadError>::iterator, yaSSL::yassl_int_cpp_local2::thr_match);
}
#endif
diff --git a/extra/yassl/taocrypt/CMakeLists.txt b/extra/yassl/taocrypt/CMakeLists.txt
index 0af0a242e5d..540827954d0 100644
--- a/extra/yassl/taocrypt/CMakeLists.txt
+++ b/extra/yassl/taocrypt/CMakeLists.txt
@@ -1,4 +1,4 @@
-INCLUDE_DIRECTORIES(../mySTL include)
+INCLUDE_DIRECTORIES(mySTL include)
ADD_LIBRARY(taocrypt src/aes.cpp src/aestables.cpp src/algebra.cpp src/arc4.cpp src/asn.cpp src/coding.cpp
src/des.cpp src/dh.cpp src/dsa.cpp src/file.cpp src/hash.cpp src/integer.cpp src/md2.cpp
diff --git a/extra/yassl/taocrypt/COPYING b/extra/yassl/taocrypt/COPYING
new file mode 100644
index 00000000000..d60c31a97a5
--- /dev/null
+++ b/extra/yassl/taocrypt/COPYING
@@ -0,0 +1,340 @@
+ GNU GENERAL PUBLIC LICENSE
+ Version 2, June 1991
+
+ Copyright (C) 1989, 1991 Free Software Foundation, Inc.
+ 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+ Preamble
+
+ The licenses for most software are designed to take away your
+freedom to share and change it. By contrast, the GNU General Public
+License is intended to guarantee your freedom to share and change free
+software--to make sure the software is free for all its users. This
+General Public License applies to most of the Free Software
+Foundation's software and to any other program whose authors commit to
+using it. (Some other Free Software Foundation software is covered by
+the GNU Library General Public License instead.) You can apply it to
+your programs, too.
+
+ When we speak of free software, we are referring to freedom, not
+price. Our General Public Licenses are designed to make sure that you
+have the freedom to distribute copies of free software (and charge for
+this service if you wish), that you receive source code or can get it
+if you want it, that you can change the software or use pieces of it
+in new free programs; and that you know you can do these things.
+
+ To protect your rights, we need to make restrictions that forbid
+anyone to deny you these rights or to ask you to surrender the rights.
+These restrictions translate to certain responsibilities for you if you
+distribute copies of the software, or if you modify it.
+
+ For example, if you distribute copies of such a program, whether
+gratis or for a fee, you must give the recipients all the rights that
+you have. You must make sure that they, too, receive or can get the
+source code. And you must show them these terms so they know their
+rights.
+
+ We protect your rights with two steps: (1) copyright the software, and
+(2) offer you this license which gives you legal permission to copy,
+distribute and/or modify the software.
+
+ Also, for each author's protection and ours, we want to make certain
+that everyone understands that there is no warranty for this free
+software. If the software is modified by someone else and passed on, we
+want its recipients to know that what they have is not the original, so
+that any problems introduced by others will not reflect on the original
+authors' reputations.
+
+ Finally, any free program is threatened constantly by software
+patents. We wish to avoid the danger that redistributors of a free
+program will individually obtain patent licenses, in effect making the
+program proprietary. To prevent this, we have made it clear that any
+patent must be licensed for everyone's free use or not licensed at all.
+
+ The precise terms and conditions for copying, distribution and
+modification follow.
+
+ GNU GENERAL PUBLIC LICENSE
+ TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
+
+ 0. This License applies to any program or other work which contains
+a notice placed by the copyright holder saying it may be distributed
+under the terms of this General Public License. The "Program", below,
+refers to any such program or work, and a "work based on the Program"
+means either the Program or any derivative work under copyright law:
+that is to say, a work containing the Program or a portion of it,
+either verbatim or with modifications and/or translated into another
+language. (Hereinafter, translation is included without limitation in
+the term "modification".) Each licensee is addressed as "you".
+
+Activities other than copying, distribution and modification are not
+covered by this License; they are outside its scope. The act of
+running the Program is not restricted, and the output from the Program
+is covered only if its contents constitute a work based on the
+Program (independent of having been made by running the Program).
+Whether that is true depends on what the Program does.
+
+ 1. You may copy and distribute verbatim copies of the Program's
+source code as you receive it, in any medium, provided that you
+conspicuously and appropriately publish on each copy an appropriate
+copyright notice and disclaimer of warranty; keep intact all the
+notices that refer to this License and to the absence of any warranty;
+and give any other recipients of the Program a copy of this License
+along with the Program.
+
+You may charge a fee for the physical act of transferring a copy, and
+you may at your option offer warranty protection in exchange for a fee.
+
+ 2. You may modify your copy or copies of the Program or any portion
+of it, thus forming a work based on the Program, and copy and
+distribute such modifications or work under the terms of Section 1
+above, provided that you also meet all of these conditions:
+
+ a) You must cause the modified files to carry prominent notices
+ stating that you changed the files and the date of any change.
+
+ b) You must cause any work that you distribute or publish, that in
+ whole or in part contains or is derived from the Program or any
+ part thereof, to be licensed as a whole at no charge to all third
+ parties under the terms of this License.
+
+ c) If the modified program normally reads commands interactively
+ when run, you must cause it, when started running for such
+ interactive use in the most ordinary way, to print or display an
+ announcement including an appropriate copyright notice and a
+ notice that there is no warranty (or else, saying that you provide
+ a warranty) and that users may redistribute the program under
+ these conditions, and telling the user how to view a copy of this
+ License. (Exception: if the Program itself is interactive but
+ does not normally print such an announcement, your work based on
+ the Program is not required to print an announcement.)
+
+These requirements apply to the modified work as a whole. If
+identifiable sections of that work are not derived from the Program,
+and can be reasonably considered independent and separate works in
+themselves, then this License, and its terms, do not apply to those
+sections when you distribute them as separate works. But when you
+distribute the same sections as part of a whole which is a work based
+on the Program, the distribution of the whole must be on the terms of
+this License, whose permissions for other licensees extend to the
+entire whole, and thus to each and every part regardless of who wrote it.
+
+Thus, it is not the intent of this section to claim rights or contest
+your rights to work written entirely by you; rather, the intent is to
+exercise the right to control the distribution of derivative or
+collective works based on the Program.
+
+In addition, mere aggregation of another work not based on the Program
+with the Program (or with a work based on the Program) on a volume of
+a storage or distribution medium does not bring the other work under
+the scope of this License.
+
+ 3. You may copy and distribute the Program (or a work based on it,
+under Section 2) in object code or executable form under the terms of
+Sections 1 and 2 above provided that you also do one of the following:
+
+ a) Accompany it with the complete corresponding machine-readable
+ source code, which must be distributed under the terms of Sections
+ 1 and 2 above on a medium customarily used for software interchange; or,
+
+ b) Accompany it with a written offer, valid for at least three
+ years, to give any third party, for a charge no more than your
+ cost of physically performing source distribution, a complete
+ machine-readable copy of the corresponding source code, to be
+ distributed under the terms of Sections 1 and 2 above on a medium
+ customarily used for software interchange; or,
+
+ c) Accompany it with the information you received as to the offer
+ to distribute corresponding source code. (This alternative is
+ allowed only for noncommercial distribution and only if you
+ received the program in object code or executable form with such
+ an offer, in accord with Subsection b above.)
+
+The source code for a work means the preferred form of the work for
+making modifications to it. For an executable work, complete source
+code means all the source code for all modules it contains, plus any
+associated interface definition files, plus the scripts used to
+control compilation and installation of the executable. However, as a
+special exception, the source code distributed need not include
+anything that is normally distributed (in either source or binary
+form) with the major components (compiler, kernel, and so on) of the
+operating system on which the executable runs, unless that component
+itself accompanies the executable.
+
+If distribution of executable or object code is made by offering
+access to copy from a designated place, then offering equivalent
+access to copy the source code from the same place counts as
+distribution of the source code, even though third parties are not
+compelled to copy the source along with the object code.
+
+ 4. You may not copy, modify, sublicense, or distribute the Program
+except as expressly provided under this License. Any attempt
+otherwise to copy, modify, sublicense or distribute the Program is
+void, and will automatically terminate your rights under this License.
+However, parties who have received copies, or rights, from you under
+this License will not have their licenses terminated so long as such
+parties remain in full compliance.
+
+ 5. You are not required to accept this License, since you have not
+signed it. However, nothing else grants you permission to modify or
+distribute the Program or its derivative works. These actions are
+prohibited by law if you do not accept this License. Therefore, by
+modifying or distributing the Program (or any work based on the
+Program), you indicate your acceptance of this License to do so, and
+all its terms and conditions for copying, distributing or modifying
+the Program or works based on it.
+
+ 6. Each time you redistribute the Program (or any work based on the
+Program), the recipient automatically receives a license from the
+original licensor to copy, distribute or modify the Program subject to
+these terms and conditions. You may not impose any further
+restrictions on the recipients' exercise of the rights granted herein.
+You are not responsible for enforcing compliance by third parties to
+this License.
+
+ 7. If, as a consequence of a court judgment or allegation of patent
+infringement or for any other reason (not limited to patent issues),
+conditions are imposed on you (whether by court order, agreement or
+otherwise) that contradict the conditions of this License, they do not
+excuse you from the conditions of this License. If you cannot
+distribute so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you
+may not distribute the Program at all. For example, if a patent
+license would not permit royalty-free redistribution of the Program by
+all those who receive copies directly or indirectly through you, then
+the only way you could satisfy both it and this License would be to
+refrain entirely from distribution of the Program.
+
+If any portion of this section is held invalid or unenforceable under
+any particular circumstance, the balance of the section is intended to
+apply and the section as a whole is intended to apply in other
+circumstances.
+
+It is not the purpose of this section to induce you to infringe any
+patents or other property right claims or to contest validity of any
+such claims; this section has the sole purpose of protecting the
+integrity of the free software distribution system, which is
+implemented by public license practices. Many people have made
+generous contributions to the wide range of software distributed
+through that system in reliance on consistent application of that
+system; it is up to the author/donor to decide if he or she is willing
+to distribute software through any other system and a licensee cannot
+impose that choice.
+
+This section is intended to make thoroughly clear what is believed to
+be a consequence of the rest of this License.
+
+ 8. If the distribution and/or use of the Program is restricted in
+certain countries either by patents or by copyrighted interfaces, the
+original copyright holder who places the Program under this License
+may add an explicit geographical distribution limitation excluding
+those countries, so that distribution is permitted only in or among
+countries not thus excluded. In such case, this License incorporates
+the limitation as if written in the body of this License.
+
+ 9. The Free Software Foundation may publish revised and/or new versions
+of the General Public License from time to time. Such new versions will
+be similar in spirit to the present version, but may differ in detail to
+address new problems or concerns.
+
+Each version is given a distinguishing version number. If the Program
+specifies a version number of this License which applies to it and "any
+later version", you have the option of following the terms and conditions
+either of that version or of any later version published by the Free
+Software Foundation. If the Program does not specify a version number of
+this License, you may choose any version ever published by the Free Software
+Foundation.
+
+ 10. If you wish to incorporate parts of the Program into other free
+programs whose distribution conditions are different, write to the author
+to ask for permission. For software which is copyrighted by the Free
+Software Foundation, write to the Free Software Foundation; we sometimes
+make exceptions for this. Our decision will be guided by the two goals
+of preserving the free status of all derivatives of our free software and
+of promoting the sharing and reuse of software generally.
+
+ NO WARRANTY
+
+ 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
+FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
+OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
+PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
+OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
+TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
+PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
+REPAIR OR CORRECTION.
+
+ 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
+WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
+REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
+INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
+OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
+TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
+YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
+PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGES.
+
+ END OF TERMS AND CONDITIONS
+
+ How to Apply These Terms to Your New Programs
+
+ If you develop a new program, and you want it to be of the greatest
+possible use to the public, the best way to achieve this is to make it
+free software which everyone can redistribute and change under these terms.
+
+ To do so, attach the following notices to the program. It is safest
+to attach them to the start of each source file to most effectively
+convey the exclusion of warranty; and each file should have at least
+the "copyright" line and a pointer to where the full notice is found.
+
+ <one line to give the program's name and a brief idea of what it does.>
+ Copyright (C) <year> <name of author>
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+
+Also add information on how to contact you by electronic and paper mail.
+
+If the program is interactive, make it output a short notice like this
+when it starts in an interactive mode:
+
+ Gnomovision version 69, Copyright (C) year name of author
+ Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
+ This is free software, and you are welcome to redistribute it
+ under certain conditions; type `show c' for details.
+
+The hypothetical commands `show w' and `show c' should show the appropriate
+parts of the General Public License. Of course, the commands you use may
+be called something other than `show w' and `show c'; they could even be
+mouse-clicks or menu items--whatever suits your program.
+
+You should also get your employer (if you work as a programmer) or your
+school, if any, to sign a "copyright disclaimer" for the program, if
+necessary. Here is a sample; alter the names:
+
+ Yoyodyne, Inc., hereby disclaims all copyright interest in the program
+ `Gnomovision' (which makes passes at compilers) written by James Hacker.
+
+ <signature of Ty Coon>, 1 April 1989
+ Ty Coon, President of Vice
+
+This General Public License does not permit incorporating your program into
+proprietary programs. If your program is a subroutine library, you may
+consider it more useful to permit linking proprietary applications with the
+library. If this is what you want to do, use the GNU Library General
+Public License instead of this License.
diff --git a/extra/yassl/taocrypt/INSTALL b/extra/yassl/taocrypt/INSTALL
new file mode 100644
index 00000000000..54caf7c190f
--- /dev/null
+++ b/extra/yassl/taocrypt/INSTALL
@@ -0,0 +1,229 @@
+Copyright (C) 1994, 1995, 1996, 1999, 2000, 2001, 2002 Free Software
+Foundation, Inc.
+
+ This file is free documentation; the Free Software Foundation gives
+unlimited permission to copy, distribute and modify it.
+
+Basic Installation
+==================
+
+ These are generic installation instructions.
+
+ The `configure' shell script attempts to guess correct values for
+various system-dependent variables used during compilation. It uses
+those values to create a `Makefile' in each directory of the package.
+It may also create one or more `.h' files containing system-dependent
+definitions. Finally, it creates a shell script `config.status' that
+you can run in the future to recreate the current configuration, and a
+file `config.log' containing compiler output (useful mainly for
+debugging `configure').
+
+ It can also use an optional file (typically called `config.cache'
+and enabled with `--cache-file=config.cache' or simply `-C') that saves
+the results of its tests to speed up reconfiguring. (Caching is
+disabled by default to prevent problems with accidental use of stale
+cache files.)
+
+ If you need to do unusual things to compile the package, please try
+to figure out how `configure' could check whether to do them, and mail
+diffs or instructions to the address given in the `README' so they can
+be considered for the next release. If you are using the cache, and at
+some point `config.cache' contains results you don't want to keep, you
+may remove or edit it.
+
+ The file `configure.ac' (or `configure.in') is used to create
+`configure' by a program called `autoconf'. You only need
+`configure.ac' if you want to change it or regenerate `configure' using
+a newer version of `autoconf'.
+
+The simplest way to compile this package is:
+
+ 1. `cd' to the directory containing the package's source code and type
+ `./configure' to configure the package for your system. If you're
+ using `csh' on an old version of System V, you might need to type
+ `sh ./configure' instead to prevent `csh' from trying to execute
+ `configure' itself.
+
+ Running `configure' takes awhile. While running, it prints some
+ messages telling which features it is checking for.
+
+ 2. Type `make' to compile the package.
+
+ 3. Optionally, type `make check' to run any self-tests that come with
+ the package.
+
+ 4. Type `make install' to install the programs and any data files and
+ documentation.
+
+ 5. You can remove the program binaries and object files from the
+ source code directory by typing `make clean'. To also remove the
+ files that `configure' created (so you can compile the package for
+ a different kind of computer), type `make distclean'. There is
+ also a `make maintainer-clean' target, but that is intended mainly
+ for the package's developers. If you use it, you may have to get
+ all sorts of other programs in order to regenerate files that came
+ with the distribution.
+
+Compilers and Options
+=====================
+
+ Some systems require unusual options for compilation or linking that
+the `configure' script does not know about. Run `./configure --help'
+for details on some of the pertinent environment variables.
+
+ You can give `configure' initial values for configuration parameters
+by setting variables in the command line or in the environment. Here
+is an example:
+
+ ./configure CC=c89 CFLAGS=-O2 LIBS=-lposix
+
+ *Note Defining Variables::, for more details.
+
+Compiling For Multiple Architectures
+====================================
+
+ You can compile the package for more than one kind of computer at the
+same time, by placing the object files for each architecture in their
+own directory. To do this, you must use a version of `make' that
+supports the `VPATH' variable, such as GNU `make'. `cd' to the
+directory where you want the object files and executables to go and run
+the `configure' script. `configure' automatically checks for the
+source code in the directory that `configure' is in and in `..'.
+
+ If you have to use a `make' that does not support the `VPATH'
+variable, you have to compile the package for one architecture at a
+time in the source code directory. After you have installed the
+package for one architecture, use `make distclean' before reconfiguring
+for another architecture.
+
+Installation Names
+==================
+
+ By default, `make install' will install the package's files in
+`/usr/local/bin', `/usr/local/man', etc. You can specify an
+installation prefix other than `/usr/local' by giving `configure' the
+option `--prefix=PATH'.
+
+ You can specify separate installation prefixes for
+architecture-specific files and architecture-independent files. If you
+give `configure' the option `--exec-prefix=PATH', the package will use
+PATH as the prefix for installing programs and libraries.
+Documentation and other data files will still use the regular prefix.
+
+ In addition, if you use an unusual directory layout you can give
+options like `--bindir=PATH' to specify different values for particular
+kinds of files. Run `configure --help' for a list of the directories
+you can set and what kinds of files go in them.
+
+ If the package supports it, you can cause programs to be installed
+with an extra prefix or suffix on their names by giving `configure' the
+option `--program-prefix=PREFIX' or `--program-suffix=SUFFIX'.
+
+Optional Features
+=================
+
+ Some packages pay attention to `--enable-FEATURE' options to
+`configure', where FEATURE indicates an optional part of the package.
+They may also pay attention to `--with-PACKAGE' options, where PACKAGE
+is something like `gnu-as' or `x' (for the X Window System). The
+`README' should mention any `--enable-' and `--with-' options that the
+package recognizes.
+
+ For packages that use the X Window System, `configure' can usually
+find the X include and library files automatically, but if it doesn't,
+you can use the `configure' options `--x-includes=DIR' and
+`--x-libraries=DIR' to specify their locations.
+
+Specifying the System Type
+==========================
+
+ There may be some features `configure' cannot figure out
+automatically, but needs to determine by the type of machine the package
+will run on. Usually, assuming the package is built to be run on the
+_same_ architectures, `configure' can figure that out, but if it prints
+a message saying it cannot guess the machine type, give it the
+`--build=TYPE' option. TYPE can either be a short name for the system
+type, such as `sun4', or a canonical name which has the form:
+
+ CPU-COMPANY-SYSTEM
+
+where SYSTEM can have one of these forms:
+
+ OS KERNEL-OS
+
+ See the file `config.sub' for the possible values of each field. If
+`config.sub' isn't included in this package, then this package doesn't
+need to know the machine type.
+
+ If you are _building_ compiler tools for cross-compiling, you should
+use the `--target=TYPE' option to select the type of system they will
+produce code for.
+
+ If you want to _use_ a cross compiler, that generates code for a
+platform different from the build platform, you should specify the
+"host" platform (i.e., that on which the generated programs will
+eventually be run) with `--host=TYPE'.
+
+Sharing Defaults
+================
+
+ If you want to set default values for `configure' scripts to share,
+you can create a site shell script called `config.site' that gives
+default values for variables like `CC', `cache_file', and `prefix'.
+`configure' looks for `PREFIX/share/config.site' if it exists, then
+`PREFIX/etc/config.site' if it exists. Or, you can set the
+`CONFIG_SITE' environment variable to the location of the site script.
+A warning: not all `configure' scripts look for a site script.
+
+Defining Variables
+==================
+
+ Variables not defined in a site shell script can be set in the
+environment passed to `configure'. However, some packages may run
+configure again during the build, and the customized values of these
+variables may be lost. In order to avoid this problem, you should set
+them in the `configure' command line, using `VAR=value'. For example:
+
+ ./configure CC=/usr/local2/bin/gcc
+
+will cause the specified gcc to be used as the C compiler (unless it is
+overridden in the site shell script).
+
+`configure' Invocation
+======================
+
+ `configure' recognizes the following options to control how it
+operates.
+
+`--help'
+`-h'
+ Print a summary of the options to `configure', and exit.
+
+`--version'
+`-V'
+ Print the version of Autoconf used to generate the `configure'
+ script, and exit.
+
+`--cache-file=FILE'
+ Enable the cache: use and save the results of the tests in FILE,
+ traditionally `config.cache'. FILE defaults to `/dev/null' to
+ disable caching.
+
+`--config-cache'
+`-C'
+ Alias for `--cache-file=config.cache'.
+
+`--quiet'
+`--silent'
+`-q'
+ Do not print messages saying which checks are being made. To
+ suppress all normal output, redirect it to `/dev/null' (any error
+ messages will still be shown).
+
+`--srcdir=DIR'
+ Look for the package's source code in directory DIR. Usually
+ `configure' can determine that directory automatically.
+
+`configure' also accepts some other, not widely useful, options. Run
+`configure --help' for more details.
+
diff --git a/extra/yassl/taocrypt/Makefile.am b/extra/yassl/taocrypt/Makefile.am
index c242696b82f..d22cdcebf67 100644
--- a/extra/yassl/taocrypt/Makefile.am
+++ b/extra/yassl/taocrypt/Makefile.am
@@ -1,2 +1,2 @@
SUBDIRS = src test benchmark
-EXTRA_DIST = taocrypt.dsw taocrypt.dsp taocrypt.vcproj CMakeLists.txt
+EXTRA_DIST = taocrypt.dsw taocrypt.dsp taocrypt.vcproj CMakeLists.txt $(wildcard mySTL/*.hpp)
diff --git a/extra/yassl/taocrypt/README b/extra/yassl/taocrypt/README
new file mode 100644
index 00000000000..34e1744492e
--- /dev/null
+++ b/extra/yassl/taocrypt/README
@@ -0,0 +1,37 @@
+TaoCrypt release 0.9.0 09/18/2006
+
+This is the first release of TaoCrypt, it was previously only included with
+yaSSL. TaoCrypt is highly portable and fast, its features include:
+
+One way hash functions: SHA-1, MD2, MD4, MD5, RIPEMD-160
+Message authentication codes: HMAC
+Block Ciphers: DES, Triple-DES, AES, Blowfish, Twofish
+Stream Ciphers: ARC4
+Public Key Crypto: RSA, DSA, Diffie-Hellman
+Password based key derivation: PBKDF2 from PKCS #5
+Pseudo Random Number Generators
+Lare Integer Support
+Base 16/64 encoding/decoding
+DER encoding/decoding
+X.509 processing
+SSE2 and ia32 asm for the right processors and compilers
+
+
+To build on Unix
+
+ ./configure
+ make
+
+ To test the build, from the ./test directory run ./test
+
+
+On Windows
+
+ Open the taocrypt project workspace
+ Choose (Re)Build All
+
+ To test the build, run the test executable
+
+
+Please send any questions or comments to todd@yassl.com.
+
diff --git a/extra/yassl/taocrypt/benchmark/Makefile.am b/extra/yassl/taocrypt/benchmark/Makefile.am
index 81200ff7e6a..a5b1713427c 100644
--- a/extra/yassl/taocrypt/benchmark/Makefile.am
+++ b/extra/yassl/taocrypt/benchmark/Makefile.am
@@ -1,8 +1,6 @@
-INCLUDES = -I../include -I../../mySTL
+INCLUDES = -I../include -I../mySTL
bin_PROGRAMS = benchmark
benchmark_SOURCES = benchmark.cpp
-benchmark_LDFLAGS = -L../src
-benchmark_LDADD = -ltaocrypt
+benchmark_LDADD = $(top_builddir)/extra/yassl/taocrypt/src/libtaocrypt.la
benchmark_CXXFLAGS = -DYASSL_PURE_C
-benchmark_DEPENDENCIES = ../src/libtaocrypt.la
EXTRA_DIST = benchmark.dsp rsa1024.der dh1024.der dsa1024.der make.bat
diff --git a/extra/yassl/taocrypt/include/asn.hpp b/extra/yassl/taocrypt/include/asn.hpp
index 8bea2ae780b..dbee54be6f1 100644
--- a/extra/yassl/taocrypt/include/asn.hpp
+++ b/extra/yassl/taocrypt/include/asn.hpp
@@ -33,10 +33,12 @@
#include "misc.hpp"
#include "block.hpp"
-#include "list.hpp"
#include "error.hpp"
+#include STL_LIST_FILE
+namespace STL = STL_NAMESPACE;
+
namespace TaoCrypt {
@@ -232,7 +234,7 @@ private:
};
-typedef mySTL::list<Signer*> SignerList;
+typedef STL::list<Signer*> SignerList;
enum SigType { SHAwDSA = 517, MD2wRSA = 646, MD5wRSA = 648, SHAwRSA =649};
diff --git a/extra/yassl/taocrypt/include/block.hpp b/extra/yassl/taocrypt/include/block.hpp
index 88cb06f62f1..a931158a83d 100644
--- a/extra/yassl/taocrypt/include/block.hpp
+++ b/extra/yassl/taocrypt/include/block.hpp
@@ -31,12 +31,14 @@
#ifndef TAO_CRYPT_BLOCK_HPP
#define TAO_CRYPT_BLOCK_HPP
-#include "algorithm.hpp" // mySTL::swap
#include "misc.hpp"
#include <string.h> // memcpy
#include <stddef.h> // ptrdiff_t
+#include STL_ALGORITHM_FILE
+namespace STL = STL_NAMESPACE;
+
namespace TaoCrypt {
@@ -80,7 +82,7 @@ typename A::pointer StdReallocate(A& a, T* p, typename A::size_type oldSize,
typename A::pointer newPointer = b.allocate(newSize, 0);
memcpy(newPointer, p, sizeof(T) * min(oldSize, newSize));
a.deallocate(p, oldSize);
- mySTL::swap(a, b);
+ STL::swap(a, b);
return newPointer;
}
else {
@@ -183,9 +185,9 @@ public:
}
void Swap(Block& other) {
- mySTL::swap(sz_, other.sz_);
- mySTL::swap(buffer_, other.buffer_);
- mySTL::swap(allocator_, other.allocator_);
+ STL::swap(sz_, other.sz_);
+ STL::swap(buffer_, other.buffer_);
+ STL::swap(allocator_, other.allocator_);
}
~Block() { allocator_.deallocate(buffer_, sz_); }
diff --git a/extra/yassl/taocrypt/include/blowfish.hpp b/extra/yassl/taocrypt/include/blowfish.hpp
index fbc4f223702..40953624232 100644
--- a/extra/yassl/taocrypt/include/blowfish.hpp
+++ b/extra/yassl/taocrypt/include/blowfish.hpp
@@ -32,7 +32,11 @@
#include "misc.hpp"
#include "modes.hpp"
-#include "algorithm.hpp"
+#include STL_ALGORITHM_FILE
+
+
+namespace STL = STL_NAMESPACE;
+
namespace TaoCrypt {
diff --git a/extra/yassl/taocrypt/include/error.hpp b/extra/yassl/taocrypt/include/error.hpp
index b0ff9b280ba..1a93056db45 100644
--- a/extra/yassl/taocrypt/include/error.hpp
+++ b/extra/yassl/taocrypt/include/error.hpp
@@ -37,7 +37,7 @@ namespace TaoCrypt {
enum ErrorNumber {
-NO_ERROR = 0, // "not in error state"
+NO_ERROR_E = 0, // "not in error state"
// RandomNumberGenerator
WINCRYPT_E = 1001, // "bad wincrypt acquire"
@@ -78,7 +78,7 @@ SIG_OTHER_E = 1039 // "bad other signature confirmation"
struct Error {
ErrorNumber what_; // description number, 0 for no error
- explicit Error(ErrorNumber w = NO_ERROR) : what_(w) {}
+ explicit Error(ErrorNumber w = NO_ERROR_E) : what_(w) {}
ErrorNumber What() const { return what_; }
void SetError(ErrorNumber w) { what_ = w; }
diff --git a/extra/yassl/taocrypt/include/file.hpp b/extra/yassl/taocrypt/include/file.hpp
index 87fc6139f8f..c12b5c73bac 100644
--- a/extra/yassl/taocrypt/include/file.hpp
+++ b/extra/yassl/taocrypt/include/file.hpp
@@ -83,7 +83,7 @@ private:
void Swap(Source& other)
{
buffer_.Swap(other.buffer_);
- mySTL::swap(current_, other.current_);
+ STL::swap(current_, other.current_);
}
};
diff --git a/extra/yassl/taocrypt/include/integer.hpp b/extra/yassl/taocrypt/include/integer.hpp
index 7e4f6450316..70b4dc79e73 100644
--- a/extra/yassl/taocrypt/include/integer.hpp
+++ b/extra/yassl/taocrypt/include/integer.hpp
@@ -44,8 +44,8 @@
#include "block.hpp"
#include "random.hpp"
#include "file.hpp"
-#include "algorithm.hpp" // mySTL::swap
#include <string.h>
+#include STL_ALGORITHM_FILE
#ifdef TAOCRYPT_X86ASM_AVAILABLE
diff --git a/extra/yassl/taocrypt/include/misc.hpp b/extra/yassl/taocrypt/include/misc.hpp
index 48604620706..3d2d4c62466 100644
--- a/extra/yassl/taocrypt/include/misc.hpp
+++ b/extra/yassl/taocrypt/include/misc.hpp
@@ -198,6 +198,23 @@ void CleanUp();
#endif
+#ifdef USE_SYS_STL
+ // use system STL
+ #define STL_VECTOR_FILE <vector>
+ #define STL_LIST_FILE <list>
+ #define STL_ALGORITHM_FILE <algorithm>
+ #define STL_MEMORY_FILE <memory>
+ #define STL_NAMESPACE std
+#else
+ // use mySTL
+ #define STL_VECTOR_FILE "vector.hpp"
+ #define STL_LIST_FILE "list.hpp"
+ #define STL_ALGORITHM_FILE "algorithm.hpp"
+ #define STL_MEMORY_FILE "memory.hpp"
+ #define STL_NAMESPACE mySTL
+#endif
+
+
// ***************** DLL related ********************
#ifdef TAOCRYPT_WIN32_AVAILABLE
diff --git a/extra/yassl/taocrypt/include/pwdbased.hpp b/extra/yassl/taocrypt/include/pwdbased.hpp
index c3e916e3d83..78df7ede02e 100644
--- a/extra/yassl/taocrypt/include/pwdbased.hpp
+++ b/extra/yassl/taocrypt/include/pwdbased.hpp
@@ -74,7 +74,7 @@ word32 PBKDF2_HMAC<T>::DeriveKey(byte* derived, word32 dLen, const byte* pwd,
}
hmac.Final(buffer.get_buffer());
- word32 segmentLen = mySTL::min(dLen, buffer.size());
+ word32 segmentLen = min(dLen, buffer.size());
memcpy(derived, buffer.get_buffer(), segmentLen);
for (j = 1; j < iterations; j++) {
diff --git a/extra/yassl/taocrypt/include/twofish.hpp b/extra/yassl/taocrypt/include/twofish.hpp
index 0529c37d6c5..ba144d2defb 100644
--- a/extra/yassl/taocrypt/include/twofish.hpp
+++ b/extra/yassl/taocrypt/include/twofish.hpp
@@ -32,7 +32,11 @@
#include "misc.hpp"
#include "modes.hpp"
-#include "algorithm.hpp"
+#include STL_ALGORITHM_FILE
+
+
+namespace STL = STL_NAMESPACE;
+
namespace TaoCrypt {
diff --git a/extra/yassl/mySTL/algorithm.hpp b/extra/yassl/taocrypt/mySTL/algorithm.hpp
index efc7aa21a07..9a51d1f2281 100644
--- a/extra/yassl/mySTL/algorithm.hpp
+++ b/extra/yassl/taocrypt/mySTL/algorithm.hpp
@@ -8,7 +8,7 @@
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
- *
+ *
* There are special exceptions to the terms and conditions of the GPL as it
* is applied to yaSSL. View the full text of the exception in the file
* FLOSS-EXCEPTIONS in the directory of this software distribution.
diff --git a/extra/yassl/mySTL/helpers.hpp b/extra/yassl/taocrypt/mySTL/helpers.hpp
index c4449519db3..43381c0f6ea 100644
--- a/extra/yassl/mySTL/helpers.hpp
+++ b/extra/yassl/taocrypt/mySTL/helpers.hpp
@@ -113,6 +113,47 @@ PlaceIter uninit_fill_n(PlaceIter place, Size n, const T& value)
}
+template <typename T>
+T* GetArrayMemory(size_t items)
+{
+ unsigned char* ret;
+
+ #ifdef YASSL_LIB
+ ret = NEW_YS unsigned char[sizeof(T) * items];
+ #else
+ ret = NEW_TC unsigned char[sizeof(T) * items];
+ #endif
+
+ return reinterpret_cast<T*>(ret);
+}
+
+
+template <typename T>
+void FreeArrayMemory(T* ptr)
+{
+ unsigned char* p = reinterpret_cast<unsigned char*>(ptr);
+
+ #ifdef YASSL_LIB
+ yaSSL::ysArrayDelete(p);
+ #else
+ TaoCrypt::tcArrayDelete(p);
+ #endif
+}
+
+
+
+inline void* GetMemory(size_t bytes)
+{
+ return GetArrayMemory<unsigned char>(bytes);
+}
+
+
+inline void FreeMemory(void* ptr)
+{
+ FreeArrayMemory(ptr);
+}
+
+
} // namespace mySTL
diff --git a/extra/yassl/mySTL/list.hpp b/extra/yassl/taocrypt/mySTL/list.hpp
index 11a1a914868..831c5bbbbbd 100644
--- a/extra/yassl/mySTL/list.hpp
+++ b/extra/yassl/taocrypt/mySTL/list.hpp
@@ -33,7 +33,6 @@
#include "helpers.hpp"
-#include <stdlib.h>
namespace mySTL {
@@ -75,8 +74,7 @@ public:
class iterator {
node* current_;
public:
- iterator() : current_(0) {}
- explicit iterator(node* p) : current_(p) {}
+ explicit iterator(node* p = 0) : current_(p) {}
T& operator*() const
{
@@ -127,11 +125,67 @@ public:
friend class list<T>;
};
+
+ class reverse_iterator {
+ node* current_;
+ public:
+ explicit reverse_iterator(node* p = 0) : current_(p) {}
+
+ T& operator*() const
+ {
+ return current_->value_;
+ }
+
+ T* operator->() const
+ {
+ return &(operator*());
+ }
+
+ reverse_iterator& operator++()
+ {
+ current_ = current_->prev_;
+ return *this;
+ }
+
+ reverse_iterator& operator--()
+ {
+ current_ = current_->next_;
+ return *this;
+ }
+
+ reverse_iterator operator++(int)
+ {
+ reverse_iterator tmp = *this;
+ current_ = current_->prev_;
+ return tmp;
+ }
+
+ reverse_iterator operator--(int)
+ {
+ reverse_iterator tmp = *this;
+ current_ = current_->next_;
+ return tmp;
+ }
+
+ bool operator==(const reverse_iterator& other) const
+ {
+ return current_ == other.current_;
+ }
+
+ bool operator!=(const reverse_iterator& other) const
+ {
+ return current_ != other.current_;
+ }
+
+ friend class list<T>;
+ };
+
bool erase(iterator);
- iterator begin() const { return iterator(head_); }
- iterator rbegin() const { return iterator(tail_); }
- iterator end() const { return iterator(); }
+ iterator begin() const { return iterator(head_); }
+ reverse_iterator rbegin() const { return reverse_iterator(tail_); }
+ iterator end() const { return iterator(); }
+ reverse_iterator rend() const { return reverse_iterator(); }
typedef iterator const_iterator; // for now
@@ -158,7 +212,7 @@ list<T>::~list()
for (; start; start = next_) {
next_ = start->next_;
destroy(start);
- free(start);
+ FreeMemory(start);
}
}
@@ -166,8 +220,7 @@ list<T>::~list()
template<typename T>
void list<T>::push_front(T t)
{
- void* mem = malloc(sizeof(node));
- if (!mem) abort();
+ void* mem = GetMemory(sizeof(node));
node* add = new (reinterpret_cast<yassl_pointer>(mem)) node(t);
if (head_) {
@@ -196,7 +249,7 @@ void list<T>::pop_front()
head_->prev_ = 0;
}
destroy(front);
- free(front);
+ FreeMemory(front);
--sz_;
}
@@ -204,7 +257,7 @@ void list<T>::pop_front()
template<typename T>
T list<T>::front() const
{
- if (head_ == 0) return 0;
+ if (head_ == 0) return T();
return head_->value_;
}
@@ -212,8 +265,7 @@ T list<T>::front() const
template<typename T>
void list<T>::push_back(T t)
{
- void* mem = malloc(sizeof(node));
- if (!mem) abort();
+ void* mem = GetMemory(sizeof(node));
node* add = new (reinterpret_cast<yassl_pointer>(mem)) node(t);
if (tail_) {
@@ -242,7 +294,7 @@ void list<T>::pop_back()
tail_->next_ = 0;
}
destroy(rear);
- free(rear);
+ FreeMemory(rear);
--sz_;
}
@@ -250,7 +302,7 @@ void list<T>::pop_back()
template<typename T>
T list<T>::back() const
{
- if (tail_ == 0) return 0;
+ if (tail_ == 0) return T();
return tail_->value_;
}
@@ -286,7 +338,7 @@ bool list<T>::remove(T t)
del->next_->prev_ = del->prev_;
destroy(del);
- free(del);
+ FreeMemory(del);
--sz_;
}
return true;
@@ -309,78 +361,13 @@ bool list<T>::erase(iterator iter)
del->next_->prev_ = del->prev_;
destroy(del);
- free(del);
+ FreeMemory(del);
--sz_;
}
return true;
}
-/* MSVC can't handle ??
-
-template<typename T>
-T& list<T>::iterator::operator*() const
-{
- return current_->value_;
-}
-
-
-template<typename T>
-T* list<T>::iterator::operator->() const
-{
- return &(operator*());
-}
-
-
-template<typename T>
-typename list<T>::iterator& list<T>::iterator::operator++()
-{
- current_ = current_->next_;
- return *this;
-}
-
-
-template<typename T>
-typename list<T>::iterator& list<T>::iterator::operator--()
-{
- current_ = current_->prev_;
- return *this;
-}
-
-
-template<typename T>
-typename list<T>::iterator& list<T>::iterator::operator++(int)
-{
- iterator tmp = *this;
- current_ = current_->next_;
- return tmp;
-}
-
-
-template<typename T>
-typename list<T>::iterator& list<T>::iterator::operator--(int)
-{
- iterator tmp = *this;
- current_ = current_->prev_;
- return tmp;
-}
-
-
-template<typename T>
-bool list<T>::iterator::operator==(const iterator& other) const
-{
- return current_ == other.current_;
-}
-
-
-template<typename T>
-bool list<T>::iterator::operator!=(const iterator& other) const
-{
- return current_ != other.current_;
-}
-*/ // end MSVC 6 can't handle
-
-
} // namespace mySTL
diff --git a/extra/yassl/mySTL/memory.hpp b/extra/yassl/taocrypt/mySTL/memory.hpp
index f480af12316..5855423c6fc 100644
--- a/extra/yassl/mySTL/memory.hpp
+++ b/extra/yassl/taocrypt/mySTL/memory.hpp
@@ -31,6 +31,7 @@
#ifndef mySTL_MEMORY_HPP
#define mySTL_MEMORY_HPP
+#include "memory_array.hpp" // for auto_array
#ifdef _MSC_VER
// disable operator-> warning for builtins
@@ -43,27 +44,25 @@ namespace mySTL {
template<typename T>
struct auto_ptr_ref {
- typedef void (*Deletor)(T*);
- T* ptr_;
- Deletor del_;
- auto_ptr_ref(T* p, Deletor d) : ptr_(p), del_(d) {}
+ T* ptr_;
+ explicit auto_ptr_ref(T* p) : ptr_(p) {}
};
template<typename T>
class auto_ptr {
- typedef void (*Deletor)(T*);
T* ptr_;
- Deletor del_;
void Destroy()
{
- del_(ptr_);
+ #ifdef YASSL_LIB
+ yaSSL::ysDelete(ptr_);
+ #else
+ TaoCrypt::tcDelete(ptr_);
+ #endif
}
public:
- auto_ptr(T* p, Deletor d) : ptr_(p), del_(d) {}
-
- explicit auto_ptr(Deletor d) : ptr_(0), del_(d) {}
+ explicit auto_ptr(T* p = 0) : ptr_(p) {}
~auto_ptr()
{
@@ -71,14 +70,13 @@ public:
}
- auto_ptr(auto_ptr& other) : ptr_(other.release()), del_(other.del_) {}
+ auto_ptr(auto_ptr& other) : ptr_(other.release()) {}
auto_ptr& operator=(auto_ptr& that)
{
if (this != &that) {
Destroy();
ptr_ = that.release();
- del_ = that.del_;
}
return *this;
}
@@ -115,14 +113,13 @@ public:
}
// auto_ptr_ref conversions
- auto_ptr(auto_ptr_ref<T> ref) : ptr_(ref.ptr_), del_(ref.del_) {}
+ auto_ptr(auto_ptr_ref<T> ref) : ptr_(ref.ptr_) {}
auto_ptr& operator=(auto_ptr_ref<T> ref)
{
if (this->ptr_ != ref.ptr_) {
Destroy();
ptr_ = ref.ptr_;
- del_ = ref.del_;
}
return *this;
}
@@ -130,13 +127,13 @@ public:
template<typename T2>
operator auto_ptr<T2>()
{
- return auto_ptr<T2>(this->release(), this->del_);
+ return auto_ptr<T2>(this->release());
}
template<typename T2>
operator auto_ptr_ref<T2>()
{
- return auto_ptr_ref<T2>(this->release(), this->del_);
+ return auto_ptr_ref<T2>(this->release());
}
};
diff --git a/extra/yassl/taocrypt/mySTL/memory_array.hpp b/extra/yassl/taocrypt/mySTL/memory_array.hpp
new file mode 100644
index 00000000000..f089c69f815
--- /dev/null
+++ b/extra/yassl/taocrypt/mySTL/memory_array.hpp
@@ -0,0 +1,142 @@
+/* mySTL memory_array.hpp
+ *
+ * Copyright (C) 2003 Sawtooth Consulting Ltd.
+ *
+ * This file is part of yaSSL.
+ *
+ * yaSSL is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * There are special exceptions to the terms and conditions of the GPL as it
+ * is applied to yaSSL. View the full text of the exception in the file
+ * FLOSS-EXCEPTIONS in the directory of this software distribution.
+ *
+ * yaSSL is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ */
+
+
+/* mySTL memory_arry implements auto_array
+ *
+ */
+
+#ifndef mySTL_MEMORY_ARRAY_HPP
+#define mySTL_MEMORY_ARRAY_HPP
+
+
+#ifdef _MSC_VER
+ // disable operator-> warning for builtins
+ #pragma warning(disable:4284)
+#endif
+
+
+namespace mySTL {
+
+
+template<typename T>
+struct auto_array_ref {
+ T* ptr_;
+ explicit auto_array_ref(T* p) : ptr_(p) {}
+};
+
+
+template<typename T>
+class auto_array {
+ T* ptr_;
+
+ void Destroy()
+ {
+ #ifdef YASSL_LIB
+ yaSSL::ysArrayDelete(ptr_);
+ #else
+ TaoCrypt::tcArrayDelete(ptr_);
+ #endif
+ }
+public:
+ explicit auto_array(T* p = 0) : ptr_(p) {}
+
+ ~auto_array()
+ {
+ Destroy();
+ }
+
+
+ auto_array(auto_array& other) : ptr_(other.release()) {}
+
+ auto_array& operator=(auto_array& that)
+ {
+ if (this != &that) {
+ Destroy();
+ ptr_ = that.release();
+ }
+ return *this;
+ }
+
+
+ T* operator->() const
+ {
+ return ptr_;
+ }
+
+ T& operator*() const
+ {
+ return *ptr_;
+ }
+
+ T* get() const
+ {
+ return ptr_;
+ }
+
+ T* release()
+ {
+ T* tmp = ptr_;
+ ptr_ = 0;
+ return tmp;
+ }
+
+ void reset(T* p = 0)
+ {
+ if (ptr_ != p) {
+ Destroy();
+ ptr_ = p;
+ }
+ }
+
+ // auto_array_ref conversions
+ auto_array(auto_array_ref<T> ref) : ptr_(ref.ptr_) {}
+
+ auto_array& operator=(auto_array_ref<T> ref)
+ {
+ if (this->ptr_ != ref.ptr_) {
+ Destroy();
+ ptr_ = ref.ptr_;
+ }
+ return *this;
+ }
+
+ template<typename T2>
+ operator auto_array<T2>()
+ {
+ return auto_array<T2>(this->release());
+ }
+
+ template<typename T2>
+ operator auto_array_ref<T2>()
+ {
+ return auto_array_ref<T2>(this->release());
+ }
+};
+
+
+} // namespace mySTL
+
+#endif // mySTL_MEMORY_ARRAY_HPP
diff --git a/extra/yassl/mySTL/pair.hpp b/extra/yassl/taocrypt/mySTL/pair.hpp
index 13916fece13..13916fece13 100644
--- a/extra/yassl/mySTL/pair.hpp
+++ b/extra/yassl/taocrypt/mySTL/pair.hpp
diff --git a/extra/yassl/mySTL/stdexcept.hpp b/extra/yassl/taocrypt/mySTL/stdexcept.hpp
index 4fd343ae6fd..4fd343ae6fd 100644
--- a/extra/yassl/mySTL/stdexcept.hpp
+++ b/extra/yassl/taocrypt/mySTL/stdexcept.hpp
diff --git a/extra/yassl/mySTL/vector.hpp b/extra/yassl/taocrypt/mySTL/vector.hpp
index 6a412447b91..902e014f75b 100644
--- a/extra/yassl/mySTL/vector.hpp
+++ b/extra/yassl/taocrypt/mySTL/vector.hpp
@@ -34,7 +34,6 @@
#include "helpers.hpp" // construct, destory, fill, etc.
#include "algorithm.hpp" // swap
#include <assert.h> // assert
-#include <stdlib.h> // malloc
namespace mySTL {
@@ -49,14 +48,15 @@ struct vector_base {
vector_base() : start_(0), finish_(0), end_of_storage_(0) {}
vector_base(size_t n)
{
- // Don't allow malloc(0), if n is 0 use 1
- start_ = static_cast<T*>(malloc((n ? n : 1) * sizeof(T)));
- if (!start_) abort();
+ start_ = GetArrayMemory<T>(n);
finish_ = start_;
end_of_storage_ = start_ + n;
}
- ~vector_base() { if (start_) free(start_); }
+ ~vector_base()
+ {
+ FreeArrayMemory(start_);
+ }
void Swap(vector_base& that)
{
@@ -71,6 +71,9 @@ struct vector_base {
template <typename T>
class vector {
public:
+ typedef T* iterator;
+ typedef const T* const_iterator;
+
vector() {}
explicit vector(size_t n) : vec_(n)
{
diff --git a/extra/yassl/taocrypt/src/Makefile.am b/extra/yassl/taocrypt/src/Makefile.am
index 1110ed335b8..6d02a625275 100644
--- a/extra/yassl/taocrypt/src/Makefile.am
+++ b/extra/yassl/taocrypt/src/Makefile.am
@@ -1,4 +1,4 @@
-INCLUDES = -I../include -I../../mySTL
+INCLUDES = -I../include -I../mySTL
noinst_LTLIBRARIES = libtaocrypt.la
@@ -11,3 +11,7 @@ libtaocrypt_la_SOURCES = aes.cpp aestables.cpp algebra.cpp arc4.cpp \
libtaocrypt_la_CXXFLAGS = @yassl_taocrypt_extra_cxxflags@ -DYASSL_PURE_C
EXTRA_DIST = $(wildcard ../include/*.hpp)
+
+# Don't update the files from bitkeeper
+%::SCCS/s.%
+
diff --git a/extra/yassl/taocrypt/src/algebra.cpp b/extra/yassl/taocrypt/src/algebra.cpp
index e9bc3fceac0..375cd6cd524 100644
--- a/extra/yassl/taocrypt/src/algebra.cpp
+++ b/extra/yassl/taocrypt/src/algebra.cpp
@@ -29,7 +29,10 @@
#include "runtime.hpp"
#include "algebra.hpp"
-#include "vector.hpp" // mySTL::vector (simple)
+#include STL_VECTOR_FILE
+
+
+namespace STL = STL_NAMESPACE;
namespace TaoCrypt {
@@ -82,7 +85,7 @@ const Integer& AbstractEuclideanDomain::Mod(const Element &a,
const Integer& AbstractEuclideanDomain::Gcd(const Element &a,
const Element &b) const
{
- mySTL::vector<Element> g(3);
+ STL::vector<Element> g(3);
g[0]= b;
g[1]= a;
unsigned int i0=0, i1=1, i2=2;
@@ -115,7 +118,7 @@ Integer AbstractGroup::CascadeScalarMultiply(const Element &x,
const unsigned w = (expLen <= 46 ? 1 : (expLen <= 260 ? 2 : 3));
const unsigned tableSize = 1<<w;
- mySTL::vector<Element> powerTable(tableSize << w);
+ STL::vector<Element> powerTable(tableSize << w);
powerTable[1] = x;
powerTable[tableSize] = y;
@@ -240,8 +243,8 @@ struct WindowSlider
void AbstractGroup::SimultaneousMultiply(Integer *results, const Integer &base,
const Integer *expBegin, unsigned int expCount) const
{
- mySTL::vector<mySTL::vector<Element> > buckets(expCount);
- mySTL::vector<WindowSlider> exponents;
+ STL::vector<STL::vector<Element> > buckets(expCount);
+ STL::vector<WindowSlider> exponents;
exponents.reserve(expCount);
unsigned int i;
@@ -332,6 +335,8 @@ void AbstractRing::SimultaneousExponentiate(Integer *results,
namespace mySTL {
template TaoCrypt::WindowSlider* uninit_copy<TaoCrypt::WindowSlider*, TaoCrypt::WindowSlider*>(TaoCrypt::WindowSlider*, TaoCrypt::WindowSlider*, TaoCrypt::WindowSlider*);
template void destroy<TaoCrypt::WindowSlider*>(TaoCrypt::WindowSlider*, TaoCrypt::WindowSlider*);
+template TaoCrypt::WindowSlider* GetArrayMemory<TaoCrypt::WindowSlider>(size_t);
+template void FreeArrayMemory<TaoCrypt::WindowSlider>(TaoCrypt::WindowSlider*);
}
#endif
diff --git a/extra/yassl/taocrypt/src/asn.cpp b/extra/yassl/taocrypt/src/asn.cpp
index 45fb1e60a0c..3dc3638d85f 100644
--- a/extra/yassl/taocrypt/src/asn.cpp
+++ b/extra/yassl/taocrypt/src/asn.cpp
@@ -38,7 +38,8 @@
#include "sha.hpp"
#include "coding.hpp"
#include <time.h> // gmtime();
-#include "memory.hpp" // mySTL::auto_ptr
+#include "memory.hpp" // some auto_ptr don't have reset, also need auto_array
+
namespace TaoCrypt {
@@ -202,13 +203,13 @@ void PublicKey::SetKey(const byte* k)
void PublicKey::AddToEnd(const byte* data, word32 len)
{
- mySTL::auto_ptr<byte> tmp(NEW_TC byte[sz_ + len], tcArrayDelete);
+ mySTL::auto_array<byte> tmp(NEW_TC byte[sz_ + len]);
memcpy(tmp.get(), key_, sz_);
memcpy(tmp.get() + sz_, data, len);
byte* del = 0;
- mySTL::swap(del, key_);
+ STL::swap(del, key_);
tcArrayDelete(del);
key_ = tmp.release();
@@ -856,7 +857,7 @@ bool CertDecoder::ValidateSignature(SignerList* signers)
bool CertDecoder::ConfirmSignature(Source& pub)
{
HashType ht;
- mySTL::auto_ptr<HASH> hasher(tcDelete);
+ mySTL::auto_ptr<HASH> hasher;
if (signatureOID_ == MD5wRSA) {
hasher.reset(NEW_TC MD5);
diff --git a/extra/yassl/taocrypt/src/blowfish.cpp b/extra/yassl/taocrypt/src/blowfish.cpp
index cc929cd7d41..40ae1a17e6c 100644
--- a/extra/yassl/taocrypt/src/blowfish.cpp
+++ b/extra/yassl/taocrypt/src/blowfish.cpp
@@ -133,7 +133,7 @@ void Blowfish::SetKey(const byte* key_string, word32 keylength, CipherDir dir)
if (dir==DECRYPTION)
for (i=0; i<(ROUNDS+2)/2; i++)
- mySTL::swap(pbox_[i], pbox_[ROUNDS+1-i]);
+ STL::swap(pbox_[i], pbox_[ROUNDS+1-i]);
}
diff --git a/extra/yassl/taocrypt/src/crypto.cpp b/extra/yassl/taocrypt/src/crypto.cpp
new file mode 100644
index 00000000000..95238100f5d
--- /dev/null
+++ b/extra/yassl/taocrypt/src/crypto.cpp
@@ -0,0 +1,39 @@
+/* crypto.cpp
+ *
+ * Copyright (C) 2003 Sawtooth Consulting Ltd.
+ *
+ * This file is part of yaSSL.
+ *
+ * yaSSL is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * There are special exceptions to the terms and conditions of the GPL as it
+ * is applied to yaSSL. View the full text of the exception in the file
+ * FLOSS-EXCEPTIONS in the directory of this software distribution.
+ *
+ * yaSSL is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ */
+
+/* put features that other apps expect from OpenSSL type crypto */
+
+
+
+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"
+
+
+
diff --git a/extra/yassl/taocrypt/src/des.cpp b/extra/yassl/taocrypt/src/des.cpp
index 054c8c2eb78..2628e142bae 100644
--- a/extra/yassl/taocrypt/src/des.cpp
+++ b/extra/yassl/taocrypt/src/des.cpp
@@ -34,7 +34,10 @@
#include "runtime.hpp"
#include "des.hpp"
-#include "algorithm.hpp" // mySTL::swap
+#include STL_ALGORITHM_FILE
+
+
+namespace STL = STL_NAMESPACE;
#if defined(TAOCRYPT_X86ASM_AVAILABLE) && defined(TAO_ASM)
@@ -265,8 +268,8 @@ void BasicDES::SetKey(const byte* key, word32 /*length*/, CipherDir dir)
// reverse key schedule order
if (dir == DECRYPTION)
for (i = 0; i < 16; i += 2) {
- mySTL::swap(k_[i], k_[32 - 2 - i]);
- mySTL::swap(k_[i+1], k_[32 - 1 - i]);
+ STL::swap(k_[i], k_[32 - 2 - i]);
+ STL::swap(k_[i+1], k_[32 - 1 - i]);
}
}
diff --git a/extra/yassl/taocrypt/src/dh.cpp b/extra/yassl/taocrypt/src/dh.cpp
index aec7122b70b..671a20d0d78 100644
--- a/extra/yassl/taocrypt/src/dh.cpp
+++ b/extra/yassl/taocrypt/src/dh.cpp
@@ -61,7 +61,7 @@ void DH::GenerateKeyPair(RandomNumberGenerator& rng, byte* priv, byte* pub)
// Generate private value
void DH::GeneratePrivate(RandomNumberGenerator& rng, byte* priv)
{
- Integer x(rng, Integer::One(), mySTL::min(p_ - 1,
+ Integer x(rng, Integer::One(), min(p_ - 1,
Integer::Power2(2*DiscreteLogWorkFactor(p_.BitCount())) ) );
x.Encode(priv, p_.ByteCount());
}
diff --git a/extra/yassl/taocrypt/src/integer.cpp b/extra/yassl/taocrypt/src/integer.cpp
index 823c0c5e193..500160cfe37 100644
--- a/extra/yassl/taocrypt/src/integer.cpp
+++ b/extra/yassl/taocrypt/src/integer.cpp
@@ -1094,7 +1094,7 @@ static bool IsP4()
word32 cpuid[4];
CpuId(0, cpuid);
- mySTL::swap(cpuid[2], cpuid[3]);
+ STL::swap(cpuid[2], cpuid[3]);
if (memcmp(cpuid+1, "GenuineIntel", 12) != 0)
return false;
@@ -2384,8 +2384,8 @@ void AsymmetricMultiply(word *R, word *T, const word *A, unsigned int NA,
if (NA > NB)
{
- mySTL::swap(A, B);
- mySTL::swap(NA, NB);
+ STL::swap(A, B);
+ STL::swap(NA, NB);
}
assert(NB % NA == 0);
@@ -2521,8 +2521,8 @@ unsigned int AlmostInverse(word *R, word *T, const word *A, unsigned int NA,
if (Compare(f, g, fgLen)==-1)
{
- mySTL::swap(f, g);
- mySTL::swap(b, c);
+ STL::swap(f, g);
+ STL::swap(b, c);
s++;
}
@@ -3162,7 +3162,7 @@ signed long Integer::ConvertToLong() const
void Integer::Swap(Integer& a)
{
reg_.Swap(a.reg_);
- mySTL::swap(sign_, a.sign_);
+ STL::swap(sign_, a.sign_);
}
diff --git a/extra/yassl/taocrypt/src/md4.cpp b/extra/yassl/taocrypt/src/md4.cpp
index 6012330cba3..0dee8bf40cb 100644
--- a/extra/yassl/taocrypt/src/md4.cpp
+++ b/extra/yassl/taocrypt/src/md4.cpp
@@ -28,9 +28,11 @@
#include "runtime.hpp"
#include "md4.hpp"
-#include "algorithm.hpp" // mySTL::swap
+#include STL_ALGORITHM_FILE
+namespace STL = STL_NAMESPACE;
+
namespace TaoCrypt {
@@ -69,9 +71,9 @@ MD4& MD4::operator= (const MD4& that)
void MD4::Swap(MD4& other)
{
- mySTL::swap(loLen_, other.loLen_);
- mySTL::swap(hiLen_, other.hiLen_);
- mySTL::swap(buffLen_, other.buffLen_);
+ STL::swap(loLen_, other.loLen_);
+ STL::swap(hiLen_, other.hiLen_);
+ STL::swap(buffLen_, other.buffLen_);
memcpy(digest_, other.digest_, DIGEST_SIZE);
memcpy(buffer_, other.buffer_, BLOCK_SIZE);
diff --git a/extra/yassl/taocrypt/src/md5.cpp b/extra/yassl/taocrypt/src/md5.cpp
index f7b0b1ee2dc..2bddc7fe308 100644
--- a/extra/yassl/taocrypt/src/md5.cpp
+++ b/extra/yassl/taocrypt/src/md5.cpp
@@ -28,7 +28,10 @@
#include "runtime.hpp"
#include "md5.hpp"
-#include "algorithm.hpp" // mySTL::swap
+#include STL_ALGORITHM_FILE
+
+
+namespace STL = STL_NAMESPACE;
#if defined(TAOCRYPT_X86ASM_AVAILABLE) && defined(TAO_ASM)
@@ -72,9 +75,9 @@ MD5& MD5::operator= (const MD5& that)
void MD5::Swap(MD5& other)
{
- mySTL::swap(loLen_, other.loLen_);
- mySTL::swap(hiLen_, other.hiLen_);
- mySTL::swap(buffLen_, other.buffLen_);
+ STL::swap(loLen_, other.loLen_);
+ STL::swap(hiLen_, other.hiLen_);
+ STL::swap(buffLen_, other.buffLen_);
memcpy(digest_, other.digest_, DIGEST_SIZE);
memcpy(buffer_, other.buffer_, BLOCK_SIZE);
diff --git a/extra/yassl/taocrypt/src/misc.cpp b/extra/yassl/taocrypt/src/misc.cpp
index a33ca4fa432..084a263a4ae 100644
--- a/extra/yassl/taocrypt/src/misc.cpp
+++ b/extra/yassl/taocrypt/src/misc.cpp
@@ -29,15 +29,6 @@
#include "runtime.hpp"
#include "misc.hpp"
-#if !defined(YASSL_MYSQL_COMPATIBLE)
-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"
-#endif
#ifdef YASSL_PURE_C
diff --git a/extra/yassl/taocrypt/src/random.cpp b/extra/yassl/taocrypt/src/random.cpp
index 2ee1e57a663..c7bb6ae9549 100644
--- a/extra/yassl/taocrypt/src/random.cpp
+++ b/extra/yassl/taocrypt/src/random.cpp
@@ -31,7 +31,7 @@
#include "runtime.hpp"
#include "random.hpp"
#include <string.h>
-
+#include <time.h>
#if defined(_WIN32)
#define _WIN32_WINNT 0x0400
@@ -74,6 +74,8 @@ byte RandomNumberGenerator::GenerateByte()
#if defined(_WIN32)
+/* The OS_Seed implementation for windows */
+
OS_Seed::OS_Seed()
{
if(!CryptAcquireContext(&handle_, 0, 0, PROV_RSA_FULL,
@@ -95,8 +97,70 @@ void OS_Seed::GenerateSeed(byte* output, word32 sz)
}
-#else // _WIN32
+#elif defined(__NETWARE__)
+
+/* The OS_Seed implementation for Netware */
+
+#include <nks/thread.h>
+#include <nks/plat.h>
+
+// Loop on high resulution Read Time Stamp Counter
+static void NetwareSeed(byte* output, word32 sz)
+{
+ word32 tscResult;
+
+ for (word32 i = 0; i < sz; i += sizeof(tscResult)) {
+ #if defined(__GNUC__)
+ asm volatile("rdtsc" : "=A" (tscResult));
+ #else
+ #ifdef __MWERKS__
+ asm {
+ #else
+ __asm {
+ #endif
+ rdtsc
+ mov tscResult, eax
+ }
+ #endif
+
+ memcpy(output, &tscResult, sizeof(tscResult));
+ output += sizeof(tscResult);
+
+ NXThreadYield(); // induce more variance
+ }
+}
+
+
+OS_Seed::OS_Seed()
+{
+}
+
+
+OS_Seed::~OS_Seed()
+{
+}
+
+
+void OS_Seed::GenerateSeed(byte* output, word32 sz)
+{
+ /*
+ Try to use NXSeedRandom as it will generate a strong
+ seed using the onboard 82802 chip
+
+ As it's not always supported, fallback to default
+ implementation if an error is returned
+ */
+
+ if (NXSeedRandom(sz, output) != 0)
+ {
+ NetwareSeed(output, sz);
+ }
+}
+
+
+#else
+/* The default OS_Seed implementation */
OS_Seed::OS_Seed()
{
diff --git a/extra/yassl/taocrypt/src/ripemd.cpp b/extra/yassl/taocrypt/src/ripemd.cpp
index c791189544f..03c09edde84 100644
--- a/extra/yassl/taocrypt/src/ripemd.cpp
+++ b/extra/yassl/taocrypt/src/ripemd.cpp
@@ -28,9 +28,11 @@
#include "runtime.hpp"
#include "ripemd.hpp"
-#include "algorithm.hpp" // mySTL::swap
+#include STL_ALGORITHM_FILE
+namespace STL = STL_NAMESPACE;
+
#if defined(TAOCRYPT_X86ASM_AVAILABLE) && defined(TAO_ASM)
#define DO_RIPEMD_ASM
@@ -75,9 +77,9 @@ RIPEMD160& RIPEMD160::operator= (const RIPEMD160& that)
void RIPEMD160::Swap(RIPEMD160& other)
{
- mySTL::swap(loLen_, other.loLen_);
- mySTL::swap(hiLen_, other.hiLen_);
- mySTL::swap(buffLen_, other.buffLen_);
+ STL::swap(loLen_, other.loLen_);
+ STL::swap(hiLen_, other.hiLen_);
+ STL::swap(buffLen_, other.buffLen_);
memcpy(digest_, other.digest_, DIGEST_SIZE);
memcpy(buffer_, other.buffer_, BLOCK_SIZE);
diff --git a/extra/yassl/taocrypt/src/sha.cpp b/extra/yassl/taocrypt/src/sha.cpp
index b877e2b7857..280d42fb3d4 100644
--- a/extra/yassl/taocrypt/src/sha.cpp
+++ b/extra/yassl/taocrypt/src/sha.cpp
@@ -27,8 +27,11 @@
#include "runtime.hpp"
#include <string.h>
-#include "algorithm.hpp" // mySTL::swap
#include "sha.hpp"
+#include STL_ALGORITHM_FILE
+
+
+namespace STL = STL_NAMESPACE;
#if defined(TAOCRYPT_X86ASM_AVAILABLE) && defined(TAO_ASM)
@@ -96,9 +99,9 @@ SHA& SHA::operator= (const SHA& that)
void SHA::Swap(SHA& other)
{
- mySTL::swap(loLen_, other.loLen_);
- mySTL::swap(hiLen_, other.hiLen_);
- mySTL::swap(buffLen_, other.buffLen_);
+ STL::swap(loLen_, other.loLen_);
+ STL::swap(hiLen_, other.hiLen_);
+ STL::swap(buffLen_, other.buffLen_);
memcpy(digest_, other.digest_, DIGEST_SIZE);
memcpy(buffer_, other.buffer_, BLOCK_SIZE);
diff --git a/extra/yassl/taocrypt/src/template_instnt.cpp b/extra/yassl/taocrypt/src/template_instnt.cpp
index 512c5cf9dce..db1ae645e09 100644
--- a/extra/yassl/taocrypt/src/template_instnt.cpp
+++ b/extra/yassl/taocrypt/src/template_instnt.cpp
@@ -77,6 +77,13 @@ template void destroy<vector<TaoCrypt::Integer>*>(vector<TaoCrypt::Integer>*, ve
template TaoCrypt::Integer* uninit_copy<TaoCrypt::Integer*, TaoCrypt::Integer*>(TaoCrypt::Integer*, TaoCrypt::Integer*, TaoCrypt::Integer*);
template TaoCrypt::Integer* uninit_fill_n<TaoCrypt::Integer*, size_t, TaoCrypt::Integer>(TaoCrypt::Integer*, size_t, TaoCrypt::Integer const&);
template void destroy<TaoCrypt::Integer*>(TaoCrypt::Integer*, TaoCrypt::Integer*);
+template TaoCrypt::byte* GetArrayMemory<TaoCrypt::byte>(size_t);
+template void FreeArrayMemory<TaoCrypt::byte>(TaoCrypt::byte*);
+template TaoCrypt::Integer* GetArrayMemory<TaoCrypt::Integer>(size_t);
+template void FreeArrayMemory<TaoCrypt::Integer>(TaoCrypt::Integer*);
+template vector<TaoCrypt::Integer>* GetArrayMemory<vector<TaoCrypt::Integer> >(size_t);
+template void FreeArrayMemory<vector<TaoCrypt::Integer> >(vector<TaoCrypt::Integer>*);
+template void FreeArrayMemory<void>(void*);
}
#endif
diff --git a/extra/yassl/taocrypt/test/Makefile.am b/extra/yassl/taocrypt/test/Makefile.am
index 0b238f1e057..988d00c7bef 100644
--- a/extra/yassl/taocrypt/test/Makefile.am
+++ b/extra/yassl/taocrypt/test/Makefile.am
@@ -1,8 +1,6 @@
-INCLUDES = -I../include -I../../mySTL
+INCLUDES = -I../include -I../mySTL
bin_PROGRAMS = test
test_SOURCES = test.cpp
-test_LDFLAGS = -L../src
-test_LDADD = -ltaocrypt
-test_DEPENDENCIES = ../src/libtaocrypt.la
+test_LDADD = $(top_builddir)/extra/yassl/taocrypt/src/libtaocrypt.la
test_CXXFLAGS = -DYASSL_PURE_C
EXTRA_DIST = make.bat
diff --git a/extra/yassl/testsuite/Makefile.am b/extra/yassl/testsuite/Makefile.am
index 2ae46a1b409..e8abffd6bb0 100644
--- a/extra/yassl/testsuite/Makefile.am
+++ b/extra/yassl/testsuite/Makefile.am
@@ -1,11 +1,14 @@
-INCLUDES = -I../include -I../taocrypt/include -I../mySTL
+INCLUDES = -I../include -I../taocrypt/include -I../taocrypt/mySTL
bin_PROGRAMS = testsuite
testsuite_SOURCES = testsuite.cpp ../taocrypt/test/test.cpp \
../examples/client/client.cpp ../examples/server/server.cpp \
../examples/echoclient/echoclient.cpp \
../examples/echoserver/echoserver.cpp
-testsuite_LDFLAGS = -L../src/ -L../taocrypt/src
testsuite_CXXFLAGS = -DYASSL_PURE_C -DYASSL_PREFIX -DNO_MAIN_DRIVER
-testsuite_LDADD = -lyassl -ltaocrypt
-testsuite_DEPENDENCIES = ../src/libyassl.la ../taocrypt/src/libtaocrypt.la
+testsuite_LDADD = $(top_builddir)/extra/yassl/src/libyassl.la \
+ $(top_builddir)/extra/yassl/taocrypt/src/libtaocrypt.la
EXTRA_DIST = testsuite.dsp test.hpp input quit make.bat
+
+# Don't update the files from bitkeeper
+%::SCCS/s.%
+
diff --git a/extra/yassl/testsuite/test.hpp b/extra/yassl/testsuite/test.hpp
index 482d384d415..0266c802657 100644
--- a/extra/yassl/testsuite/test.hpp
+++ b/extra/yassl/testsuite/test.hpp
@@ -27,24 +27,27 @@
#endif /* _WIN32 */
-#if !defined(_SOCKLEN_T) && defined(_WIN32)
+#if !defined(_SOCKLEN_T) && (defined(_WIN32) || defined(__NETWARE__))
typedef int socklen_t;
#endif
+// Check type of third arg to accept
+#if defined(__hpux)
// HPUX doesn't use socklent_t for third parameter to accept
-#if !defined(__hpux)
- typedef socklen_t* ACCEPT_THIRD_T;
-#else
typedef int* ACCEPT_THIRD_T;
+#else
+ typedef socklen_t* ACCEPT_THIRD_T;
+#endif
+
+// Check if _POSIX_THREADS should be forced
+#if !defined(_POSIX_THREADS) && (defined(__NETWARE__) || defined(__hpux))
// HPUX does not define _POSIX_THREADS as it's not _fully_ implemented
-#ifndef _POSIX_THREADS
+// Netware supports pthreads but does not announce it
#define _POSIX_THREADS
#endif
-#endif
-
#ifndef _POSIX_THREADS
typedef unsigned int THREAD_RETURN;
@@ -148,6 +151,13 @@ inline void err_sys(const char* msg)
}
+static int PasswordCallBack(char* passwd, int sz, int rw, void* userdata)
+{
+ strncpy(passwd, "12345678", sz);
+ return 8;
+}
+
+
inline void store_ca(SSL_CTX* ctx)
{
// To allow testing from serveral dirs
@@ -168,6 +178,7 @@ inline void store_ca(SSL_CTX* ctx)
inline void set_certs(SSL_CTX* ctx)
{
store_ca(ctx);
+ SSL_CTX_set_default_passwd_cb(ctx, PasswordCallBack);
// To allow testing from serveral dirs
if (SSL_CTX_use_certificate_file(ctx, cert, SSL_FILETYPE_PEM)
@@ -193,6 +204,7 @@ inline void set_certs(SSL_CTX* ctx)
inline void set_serverCerts(SSL_CTX* ctx)
{
store_ca(ctx);
+ SSL_CTX_set_default_passwd_cb(ctx, PasswordCallBack);
// To allow testing from serveral dirs
if (SSL_CTX_use_certificate_file(ctx, svrCert, SSL_FILETYPE_PEM)
@@ -258,13 +270,27 @@ inline void tcp_socket(SOCKET_T& sockfd, sockaddr_in& addr)
}
+inline void tcp_close(SOCKET_T& sockfd)
+{
+#ifdef _WIN32
+ closesocket(sockfd);
+#else
+ close(sockfd);
+#endif
+ sockfd = -1;
+}
+
+
inline void tcp_connect(SOCKET_T& sockfd)
{
sockaddr_in addr;
tcp_socket(sockfd, addr);
if (connect(sockfd, (const sockaddr*)&addr, sizeof(addr)) != 0)
+ {
+ tcp_close(sockfd);
err_sys("tcp connect failed");
+ }
}
@@ -274,13 +300,19 @@ inline void tcp_listen(SOCKET_T& sockfd)
tcp_socket(sockfd, addr);
if (bind(sockfd, (const sockaddr*)&addr, sizeof(addr)) != 0)
+ {
+ tcp_close(sockfd);
err_sys("tcp bind failed");
+ }
if (listen(sockfd, 3) != 0)
+ {
+ tcp_close(sockfd);
err_sys("tcp listen failed");
+ }
}
-inline void tcp_accept(SOCKET_T& sockfd, int& clientfd, func_args& args)
+inline void tcp_accept(SOCKET_T& sockfd, SOCKET_T& clientfd, func_args& args)
{
tcp_listen(sockfd);
@@ -299,7 +331,10 @@ inline void tcp_accept(SOCKET_T& sockfd, int& clientfd, func_args& args)
clientfd = accept(sockfd, (sockaddr*)&client, (ACCEPT_THIRD_T)&client_len);
if (clientfd == -1)
+ {
+ tcp_close(sockfd);
err_sys("tcp accept failed");
+ }
}
diff --git a/include/base64.h b/include/base64.h
index 4653e824a9a..a6bffebfe07 100644
--- a/include/base64.h
+++ b/include/base64.h
@@ -39,7 +39,8 @@ int base64_encode(const void *src, size_t src_len, char *dst);
/*
Decode a base64 string into data
*/
-int base64_decode(const char *src, size_t src_len, void *dst);
+int base64_decode(const char *src, size_t src_len,
+ void *dst, const char **end_ptr);
#ifdef __cplusplus
diff --git a/include/heap.h b/include/heap.h
index 985b20f9dc9..69d1e441a4b 100644
--- a/include/heap.h
+++ b/include/heap.h
@@ -225,6 +225,7 @@ extern int heap_indexes_are_disabled(HP_INFO *info);
extern void heap_update_auto_increment(HP_INFO *info, const byte *record);
ha_rows hp_rb_records_in_range(HP_INFO *info, int inx, key_range *min_key,
key_range *max_key);
+int hp_panic(enum ha_panic_function flag);
int heap_rkey(HP_INFO *info, byte *record, int inx, const byte *key,
uint key_len, enum ha_rkey_function find_flag);
extern gptr heap_find(HP_INFO *info,int inx,const byte *key);
diff --git a/include/m_ctype.h b/include/m_ctype.h
index 40cadad0017..c357f067358 100644
--- a/include/m_ctype.h
+++ b/include/m_ctype.h
@@ -196,7 +196,7 @@ typedef struct my_charset_handler_st
/* Charset dependant snprintf() */
int (*snprintf)(struct charset_info_st *, char *to, uint n, const char *fmt,
- ...);
+ ...) ATTRIBUTE_FORMAT_FPTR(printf, 4, 5);
int (*long10_to_str)(struct charset_info_st *, char *to, uint n, int radix,
long int val);
int (*longlong10_to_str)(struct charset_info_st *, char *to, uint n,
@@ -217,6 +217,9 @@ typedef struct my_charset_handler_st
int *err);
longlong (*strtoll10)(struct charset_info_st *cs,
const char *nptr, char **endptr, int *error);
+ ulonglong (*strntoull10rnd)(struct charset_info_st *cs,
+ const char *str, uint length, int unsigned_fl,
+ char **endptr, int *error);
ulong (*scan)(struct charset_info_st *, const char *b, const char *e,
int sq);
} MY_CHARSET_HANDLER;
@@ -335,7 +338,8 @@ int my_mb_ctype_mb(CHARSET_INFO *,int *, const uchar *,const uchar *);
ulong my_scan_8bit(CHARSET_INFO *cs, const char *b, const char *e, int sq);
int my_snprintf_8bit(struct charset_info_st *, char *to, uint n,
- const char *fmt, ...);
+ const char *fmt, ...)
+ ATTRIBUTE_FORMAT(printf, 4, 5);
long my_strntol_8bit(CHARSET_INFO *, const char *s, uint l, int base,
char **e, int *err);
@@ -357,6 +361,13 @@ longlong my_strtoll10_8bit(CHARSET_INFO *cs,
longlong my_strtoll10_ucs2(CHARSET_INFO *cs,
const char *nptr, char **endptr, int *error);
+ulonglong my_strntoull10rnd_8bit(CHARSET_INFO *cs,
+ const char *str, uint length, int unsigned_fl,
+ char **endptr, int *error);
+ulonglong my_strntoull10rnd_ucs2(CHARSET_INFO *cs,
+ const char *str, uint length, int unsigned_fl,
+ char **endptr, int *error);
+
void my_fill_8bit(CHARSET_INFO *cs, char* to, uint l, int fill);
my_bool my_like_range_simple(CHARSET_INFO *cs,
diff --git a/include/m_string.h b/include/m_string.h
index e009447c192..caccc59abd5 100644
--- a/include/m_string.h
+++ b/include/m_string.h
@@ -235,7 +235,8 @@ extern ulonglong strtoull(const char *str, char **ptr, int base);
extern int my_vsnprintf( char *str, size_t n,
const char *format, va_list ap );
-extern int my_snprintf(char* to, size_t n, const char* fmt, ...);
+extern int my_snprintf(char *to, size_t n, const char *fmt, ...)
+ ATTRIBUTE_FORMAT(printf, 3, 4);
#if defined(__cplusplus)
}
diff --git a/include/my_global.h b/include/my_global.h
index c72a7522127..39947735f3c 100644
--- a/include/my_global.h
+++ b/include/my_global.h
@@ -546,12 +546,50 @@ typedef unsigned short ushort;
#define function_volatile volatile
#define my_reinterpret_cast(A) reinterpret_cast<A>
#define my_const_cast(A) const_cast<A>
+# ifndef GCC_VERSION
+# define GCC_VERSION (__GNUC__ * 1000 + __GNUC_MINOR__)
+# endif
#elif !defined(my_reinterpret_cast)
#define my_reinterpret_cast(A) (A)
#define my_const_cast(A) (A)
#endif
-#if !defined(__attribute__) && (defined(__cplusplus) || !defined(__GNUC__) || __GNUC__ == 2 && __GNUC_MINOR__ < 8)
-#define __attribute__(A)
+
+/*
+ Disable __attribute__() on gcc < 2.7, g++ < 3.4, and non-gcc compilers.
+ Some forms of __attribute__ are actually supported in earlier versions of
+ g++, but we just disable them all because we only use them to generate
+ compilation warnings.
+*/
+#ifndef __attribute__
+# if !defined(__GNUC__)
+# define __attribute__(A)
+# elif GCC_VERSION < 2008
+# define __attribute__(A)
+# elif defined(__cplusplus) && GCC_VERSION < 3004
+# define __attribute__(A)
+# endif
+#endif
+
+/*
+ __attribute__((format(...))) is only supported in gcc >= 2.8 and g++ >= 3.4
+ But that's already covered by the __attribute__ tests above, so this is
+ just a convenience macro.
+*/
+#ifndef ATTRIBUTE_FORMAT
+# define ATTRIBUTE_FORMAT(style, m, n) __attribute__((format(style, m, n)))
+#endif
+
+/*
+
+ __attribute__((format(...))) on a function pointer is not supported
+ until gcc 3.1
+*/
+#ifndef ATTRIBUTE_FORMAT_FPTR
+# if (GCC_VERSION >= 3001)
+# define ATTRIBUTE_FORMAT_FPTR(style, m, n) ATTRIBUTE_FORMAT(style, m, n)
+# else
+# define ATTRIBUTE_FORMAT_FPTR(style, m, n)
+# endif /* GNUC >= 3.1 */
#endif
/*
diff --git a/include/my_sys.h b/include/my_sys.h
index 4b31f6bcd2b..e26e6535c66 100644
--- a/include/my_sys.h
+++ b/include/my_sys.h
@@ -517,6 +517,7 @@ typedef int (*qsort2_cmp)(const void *, const void *, const void *);
(uint) (*(info)->current_pos - (info)->request_pos))
/* tell write offset in the SEQ_APPEND cache */
+int my_b_copy_to_file(IO_CACHE *cache, FILE *file);
my_off_t my_b_append_tell(IO_CACHE* info);
my_off_t my_b_safe_tell(IO_CACHE* info); /* picks the correct tell() */
@@ -623,8 +624,8 @@ extern int my_chsize(File fd,my_off_t newlength, int filler, myf MyFlags);
extern int my_sync(File fd, myf my_flags);
extern int my_error _VARARGS((int nr,myf MyFlags, ...));
extern int my_printf_error _VARARGS((uint my_err, const char *format,
- myf MyFlags, ...)
- __attribute__ ((format (printf, 2, 4))));
+ myf MyFlags, ...))
+ ATTRIBUTE_FORMAT(printf, 2, 4);
extern int my_error_register(const char **errmsgs, int first, int last);
extern const char **my_error_unregister(int first, int last);
extern int my_message(uint my_err, const char *str,myf MyFlags);
diff --git a/include/mysql/plugin.h b/include/mysql/plugin.h
index ae952ccab1e..22cd64a52c4 100644
--- a/include/mysql/plugin.h
+++ b/include/mysql/plugin.h
@@ -31,6 +31,15 @@
#define MYSQL_FTPARSER_PLUGIN 2 /* Full-text parser plugin */
#define MYSQL_MAX_PLUGIN_TYPE_NUM 3 /* The number of plugin types */
+/* We use the following strings to define licenses for plugins */
+#define PLUGIN_LICENSE_PROPRIETARY 0
+#define PLUGIN_LICENSE_GPL 1
+#define PLUGIN_LICENSE_BSD 2
+
+#define PLUGIN_LICENSE_PROPRIETARY_STRING "PROPRIETARY"
+#define PLUGIN_LICENSE_GPL_STRING "GPL"
+#define PLUGIN_LICENSE_BSD_STRING "BSD"
+
/*
Macros for beginning and ending plugin declarations. Between
mysql_declare_plugin and mysql_declare_plugin_end there should
@@ -88,6 +97,7 @@ struct st_mysql_plugin
const char *name; /* plugin name */
const char *author; /* plugin author (for SHOW PLUGINS) */
const char *descr; /* general descriptive text (for SHOW PLUGINS ) */
+ int license; /* the plugin type (a MYSQL_XXX_PLUGIN value) */
int (*init)(void *); /* the function to invoke when plugin is loaded */
int (*deinit)(void *);/* the function to invoke when plugin is unloaded */
unsigned int version; /* plugin version (for SHOW PLUGINS) */
@@ -301,7 +311,6 @@ struct st_mysql_ftparser
struct st_mysql_storage_engine
{
int interface_version;
- struct handlerton *handlerton;
};
#endif
diff --git a/include/mysql_com.h b/include/mysql_com.h
index af3b8535ee2..156d68efdec 100644
--- a/include/mysql_com.h
+++ b/include/mysql_com.h
@@ -26,9 +26,6 @@
#define USERNAME_LENGTH 16
#define SERVER_VERSION_LENGTH 60
#define SQLSTATE_LENGTH 5
-#define SYSTEM_CHARSET_MBMAXLEN 3
-#define NAME_BYTE_LEN NAME_LEN*SYSTEM_CHARSET_MBMAXLEN
-#define USERNAME_BYTE_LENGTH USERNAME_LENGTH*SYSTEM_CHARSET_MBMAXLEN
/*
USER_HOST_BUFF_SIZE -- length of string buffer, that is enough to contain
@@ -36,7 +33,7 @@
MySQL standard format:
user_name_part@host_name_part\0
*/
-#define USER_HOST_BUFF_SIZE HOSTNAME_LENGTH + USERNAME_BYTE_LENGTH + 2
+#define USER_HOST_BUFF_SIZE HOSTNAME_LENGTH + USERNAME_LENGTH + 2
#define LOCAL_HOST "localhost"
#define LOCAL_HOST_NAMEDPIPE "."
@@ -141,11 +138,11 @@ enum enum_server_command
#define CLIENT_TRANSACTIONS 8192 /* Client knows about transactions */
#define CLIENT_RESERVED 16384 /* Old flag for 4.1 protocol */
#define CLIENT_SECURE_CONNECTION 32768 /* New 4.1 authentication */
-#define CLIENT_MULTI_STATEMENTS (((ulong) 1) << 16) /* Enable/disable multi-stmt support */
-#define CLIENT_MULTI_RESULTS (((ulong) 1) << 17) /* Enable/disable multi-results */
+#define CLIENT_MULTI_STATEMENTS (1UL << 16) /* Enable/disable multi-stmt support */
+#define CLIENT_MULTI_RESULTS (1UL << 17) /* Enable/disable multi-results */
-#define CLIENT_SSL_VERIFY_SERVER_CERT (((ulong) 1) << 30)
-#define CLIENT_REMEMBER_OPTIONS (((ulong) 1) << 31)
+#define CLIENT_SSL_VERIFY_SERVER_CERT (1UL << 30)
+#define CLIENT_REMEMBER_OPTIONS (1UL << 31)
#define SERVER_STATUS_IN_TRANS 1 /* Transaction has started */
#define SERVER_STATUS_AUTOCOMMIT 2 /* Server in auto_commit mode */
diff --git a/mysql-test/Makefile.am b/mysql-test/Makefile.am
index 61bac05b224..f0bc1e9b20a 100644
--- a/mysql-test/Makefile.am
+++ b/mysql-test/Makefile.am
@@ -22,14 +22,15 @@ DIST_SUBDIRS=ndb
benchdir_root= $(prefix)
testdir = $(benchdir_root)/mysql-test
-EXTRA_SCRIPTS = mysql-test-run.sh install_test_db.sh valgrind.supp $(PRESCRIPTS)
-EXTRA_DIST = $(EXTRA_SCRIPTS)
-GENSCRIPTS = mysql-test-run install_test_db mtr
+EXTRA_SCRIPTS = mysql-test-run-shell.sh install_test_db.sh \
+ valgrind.supp $(PRESCRIPTS)
+EXTRA_DIST = $(EXTRA_SCRIPTS)
+GENSCRIPTS = mysql-test-run-shell install_test_db mtr mysql-test-run
PRESCRIPTS = mysql-test-run.pl
test_SCRIPTS = $(GENSCRIPTS) $(PRESCRIPTS)
test_DATA = std_data/client-key.pem std_data/client-cert.pem \
std_data/cacert.pem std_data/server-cert.pem \
- std_data/server-key.pem
+ std_data/server-key.pem
CLEANFILES = $(GENSCRIPTS)
INCLUDES = -I$(top_builddir)/include -I$(top_srcdir)/include -I..
@@ -118,6 +119,11 @@ mtr:
$(RM) -f mtr
$(LN_S) mysql-test-run.pl mtr
+# mysql-test-run - a shortcut for executing mysql-test-run.pl
+mysql-test-run:
+ $(RM) -f mysql-test-run
+ $(LN_S) mysql-test-run.pl mysql-test-run
+
SUFFIXES = .sh
.sh:
diff --git a/mysql-test/extra/binlog_tests/binlog_insert_delayed.test b/mysql-test/extra/binlog_tests/binlog_insert_delayed.test
index 6f504fded96..4da883b9e60 100644
--- a/mysql-test/extra/binlog_tests/binlog_insert_delayed.test
+++ b/mysql-test/extra/binlog_tests/binlog_insert_delayed.test
@@ -4,25 +4,39 @@ create table t1 (a int not null auto_increment, primary key (a)) engine=myisam;
set @@session.auto_increment_increment=1, @@session.auto_increment_offset=1;
# Verify that only one INSERT_ID event is binlogged.
# Note, that because of WL#3368 mixed mode binlog records RBR events for the delayed
+let $table=t1;
+let $rows_inserted=11; # total number of inserted rows in this test
insert delayed into t1 values (207);
+let $count=1;
-# We use sleeps between statements, that's the only way to get a
-# repeatable binlog in a normal test run and under Valgrind. The
-# reason is that without sleeps, rows of different INSERT DELAYEDs
-# sometimes group together and sometimes not, so the table may be
-# unlocked/relocked causing a different number of table map log
-# events.
-sleep 2;
+# use this macro instead of sleeps.
+
+--source include/wait_until_rows_count.inc
insert delayed into t1 values (null);
-sleep 2;
+inc $count;
+--source include/wait_until_rows_count.inc
+
insert delayed into t1 values (300);
-sleep 2; # time for the delayed queries to reach disk
-insert delayed into t1 values (null),(null),(null),(null);
-sleep 2;
-insert delayed into t1 values (null),(null),(400),(null);
-sleep 2;
-select * from t1;
+inc $count;
+--source include/wait_until_rows_count.inc
+
+# moving binlog check affront of multi-rows queries which work is indeterministic (extra table_maps)
+# todo: better check is to substitute SHOW BINLOG with reading from binlog, probably bug#19459 is in
+# the way
--replace_column 2 # 5 #
--replace_regex /table_id: [0-9]+/table_id: #/
show binlog events from 102;
+
+insert delayed into t1 values (null),(null),(null),(null);
+inc $count; inc $count; inc $count; inc $count;
+--source include/wait_until_rows_count.inc
+
+insert delayed into t1 values (null),(null),(400),(null);
+inc $count; inc $count; inc $count; inc $count;
+--source include/wait_until_rows_count.inc
+
+#check this assertion about $count calculation
+--echo $count == $rows_inserted
+
+select * from t1;
drop table t1;
diff --git a/mysql-test/extra/rpl_tests/rpl_insert_id.test b/mysql-test/extra/rpl_tests/rpl_insert_id.test
index 1819c65c4e1..33194270d37 100644
--- a/mysql-test/extra/rpl_tests/rpl_insert_id.test
+++ b/mysql-test/extra/rpl_tests/rpl_insert_id.test
@@ -276,10 +276,156 @@ connection master;
drop table t1;
sync_slave_with_master;
+
+#
+# BUG#20339: stored procedure using LAST_INSERT_ID() does not
+# replicate statement-based.
+#
+# There is another version of the test for bug#20339 above that is
+# actually originates in 5.1, and this is the version that is merged
+# from 5.0.
+#
+connection master;
+
+--disable_warnings
+DROP PROCEDURE IF EXISTS p1;
+DROP TABLE IF EXISTS t1, t2;
+--enable_warnings
+
+# Reset result of LAST_INSERT_ID().
+SELECT LAST_INSERT_ID(0);
+
+CREATE TABLE t1 (
+ id INT NOT NULL DEFAULT 0,
+ last_id INT,
+ PRIMARY KEY (id)
+);
+
+CREATE TABLE t2 (
+ id INT NOT NULL AUTO_INCREMENT,
+ last_id INT,
+ PRIMARY KEY (id)
+);
+
+delimiter |;
+CREATE PROCEDURE p1()
+BEGIN
+ INSERT INTO t2 (last_id) VALUES (LAST_INSERT_ID());
+ INSERT INTO t1 (last_id) VALUES (LAST_INSERT_ID());
+END|
+delimiter ;|
+
+CALL p1();
+SELECT * FROM t1;
+SELECT * FROM t2;
+
+sync_slave_with_master;
+SELECT * FROM t1;
+SELECT * FROM t2;
+
+connection master;
+
+DROP PROCEDURE p1;
+DROP TABLE t1, t2;
+
+
+#
+# BUG#21726: Incorrect result with multiple invocations of
+# LAST_INSERT_ID
+#
+--disable_warnings
+DROP PROCEDURE IF EXISTS p1;
+DROP FUNCTION IF EXISTS f1;
+DROP FUNCTION IF EXISTS f2;
+DROP FUNCTION IF EXISTS f3;
+DROP TABLE IF EXISTS t1, t2;
+--enable_warnings
+
+CREATE TABLE t1 (
+ i INT NOT NULL AUTO_INCREMENT PRIMARY KEY,
+ j INT DEFAULT 0
+);
+CREATE TABLE t2 (i INT);
+
+delimiter |;
+CREATE PROCEDURE p1()
+BEGIN
+ INSERT INTO t1 (i) VALUES (NULL);
+ INSERT INTO t2 (i) VALUES (LAST_INSERT_ID());
+ INSERT INTO t1 (i) VALUES (NULL), (NULL);
+ INSERT INTO t2 (i) VALUES (LAST_INSERT_ID());
+END |
+
+CREATE FUNCTION f1() RETURNS INT MODIFIES SQL DATA
+BEGIN
+ INSERT INTO t1 (i) VALUES (NULL);
+ INSERT INTO t2 (i) VALUES (LAST_INSERT_ID());
+ INSERT INTO t1 (i) VALUES (NULL), (NULL);
+ INSERT INTO t2 (i) VALUES (LAST_INSERT_ID());
+ RETURN 0;
+END |
+
+CREATE FUNCTION f2() RETURNS INT NOT DETERMINISTIC
+ RETURN LAST_INSERT_ID() |
+
+CREATE FUNCTION f3() RETURNS INT MODIFIES SQL DATA
+BEGIN
+ INSERT INTO t2 (i) VALUES (LAST_INSERT_ID());
+ RETURN 0;
+END |
+delimiter ;|
+
+INSERT INTO t1 VALUES (NULL, -1);
+CALL p1();
+SELECT f1();
+INSERT INTO t1 VALUES (NULL, f2()), (NULL, LAST_INSERT_ID()),
+ (NULL, LAST_INSERT_ID()), (NULL, f2()), (NULL, f2());
+INSERT INTO t1 VALUES (NULL, f2());
+INSERT INTO t1 VALUES (NULL, LAST_INSERT_ID()), (NULL, LAST_INSERT_ID(5)),
+ (NULL, @@LAST_INSERT_ID);
+# Test replication of substitution "IS NULL" -> "= LAST_INSERT_ID".
+INSERT INTO t1 VALUES (NULL, 0), (NULL, LAST_INSERT_ID());
+UPDATE t1 SET j= -1 WHERE i IS NULL;
+
+# Test statement-based replication of function calls.
+INSERT INTO t1 (i) VALUES (NULL);
+
+connection master1;
+INSERT INTO t1 (i) VALUES (NULL);
+
+connection master;
+SELECT f3();
+
+SELECT * FROM t1;
+SELECT * FROM t2;
+
+sync_slave_with_master;
+SELECT * FROM t1;
+SELECT * FROM t2;
+
+connection master;
+DROP PROCEDURE p1;
+DROP FUNCTION f1;
+DROP FUNCTION f2;
+DROP FUNCTION f3;
+DROP TABLE t1, t2;
+
+
+sync_slave_with_master;
+
--echo #
--echo # End of 5.0 tests
--echo #
+# Tests in this file are tightly bound together. Recreate t2.
+connection master;
+create table t2 (
+ id int not null auto_increment,
+ last_id int,
+ primary key (id)
+);
+
+
# Test for BUG#20341 "stored function inserting into one
# auto_increment puts bad data in slave"
diff --git a/mysql-test/include/rpl_row_basic.inc b/mysql-test/extra/rpl_tests/rpl_row_basic.test
index ea2c4c1688c..ea2c4c1688c 100644
--- a/mysql-test/include/rpl_row_basic.inc
+++ b/mysql-test/extra/rpl_tests/rpl_row_basic.test
diff --git a/mysql-test/include/have_ndb.inc b/mysql-test/include/have_ndb.inc
index be339d41238..8cbeab07a4f 100644
--- a/mysql-test/include/have_ndb.inc
+++ b/mysql-test/include/have_ndb.inc
@@ -4,12 +4,4 @@ disable_query_log;
select support = 'Enabled' as `TRUE` from information_schema.engines where engine = 'ndbcluster';
enable_query_log;
-# Check that NDB is installed and known to be working
-# This will disable ndb from the shell script 'mysql-test-run'
-
--- require r/have_ndb_status_ok.require
-disable_query_log;
-eval select "$NDB_STATUS_OK" as ndb_status_ok;
-enable_query_log;
-
diff --git a/mysql-test/include/wait_until_connected_again.inc b/mysql-test/include/wait_until_connected_again.inc
index 5ae722e6db7..dc96f646cb3 100644
--- a/mysql-test/include/wait_until_connected_again.inc
+++ b/mysql-test/include/wait_until_connected_again.inc
@@ -3,7 +3,7 @@
# server has been restored or timeout occurs
--disable_result_log
--disable_query_log
-let $counter= 100;
+let $counter= 500;
while ($mysql_errno)
{
--error 0,2002,2006
diff --git a/mysql-test/include/wait_until_rows_count.inc b/mysql-test/include/wait_until_rows_count.inc
new file mode 100644
index 00000000000..cf2a21d335a
--- /dev/null
+++ b/mysql-test/include/wait_until_rows_count.inc
@@ -0,0 +1,52 @@
+# include/wait_until_rows_count.inc
+# inspired by wait_for_slave_status by Matthias Leich
+#
+# SUMMARY
+#
+# Waits until SELECT count(*)-$count from $table returns zero
+#
+# USAGE
+#
+# Set vars like
+# let $count=11;
+# let $table=t1;
+# # invoke the macro
+# --include wait_until_rows_count.inc
+#
+# EXAMPLE
+# extra/binlog/binlog_insert_delayed.test
+#
+#
+# TODO: generalize up to wait_[until|while] with arbitrary select or even query and
+# a condition to wait or get awakened
+# It's impossible to implement such a "most" general macro without
+# extending mysqltest. Just no way to pass a query as an argument and
+# evaluate it here, like eval "$quuery". One is bound
+# to specify it inside of the macro
+
+--disable_query_log
+
+let $wait_counter= 300; # max wait in 0.1 seconds
+while ($wait_counter)
+{
+ eval select count(*)-$count from $table into @rez;
+ let $rez=`select @rez`;
+ let $success=`SELECT @rez = 0`;
+ let $no_success=1;
+ if ($success)
+ {
+ let $wait_counter= 1; # droppping counter to leave loop
+ let $no_success=0;
+ }
+ if ($no_success)
+ {
+ --sleep 0.1
+ }
+ dec $wait_counter;
+}
+
+--enable_query_log
+if ($no_success)
+{
+ --die Timeout in wait_until_rows_count.inc, required table never had a prescribed number of rows.
+}
diff --git a/mysql-test/lib/mtr_cases.pl b/mysql-test/lib/mtr_cases.pl
index cfd07abb9e0..bb92730444c 100644
--- a/mysql-test/lib/mtr_cases.pl
+++ b/mysql-test/lib/mtr_cases.pl
@@ -62,7 +62,7 @@ sub collect_test_cases ($) {
foreach my $tname ( @::opt_cases ) { # Run in specified order, no sort
my $elem= undef;
my $component_id= undef;
-
+
# Get rid of directory part (path). Leave the extension since it is used
# to understand type of the test.
@@ -390,6 +390,7 @@ sub collect_one_test_case($$$$$$$) {
{
$tinfo->{'skip'}= 1;
$tinfo->{'comment'}= "No tests with sh scripts on Windows";
+ return;
}
else
{
@@ -404,6 +405,7 @@ sub collect_one_test_case($$$$$$$) {
{
$tinfo->{'skip'}= 1;
$tinfo->{'comment'}= "No tests with sh scripts on Windows";
+ return;
}
else
{
@@ -448,6 +450,7 @@ sub collect_one_test_case($$$$$$$) {
{
$tinfo->{'skip'}= 1;
$tinfo->{'disable'}= 1; # Sub type of 'skip'
+ return;
}
}
@@ -457,16 +460,19 @@ sub collect_one_test_case($$$$$$$) {
{
$tinfo->{'skip'}= 1;
$tinfo->{'comment'}= "No IM with embedded server";
+ return;
}
elsif ( $::opt_ps_protocol )
{
$tinfo->{'skip'}= 1;
$tinfo->{'comment'}= "No IM with --ps-protocol";
+ return;
}
elsif ( $::opt_skip_im )
{
$tinfo->{'skip'}= 1;
$tinfo->{'comment'}= "No IM tests(--skip-im)";
+ return;
}
}
else
@@ -477,18 +483,21 @@ sub collect_one_test_case($$$$$$$) {
{
$tinfo->{'skip'}= 1;
$tinfo->{'comment'}= "Test need 'big-test' option";
+ return;
}
if ( $tinfo->{'ndb_extra'} and ! $::opt_ndb_extra_test )
{
$tinfo->{'skip'}= 1;
$tinfo->{'comment'}= "Test need 'ndb_extra' option";
+ return;
}
if ( $tinfo->{'require_manager'} )
{
$tinfo->{'skip'}= 1;
$tinfo->{'comment'}= "Test need the _old_ manager(to be removed)";
+ return;
}
if ( defined $tinfo->{'binlog_format'} and
@@ -496,12 +505,14 @@ sub collect_one_test_case($$$$$$$) {
{
$tinfo->{'skip'}= 1;
$tinfo->{'comment'}= "Not running with binlog format '$tinfo->{'binlog_format'}'";
+ return;
}
if ( $tinfo->{'need_debug'} && ! $::debug_compiled_binaries )
{
$tinfo->{'skip'}= 1;
$tinfo->{'comment'}= "Test need debug binaries";
+ return;
}
}
@@ -512,6 +523,7 @@ sub collect_one_test_case($$$$$$$) {
{
$tinfo->{'skip'}= 1;
$tinfo->{'comment'}= "Can't restart a running server";
+ return;
}
}
@@ -538,8 +550,6 @@ sub mtr_options_from_test_file($$) {
while ( my $line= <$F> )
{
- chomp;
-
next if ( $line !~ /^--/ );
# Match this line against tag in "tags" array
diff --git a/mysql-test/lib/mtr_im.pl b/mysql-test/lib/mtr_im.pl
new file mode 100644
index 00000000000..ca17516278e
--- /dev/null
+++ b/mysql-test/lib/mtr_im.pl
@@ -0,0 +1,761 @@
+# -*- cperl -*-
+
+# This is a library file used by the Perl version of mysql-test-run,
+# and is part of the translation of the Bourne shell script with the
+# same name.
+
+use strict;
+
+# Private IM-related operations.
+
+sub mtr_im_kill_process ($$$$);
+sub mtr_im_load_pids ($);
+sub mtr_im_terminate ($);
+sub mtr_im_check_alive ($);
+sub mtr_im_check_main_alive ($);
+sub mtr_im_check_angel_alive ($);
+sub mtr_im_check_mysqlds_alive ($);
+sub mtr_im_check_mysqld_alive ($);
+sub mtr_im_cleanup ($);
+sub mtr_im_rm_file ($);
+sub mtr_im_errlog ($);
+sub mtr_im_kill ($);
+sub mtr_im_wait_for_connection ($$$);
+sub mtr_im_wait_for_mysqld($$$);
+
+# Public IM-related operations.
+
+sub mtr_im_start ($$);
+sub mtr_im_stop ($);
+
+##############################################################################
+#
+# Private operations.
+#
+##############################################################################
+
+sub mtr_im_kill_process ($$$$) {
+ my $pid_lst= shift;
+ my $signal= shift;
+ my $total_retries= shift;
+ my $timeout= shift;
+
+ my %pids;
+
+ foreach my $pid ( @{$pid_lst} )
+ {
+ $pids{$pid}= 1;
+ }
+
+ for ( my $cur_attempt= 1; $cur_attempt <= $total_retries; ++$cur_attempt )
+ {
+ foreach my $pid ( keys %pids )
+ {
+ mtr_debug("Sending $signal to $pid...");
+
+ kill($signal, $pid);
+
+ unless ( kill (0, $pid) )
+ {
+ mtr_debug("Process $pid died.");
+ delete $pids{$pid};
+ }
+ }
+
+ return if scalar keys %pids == 0;
+
+ mtr_debug("Sleeping $timeout second(s) waiting for processes to die...");
+
+ sleep($timeout);
+ }
+
+ mtr_debug("Process(es) " .
+ join(' ', keys %pids) .
+ " is still alive after $total_retries " .
+ "of sending signal $signal.");
+}
+
+###########################################################################
+
+sub mtr_im_load_pids($) {
+ my $im= shift;
+
+ mtr_debug("Loading PID files...");
+
+ # Obtain mysqld-process pids.
+
+ my $instances = $im->{'instances'};
+
+ for ( my $idx= 0; $idx < 2; ++$idx )
+ {
+ mtr_debug("IM-guarded mysqld[$idx] PID file: '" .
+ $instances->[$idx]->{'path_pid'} . "'.");
+
+ my $mysqld_pid;
+
+ if ( -r $instances->[$idx]->{'path_pid'} )
+ {
+ $mysqld_pid= mtr_get_pid_from_file($instances->[$idx]->{'path_pid'});
+ mtr_debug("IM-guarded mysqld[$idx] PID: $mysqld_pid.");
+ }
+ else
+ {
+ $mysqld_pid= undef;
+ mtr_debug("IM-guarded mysqld[$idx]: no PID file.");
+ }
+
+ $instances->[$idx]->{'pid'}= $mysqld_pid;
+ }
+
+ # Re-read Instance Manager PIDs from the file, since during tests Instance
+ # Manager could have been restarted, so its PIDs could have been changed.
+
+ # - IM-main
+
+ mtr_debug("IM-main PID file: '$im->{path_pid}'.");
+
+ if ( -f $im->{'path_pid'} )
+ {
+ $im->{'pid'} =
+ mtr_get_pid_from_file($im->{'path_pid'});
+
+ mtr_debug("IM-main PID: $im->{pid}.");
+ }
+ else
+ {
+ mtr_debug("IM-main: no PID file.");
+ $im->{'pid'}= undef;
+ }
+
+ # - IM-angel
+
+ mtr_debug("IM-angel PID file: '$im->{path_angel_pid}'.");
+
+ if ( -f $im->{'path_angel_pid'} )
+ {
+ $im->{'angel_pid'} =
+ mtr_get_pid_from_file($im->{'path_angel_pid'});
+
+ mtr_debug("IM-angel PID: $im->{'angel_pid'}.");
+ }
+ else
+ {
+ mtr_debug("IM-angel: no PID file.");
+ $im->{'angel_pid'} = undef;
+ }
+}
+
+###########################################################################
+
+sub mtr_im_terminate($) {
+ my $im= shift;
+
+ # Load pids from pid-files. We should do it first of all, because IM deletes
+ # them on shutdown.
+
+ mtr_im_load_pids($im);
+
+ mtr_debug("Shutting Instance Manager down...");
+
+ # Ignoring SIGCHLD so that all children could rest in peace.
+
+ start_reap_all();
+
+ # Send SIGTERM to IM-main.
+
+ if ( defined $im->{'pid'} )
+ {
+ mtr_debug("IM-main pid: $im->{pid}.");
+ mtr_debug("Stopping IM-main...");
+
+ mtr_im_kill_process([ $im->{'pid'} ], 'TERM', 10, 1);
+ }
+ else
+ {
+ mtr_debug("IM-main pid: n/a.");
+ }
+
+ # If IM-angel was alive, wait for it to die.
+
+ if ( defined $im->{'angel_pid'} )
+ {
+ mtr_debug("IM-angel pid: $im->{'angel_pid'}.");
+ mtr_debug("Waiting for IM-angel to die...");
+
+ my $total_attempts= 10;
+
+ for ( my $cur_attempt=1; $cur_attempt <= $total_attempts; ++$cur_attempt )
+ {
+ unless ( kill (0, $im->{'angel_pid'}) )
+ {
+ mtr_debug("IM-angel died.");
+ last;
+ }
+
+ sleep(1);
+ }
+ }
+ else
+ {
+ mtr_debug("IM-angel pid: n/a.");
+ }
+
+ stop_reap_all();
+
+ # Re-load PIDs.
+
+ mtr_im_load_pids($im);
+}
+
+###########################################################################
+
+sub mtr_im_check_alive($) {
+ my $im= shift;
+
+ mtr_debug("Checking whether IM-components are alive...");
+
+ return 1 if mtr_im_check_main_alive($im);
+
+ return 1 if mtr_im_check_angel_alive($im);
+
+ return 1 if mtr_im_check_mysqlds_alive($im);
+
+ return 0;
+}
+
+###########################################################################
+
+sub mtr_im_check_main_alive($) {
+ my $im= shift;
+
+ # Check that the process, that we know to be IM's, is dead.
+
+ if ( defined $im->{'pid'} )
+ {
+ if ( kill (0, $im->{'pid'}) )
+ {
+ mtr_debug("IM-main (PID: $im->{pid}) is alive.");
+ return 1;
+ }
+ else
+ {
+ mtr_debug("IM-main (PID: $im->{pid}) is dead.");
+ }
+ }
+ else
+ {
+ mtr_debug("No PID file for IM-main.");
+ }
+
+ # Check that IM does not accept client connections.
+
+ if ( mtr_ping_port($im->{'port'}) )
+ {
+ mtr_debug("IM-main (port: $im->{port}) " .
+ "is accepting connections.");
+
+ mtr_im_errlog("IM-main is accepting connections on port " .
+ "$im->{port}, but there is no " .
+ "process information.");
+ return 1;
+ }
+ else
+ {
+ mtr_debug("IM-main (port: $im->{port}) " .
+ "does not accept connections.");
+ return 0;
+ }
+}
+
+###########################################################################
+
+sub mtr_im_check_angel_alive($) {
+ my $im= shift;
+
+ # Check that the process, that we know to be the Angel, is dead.
+
+ if ( defined $im->{'angel_pid'} )
+ {
+ if ( kill (0, $im->{'angel_pid'}) )
+ {
+ mtr_debug("IM-angel (PID: $im->{angel_pid}) is alive.");
+ return 1;
+ }
+ else
+ {
+ mtr_debug("IM-angel (PID: $im->{angel_pid}) is dead.");
+ return 0;
+ }
+ }
+ else
+ {
+ mtr_debug("No PID file for IM-angel.");
+ return 0;
+ }
+}
+
+###########################################################################
+
+sub mtr_im_check_mysqlds_alive($) {
+ my $im= shift;
+
+ mtr_debug("Checking for IM-guarded mysqld instances...");
+
+ my $instances = $im->{'instances'};
+
+ for ( my $idx= 0; $idx < 2; ++$idx )
+ {
+ mtr_debug("Checking mysqld[$idx]...");
+
+ return 1
+ if mtr_im_check_mysqld_alive($instances->[$idx]);
+ }
+}
+
+###########################################################################
+
+sub mtr_im_check_mysqld_alive($) {
+ my $mysqld_instance= shift;
+
+ # Check that the process is dead.
+
+ if ( defined $mysqld_instance->{'pid'} )
+ {
+ if ( kill (0, $mysqld_instance->{'pid'}) )
+ {
+ mtr_debug("Mysqld instance (PID: $mysqld_instance->{pid}) is alive.");
+ return 1;
+ }
+ else
+ {
+ mtr_debug("Mysqld instance (PID: $mysqld_instance->{pid}) is dead.");
+ }
+ }
+ else
+ {
+ mtr_debug("No PID file for mysqld instance.");
+ }
+
+ # Check that mysqld does not accept client connections.
+
+ if ( mtr_ping_port($mysqld_instance->{'port'}) )
+ {
+ mtr_debug("Mysqld instance (port: $mysqld_instance->{port}) " .
+ "is accepting connections.");
+
+ mtr_im_errlog("Mysqld is accepting connections on port " .
+ "$mysqld_instance->{port}, but there is no " .
+ "process information.");
+ return 1;
+ }
+ else
+ {
+ mtr_debug("Mysqld instance (port: $mysqld_instance->{port}) " .
+ "does not accept connections.");
+ return 0;
+ }
+}
+
+###########################################################################
+
+sub mtr_im_cleanup($) {
+ my $im= shift;
+
+ mtr_im_rm_file($im->{'path_pid'});
+ mtr_im_rm_file($im->{'path_sock'});
+
+ mtr_im_rm_file($im->{'path_angel_pid'});
+
+ for ( my $idx= 0; $idx < 2; ++$idx )
+ {
+ mtr_im_rm_file($im->{'instances'}->[$idx]->{'path_pid'});
+ mtr_im_rm_file($im->{'instances'}->[$idx]->{'path_sock'});
+ }
+}
+
+###########################################################################
+
+sub mtr_im_rm_file($)
+{
+ my $file_path= shift;
+
+ if ( -f $file_path )
+ {
+ mtr_debug("Removing '$file_path'...");
+
+ unless ( unlink($file_path) )
+ {
+ mtr_warning("Can not remove '$file_path'.")
+ }
+ }
+ else
+ {
+ mtr_debug("File '$file_path' does not exist already.");
+ }
+}
+
+###########################################################################
+
+sub mtr_im_errlog($) {
+ my $msg= shift;
+
+ # Complain in error log so that a warning will be shown.
+ #
+ # TODO: unless BUG#20761 is fixed, we will print the warning to stdout, so
+ # that it can be seen on console and does not produce pushbuild error.
+
+ # 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] $msg\n";
+ #
+ # close ERRLOG;
+
+ my $ts= localtime();
+ print "Warning: [$ts] $msg\n";
+}
+
+###########################################################################
+
+sub mtr_im_kill($) {
+ my $im= shift;
+
+ # Re-load PIDs. That can be useful because some processes could have been
+ # restarted.
+
+ mtr_im_load_pids($im);
+
+ # Ignoring SIGCHLD so that all children could rest in peace.
+
+ start_reap_all();
+
+ # Kill IM-angel first of all.
+
+ if ( defined $im->{'angel_pid'} )
+ {
+ mtr_debug("Killing IM-angel (PID: $im->{angel_pid})...");
+ mtr_im_kill_process([ $im->{'angel_pid'} ], 'KILL', 10, 1)
+ }
+ else
+ {
+ mtr_debug("IM-angel is dead.");
+ }
+
+ # Re-load PIDs again.
+
+ mtr_im_load_pids($im);
+
+ # Kill IM-main.
+
+ if ( defined $im->{'pid'} )
+ {
+ mtr_debug("Killing IM-main (PID: $im->pid})...");
+ mtr_im_kill_process([ $im->{'pid'} ], 'KILL', 10, 1);
+ }
+ else
+ {
+ mtr_debug("IM-main is dead.");
+ }
+
+ # Re-load PIDs again.
+
+ mtr_im_load_pids($im);
+
+ # Kill guarded mysqld instances.
+
+ my @mysqld_pids;
+
+ mtr_debug("Collecting PIDs of mysqld instances to kill...");
+
+ for ( my $idx= 0; $idx < 2; ++$idx )
+ {
+ my $pid= $im->{'instances'}->[$idx]->{'pid'};
+
+ unless ( defined $pid )
+ {
+ next;
+ }
+
+ mtr_debug(" - IM-guarded mysqld[$idx] PID: $pid.");
+
+ push (@mysqld_pids, $pid);
+ }
+
+ if ( scalar @mysqld_pids > 0 )
+ {
+ mtr_debug("Killing IM-guarded mysqld instances...");
+ mtr_im_kill_process(\@mysqld_pids, 'KILL', 10, 1);
+ }
+
+ # That's all.
+
+ stop_reap_all();
+}
+
+##############################################################################
+
+sub mtr_im_wait_for_connection($$$) {
+ my $im= shift;
+ my $total_attempts= shift;
+ my $connect_timeout= shift;
+
+ mtr_debug("Waiting for IM on port $im->{port} " .
+ "to start accepting connections...");
+
+ for ( my $cur_attempt= 1; $cur_attempt <= $total_attempts; ++$cur_attempt )
+ {
+ mtr_debug("Trying to connect to IM ($cur_attempt of $total_attempts)...");
+
+ if ( mtr_ping_port($im->{'port'}) )
+ {
+ mtr_debug("IM is accepting connections " .
+ "on port $im->{port}.");
+ return 1;
+ }
+
+ mtr_debug("Sleeping $connect_timeout...");
+ sleep($connect_timeout);
+ }
+
+ mtr_debug("IM does not accept connections " .
+ "on port $im->{port} after " .
+ ($total_attempts * $connect_timeout) . " seconds.");
+
+ return 0;
+}
+
+##############################################################################
+
+sub mtr_im_wait_for_mysqld($$$) {
+ my $mysqld= shift;
+ my $total_attempts= shift;
+ my $connect_timeout= shift;
+
+ mtr_debug("Waiting for IM-guarded mysqld on port $mysqld->{port} " .
+ "to start accepting connections...");
+
+ for ( my $cur_attempt= 1; $cur_attempt <= $total_attempts; ++$cur_attempt )
+ {
+ mtr_debug("Trying to connect to mysqld " .
+ "($cur_attempt of $total_attempts)...");
+
+ if ( mtr_ping_port($mysqld->{'port'}) )
+ {
+ mtr_debug("Mysqld is accepting connections " .
+ "on port $mysqld->{port}.");
+ return 1;
+ }
+
+ mtr_debug("Sleeping $connect_timeout...");
+ sleep($connect_timeout);
+ }
+
+ mtr_debug("Mysqld does not accept connections " .
+ "on port $mysqld->{port} after " .
+ ($total_attempts * $connect_timeout) . " seconds.");
+
+ return 0;
+}
+
+##############################################################################
+#
+# Public operations.
+#
+##############################################################################
+
+sub mtr_im_start($$) {
+ my $im = shift;
+ my $opts = shift;
+
+ mtr_debug("Starting Instance Manager...");
+
+ my $args;
+ mtr_init_args(\$args);
+ mtr_add_arg($args, "--defaults-file=%s", $im->{'defaults_file'});
+
+ foreach my $opt ( @{$opts} )
+ {
+ mtr_add_arg($args, $opt);
+ }
+
+ $im->{'pid'} =
+ mtr_spawn(
+ $::exe_im, # path to the executable
+ $args, # cmd-line args
+ '', # stdin
+ $im->{'path_log'}, # stdout
+ $im->{'path_err'}, # stderr
+ '', # pid file path (not used)
+ { append_log_file => 1 } # append log files
+ );
+
+ unless ( $im->{'pid'} )
+ {
+ mtr_error('Could not start Instance Manager.')
+ }
+
+ # Instance Manager can be run in daemon mode. In this case, it creates
+ # several processes and the parent process, created by mtr_spawn(), exits just
+ # after start. So, we have to obtain Instance Manager PID from the PID file.
+
+ mtr_debug("Waiting for IM to create PID file (" .
+ "path: '$im->{path_pid}'; " .
+ "timeout: $im->{start_timeout})...");
+
+ unless ( sleep_until_file_created($im->{'path_pid'},
+ $im->{'start_timeout'},
+ -1) ) # real PID is still unknown
+ {
+ mtr_debug("IM has not created PID file in $im->{start_timeout} secs.");
+ mtr_debug("Aborting test suite...");
+
+ mtr_kill_leftovers();
+
+ mtr_report("IM has not created PID file in $im->{start_timeout} secs.");
+ return 0;
+ }
+
+ $im->{'pid'}= mtr_get_pid_from_file($im->{'path_pid'});
+
+ mtr_debug("Instance Manager started. PID: $im->{pid}.");
+
+ # Wait until we can connect to IM.
+
+ my $IM_CONNECT_TIMEOUT= 30;
+
+ unless ( mtr_im_wait_for_connection($im,
+ $IM_CONNECT_TIMEOUT, 1) )
+ {
+ mtr_debug("Can not connect to Instance Manager " .
+ "in $IM_CONNECT_TIMEOUT seconds after start.");
+ mtr_debug("Aborting test suite...");
+
+ mtr_kill_leftovers();
+
+ mtr_report("Can not connect to Instance Manager " .
+ "in $IM_CONNECT_TIMEOUT seconds after start.");
+ return 0;
+ }
+
+ # Wait for IM to start guarded instances:
+ # - wait for PID files;
+
+ mtr_debug("Waiting for guarded mysqlds instances to create PID files...");
+
+ for ( my $idx= 0; $idx < 2; ++$idx )
+ {
+ my $mysqld= $im->{'instances'}->[$idx];
+
+ if ( exists $mysqld->{'nonguarded'} )
+ {
+ next;
+ }
+
+ mtr_debug("Waiting for mysqld[$idx] to create PID file (" .
+ "path: '$mysqld->{path_pid}'; " .
+ "timeout: $mysqld->{start_timeout})...");
+
+ unless ( sleep_until_file_created($mysqld->{'path_pid'},
+ $mysqld->{'start_timeout'},
+ -1) ) # real PID is still unknown
+ {
+ mtr_debug("mysqld[$idx] has not created PID file in " .
+ "$mysqld->{start_timeout} secs.");
+ mtr_debug("Aborting test suite...");
+
+ mtr_kill_leftovers();
+
+ mtr_report("mysqld[$idx] has not created PID file in " .
+ "$mysqld->{start_timeout} secs.");
+ return 0;
+ }
+
+ mtr_debug("PID file for mysqld[$idx] ($mysqld->{path_pid} created.");
+ }
+
+ # Wait until we can connect to guarded mysqld-instances
+ # (in other words -- wait for IM to start guarded instances).
+
+ mtr_debug("Waiting for guarded mysqlds to start accepting connections...");
+
+ for ( my $idx= 0; $idx < 2; ++$idx )
+ {
+ my $mysqld= $im->{'instances'}->[$idx];
+
+ if ( exists $mysqld->{'nonguarded'} )
+ {
+ next;
+ }
+
+ mtr_debug("Waiting for mysqld[$idx] to accept connection...");
+
+ unless ( mtr_im_wait_for_mysqld($mysqld, 30, 1) )
+ {
+ mtr_debug("Can not connect to mysqld[$idx] " .
+ "in $IM_CONNECT_TIMEOUT seconds after start.");
+ mtr_debug("Aborting test suite...");
+
+ mtr_kill_leftovers();
+
+ mtr_report("Can not connect to mysqld[$idx] " .
+ "in $IM_CONNECT_TIMEOUT seconds after start.");
+ return 0;
+ }
+
+ mtr_debug("mysqld[$idx] started.");
+ }
+
+ mtr_debug("Instance Manager and its components are up and running.");
+
+ return 1;
+}
+
+##############################################################################
+
+sub mtr_im_stop($) {
+ my $im= shift;
+
+ mtr_debug("Stopping Instance Manager...");
+
+ # Try graceful shutdown.
+
+ mtr_im_terminate($im);
+
+ # Check that all processes died.
+
+ unless ( mtr_im_check_alive($im) )
+ {
+ mtr_debug("Instance Manager has been stopped successfully.");
+ mtr_im_cleanup($im);
+ return 1;
+ }
+
+ # Instance Manager don't want to die. We should kill it.
+
+ mtr_im_errlog("Instance Manager did not shutdown gracefully.");
+
+ mtr_im_kill($im);
+
+ # Check again that all IM-related processes have been killed.
+
+ my $im_is_alive= mtr_im_check_alive($im);
+
+ mtr_im_cleanup($im);
+
+ if ( $im_is_alive )
+ {
+ mtr_debug("Can not kill Instance Manager or its children.");
+ return 0;
+ }
+
+ mtr_debug("Instance Manager has been killed successfully.");
+ return 1;
+}
+
+###########################################################################
+
+1;
diff --git a/mysql-test/lib/mtr_process.pl b/mysql-test/lib/mtr_process.pl
index ab2af8c4ccf..868b6d4f1ec 100644
--- a/mysql-test/lib/mtr_process.pl
+++ b/mysql-test/lib/mtr_process.pl
@@ -26,28 +26,6 @@ sub mtr_kill_processes ($);
sub mtr_ping_with_timeout($);
sub mtr_ping_port ($);
-# Private IM-related operations.
-
-sub mtr_im_kill_process ($$$);
-sub mtr_im_load_pids ($);
-sub mtr_im_terminate ($);
-sub mtr_im_check_alive ($);
-sub mtr_im_check_main_alive ($);
-sub mtr_im_check_angel_alive ($);
-sub mtr_im_check_mysqlds_alive ($);
-sub mtr_im_check_mysqld_alive ($$);
-sub mtr_im_cleanup ($);
-sub mtr_im_rm_file ($);
-sub mtr_im_errlog ($);
-sub mtr_im_kill ($);
-sub mtr_im_wait_for_connection ($$$);
-sub mtr_im_wait_for_mysqld($$$);
-
-# Public IM-related operations.
-
-sub mtr_im_start ($$);
-sub mtr_im_stop ($$);
-
# static in C
sub spawn_impl ($$$$$$$$);
@@ -358,9 +336,16 @@ sub mtr_process_exit_status {
# kill IM manager first, else it will restart the servers
sub mtr_kill_leftovers () {
+ mtr_report("Killing Possible Leftover Processes");
mtr_debug("mtr_kill_leftovers(): started.");
- mtr_im_stop($::instance_manager, 'mtr_kill_leftovers');
+ mkpath("$::opt_vardir/log"); # Needed for mysqladmin log
+
+ # Stop or kill Instance Manager and all its children. If we failed to do
+ # that, we can only abort -- there is nothing left to do.
+
+ mtr_error("Failed to stop Instance Manager.")
+ unless mtr_im_stop($::instance_manager);
# Start shutdown of masters and slaves. Don't touch IM-managed mysqld
# instances -- they should be stopped by mtr_im_stop().
@@ -476,14 +461,6 @@ sub mtr_kill_leftovers () {
mtr_debug("Got pid: $pid from file '$pidfile'");
- # Race, could have been removed between I tested with -f
- # and the unlink() below, so I better check again with -f
-
- if ( ! unlink($pidfile) and -f $pidfile )
- {
- mtr_error("can't remove $pidfile");
- }
-
if ( $::glob_cygwin_perl or kill(0, $pid) )
{
mtr_debug("There is process with pid $pid -- scheduling for kill.");
@@ -1103,7 +1080,7 @@ sub mtr_kill_processes ($) {
{
foreach my $sig (15, 9)
{
- last if mtr_im_kill_process([ $pid ], $sig, 10);
+ last if mtr_im_kill_process([ $pid ], $sig, 10, 1);
}
}
}
@@ -1138,679 +1115,6 @@ sub mtr_exit ($) {
exit($code);
}
-##############################################################################
-#
-# Instance Manager management routines.
-#
-##############################################################################
-
-sub mtr_im_kill_process ($$$) {
- my $pid_lst= shift;
- my $signal= shift;
- my $timeout= shift;
- my $total_attempts= $timeout * 10;
-
- my %pids;
-
- foreach my $pid (@{$pid_lst})
- {
- $pids{$pid}= 1;
- }
-
- for (my $cur_attempt= 1; $cur_attempt <= $total_attempts; ++$cur_attempt)
- {
- foreach my $pid (keys %pids)
- {
- mtr_debug("Sending $signal to $pid...");
-
- kill($signal, $pid);
-
- unless (kill (0, $pid))
- {
- mtr_debug("Process $pid died.");
- delete $pids{$pid};
- }
- }
-
- return if scalar keys %pids == 0;
-
- mtr_debug("Sleeping 100ms waiting for processes to die...");
-
- select(undef, undef, undef, 0.1);
- }
-
- mtr_debug("Process(es) " .
- join(' ', keys %pids) .
- " is still alive after $total_attempts " .
- "of sending signal $signal.");
-}
-
-###########################################################################
-
-sub mtr_im_load_pids($) {
- my $instance_manager= shift;
-
- mtr_debug("Loading PID files...");
-
- # Obtain mysqld-process pids.
-
- my $instances = $instance_manager->{'instances'};
-
- for (my $idx= 0; $idx < 2; ++$idx)
- {
- mtr_debug("IM-guarded mysqld[$idx] PID file: '" .
- $instances->[$idx]->{'path_pid'} . "'.");
-
- my $mysqld_pid;
-
- if (-r $instances->[$idx]->{'path_pid'})
- {
- $mysqld_pid= mtr_get_pid_from_file($instances->[$idx]->{'path_pid'});
- mtr_debug("IM-guarded mysqld[$idx] PID: $mysqld_pid.");
- }
- else
- {
- $mysqld_pid= undef;
- mtr_debug("IM-guarded mysqld[$idx]: no PID file.");
- }
-
- $instances->[$idx]->{'pid'}= $mysqld_pid;
- }
-
- # Re-read Instance Manager PIDs from the file, since during tests Instance
- # Manager could have been restarted, so its PIDs could have been changed.
-
- # - IM-main
-
- mtr_debug("IM-main PID file: '$instance_manager->{path_pid}'.");
-
- if (-f $instance_manager->{'path_pid'})
- {
- $instance_manager->{'pid'} =
- mtr_get_pid_from_file($instance_manager->{'path_pid'});
-
- mtr_debug("IM-main PID: $instance_manager->{pid}.");
- }
- else
- {
- mtr_debug("IM-main: no PID file.");
- $instance_manager->{'pid'}= undef;
- }
-
- # - IM-angel
-
- mtr_debug("IM-angel PID file: '$instance_manager->{path_angel_pid}'.");
-
- if (-f $instance_manager->{'path_angel_pid'})
- {
- $instance_manager->{'angel_pid'} =
- mtr_get_pid_from_file($instance_manager->{'path_angel_pid'});
-
- mtr_debug("IM-angel PID: $instance_manager->{'angel_pid'}.");
- }
- else
- {
- mtr_debug("IM-angel: no PID file.");
- $instance_manager->{'angel_pid'} = undef;
- }
-}
-
-###########################################################################
-
-sub mtr_im_terminate($) {
- my $instance_manager= shift;
-
- # Load pids from pid-files. We should do it first of all, because IM deletes
- # them on shutdown.
-
- mtr_im_load_pids($instance_manager);
-
- mtr_debug("Shutting Instance Manager down...");
-
- # Ignoring SIGCHLD so that all children could rest in peace.
-
- start_reap_all();
-
- # Send SIGTERM to IM-main.
-
- if (defined $instance_manager->{'pid'})
- {
- mtr_debug("IM-main pid: $instance_manager->{pid}.");
- mtr_debug("Stopping IM-main...");
-
- mtr_im_kill_process([ $instance_manager->{'pid'} ], 'TERM', 10);
- }
- else
- {
- mtr_debug("IM-main pid: n/a.");
- }
-
- # If IM-angel was alive, wait for it to die.
-
- if (defined $instance_manager->{'angel_pid'})
- {
- mtr_debug("IM-angel pid: $instance_manager->{'angel_pid'}.");
- mtr_debug("Waiting for IM-angel to die...");
-
- my $total_attempts= 10;
-
- for (my $cur_attempt=1; $cur_attempt <= $total_attempts; ++$cur_attempt)
- {
- unless (kill (0, $instance_manager->{'angel_pid'}))
- {
- mtr_debug("IM-angel died.");
- last;
- }
-
- sleep(1);
- }
- }
- else
- {
- mtr_debug("IM-angel pid: n/a.");
- }
-
- stop_reap_all();
-
- # Re-load PIDs.
-
- mtr_im_load_pids($instance_manager);
-}
-
-###########################################################################
-
-sub mtr_im_check_alive($) {
- my $instance_manager= shift;
-
- mtr_debug("Checking whether IM-components are alive...");
-
- return 1 if mtr_im_check_main_alive($instance_manager);
-
- return 1 if mtr_im_check_angel_alive($instance_manager);
-
- return 1 if mtr_im_check_mysqlds_alive($instance_manager);
-
- return 0;
-}
-
-###########################################################################
-
-sub mtr_im_check_main_alive($) {
- my $instance_manager= shift;
-
- # Check that the process, that we know to be IM's, is dead.
-
- if (defined $instance_manager->{'pid'})
- {
- if (kill (0, $instance_manager->{'pid'}))
- {
- mtr_debug("IM-main (PID: $instance_manager->{pid}) is alive.");
- return 1;
- }
- else
- {
- mtr_debug("IM-main (PID: $instance_manager->{pid}) is dead.");
- }
- }
- else
- {
- mtr_debug("No PID file for IM-main.");
- }
-
- # Check that IM does not accept client connections.
-
- if (mtr_ping_port($instance_manager->{'port'}))
- {
- mtr_debug("IM-main (port: $instance_manager->{port}) " .
- "is accepting connections.");
-
- mtr_im_errlog("IM-main is accepting connections on port " .
- "$instance_manager->{port}, but there is no " .
- "process information.");
- return 1;
- }
- else
- {
- mtr_debug("IM-main (port: $instance_manager->{port}) " .
- "does not accept connections.");
- return 0;
- }
-}
-
-###########################################################################
-
-sub mtr_im_check_angel_alive($) {
- my $instance_manager= shift;
-
- # Check that the process, that we know to be the Angel, is dead.
-
- if (defined $instance_manager->{'angel_pid'})
- {
- if (kill (0, $instance_manager->{'angel_pid'}))
- {
- mtr_debug("IM-angel (PID: $instance_manager->{angel_pid}) is alive.");
- return 1;
- }
- else
- {
- mtr_debug("IM-angel (PID: $instance_manager->{angel_pid}) is dead.");
- return 0;
- }
- }
- else
- {
- mtr_debug("No PID file for IM-angel.");
- return 0;
- }
-}
-
-###########################################################################
-
-sub mtr_im_check_mysqlds_alive($) {
- my $instance_manager= shift;
-
- mtr_debug("Checking for IM-guarded mysqld instances...");
-
- my $instances = $instance_manager->{'instances'};
-
- for (my $idx= 0; $idx < 2; ++$idx)
- {
- mtr_debug("Checking mysqld[$idx]...");
-
- return 1
- if mtr_im_check_mysqld_alive($instance_manager, $instances->[$idx]);
- }
-}
-
-###########################################################################
-
-sub mtr_im_check_mysqld_alive($$) {
- my $instance_manager= shift;
- my $mysqld_instance= shift;
-
- # Check that the process is dead.
-
- if (defined $instance_manager->{'pid'})
- {
- if (kill (0, $instance_manager->{'pid'}))
- {
- mtr_debug("Mysqld instance (PID: $mysqld_instance->{pid}) is alive.");
- return 1;
- }
- else
- {
- mtr_debug("Mysqld instance (PID: $mysqld_instance->{pid}) is dead.");
- }
- }
- else
- {
- mtr_debug("No PID file for mysqld instance.");
- }
-
- # Check that mysqld does not accept client connections.
-
- if (mtr_ping_port($mysqld_instance->{'port'}))
- {
- mtr_debug("Mysqld instance (port: $mysqld_instance->{port}) " .
- "is accepting connections.");
-
- mtr_im_errlog("Mysqld is accepting connections on port " .
- "$mysqld_instance->{port}, but there is no " .
- "process information.");
- return 1;
- }
- else
- {
- mtr_debug("Mysqld instance (port: $mysqld_instance->{port}) " .
- "does not accept connections.");
- return 0;
- }
-}
-
-###########################################################################
-
-sub mtr_im_cleanup($) {
- my $instance_manager= shift;
-
- mtr_im_rm_file($instance_manager->{'path_pid'});
- mtr_im_rm_file($instance_manager->{'path_sock'});
-
- mtr_im_rm_file($instance_manager->{'path_angel_pid'});
-
- for (my $idx= 0; $idx < 2; ++$idx)
- {
- mtr_im_rm_file($instance_manager->{'instances'}->[$idx]->{'path_pid'});
- mtr_im_rm_file($instance_manager->{'instances'}->[$idx]->{'path_sock'});
- }
-}
-
-###########################################################################
-
-sub mtr_im_rm_file($)
-{
- my $file_path= shift;
-
- if (-f $file_path)
- {
- mtr_debug("Removing '$file_path'...");
-
- mtr_warning("Can not remove '$file_path'.")
- unless unlink($file_path);
- }
- else
- {
- mtr_debug("File '$file_path' does not exist already.");
- }
-}
-
-###########################################################################
-
-sub mtr_im_errlog($) {
- my $msg= shift;
-
- # Complain in error log so that a warning will be shown.
- #
- # TODO: unless BUG#20761 is fixed, we will print the warning to stdout, so
- # that it can be seen on console and does not produce pushbuild error.
-
- # 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] $msg\n";
- #
- # close ERRLOG;
-
- my $ts= localtime();
- print "Warning: [$ts] $msg\n";
-}
-
-###########################################################################
-
-sub mtr_im_kill($) {
- my $instance_manager= shift;
-
- # Re-load PIDs. That can be useful because some processes could have been
- # restarted.
-
- mtr_im_load_pids($instance_manager);
-
- # Ignoring SIGCHLD so that all children could rest in peace.
-
- start_reap_all();
-
- # Kill IM-angel first of all.
-
- if (defined $instance_manager->{'angel_pid'})
- {
- mtr_debug("Killing IM-angel (PID: $instance_manager->{angel_pid})...");
- mtr_im_kill_process([ $instance_manager->{'angel_pid'} ], 'KILL', 10);
- }
- else
- {
- mtr_debug("IM-angel is dead.");
- }
-
- # Re-load PIDs again.
-
- mtr_im_load_pids($instance_manager);
-
- # Kill IM-main.
-
- if (defined $instance_manager->{'pid'})
- {
- mtr_debug("Killing IM-main (PID: $instance_manager->pid})...");
- mtr_im_kill_process([ $instance_manager->{'pid'} ], 'KILL', 10);
- }
- else
- {
- mtr_debug("IM-main is dead.");
- }
-
- # Re-load PIDs again.
-
- mtr_im_load_pids($instance_manager);
-
- # Kill guarded mysqld instances.
-
- my @mysqld_pids;
-
- mtr_debug("Collecting PIDs of mysqld instances to kill...");
-
- for (my $idx= 0; $idx < 2; ++$idx)
- {
- my $pid= $instance_manager->{'instances'}->[$idx]->{'pid'};
-
- next unless defined $pid;
-
- mtr_debug(" - IM-guarded mysqld[$idx] PID: $pid.");
-
- push (@mysqld_pids, $pid);
- }
-
- if (scalar @mysqld_pids > 0)
- {
- mtr_debug("Killing IM-guarded mysqld instances...");
- mtr_im_kill_process(\@mysqld_pids, 'KILL', 10);
- }
-
- # That's all.
-
- stop_reap_all();
-}
-
-##############################################################################
-
-sub mtr_im_wait_for_connection($$$) {
- my $instance_manager= shift;
- my $total_attempts= shift;
- my $connect_timeout= shift;
-
- mtr_debug("Waiting for IM on port $instance_manager->{port} " .
- "to start accepting connections...");
-
- for (my $cur_attempt= 1; $cur_attempt <= $total_attempts; ++$cur_attempt)
- {
- mtr_debug("Trying to connect to IM ($cur_attempt of $total_attempts)...");
-
- if (mtr_ping_port($instance_manager->{'port'}))
- {
- mtr_debug("IM is accepting connections " .
- "on port $instance_manager->{port}.");
- return 1;
- }
-
- mtr_debug("Sleeping $connect_timeout...");
- sleep($connect_timeout);
- }
-
- mtr_debug("IM does not accept connections " .
- "on port $instance_manager->{port} after " .
- ($total_attempts * $connect_timeout) . " seconds.");
-
- return 0;
-}
-
-##############################################################################
-
-sub mtr_im_wait_for_mysqld($$$) {
- my $mysqld= shift;
- my $total_attempts= shift;
- my $connect_timeout= shift;
-
- mtr_debug("Waiting for IM-guarded mysqld on port $mysqld->{port} " .
- "to start accepting connections...");
-
- for (my $cur_attempt= 1; $cur_attempt <= $total_attempts; ++$cur_attempt)
- {
- mtr_debug("Trying to connect to mysqld " .
- "($cur_attempt of $total_attempts)...");
-
- if (mtr_ping_port($mysqld->{'port'}))
- {
- mtr_debug("Mysqld is accepting connections " .
- "on port $mysqld->{port}.");
- return 1;
- }
-
- mtr_debug("Sleeping $connect_timeout...");
- sleep($connect_timeout);
- }
-
- mtr_debug("Mysqld does not accept connections " .
- "on port $mysqld->{port} after " .
- ($total_attempts * $connect_timeout) . " seconds.");
-
- return 0;
-}
-
-##############################################################################
-
-sub mtr_im_start($$) {
- my $instance_manager = shift;
- my $opts = shift;
-
- mtr_debug("Starting Instance Manager...");
-
- my $args;
- mtr_init_args(\$args);
- mtr_add_arg($args, "--defaults-file=%s",
- $instance_manager->{'defaults_file'});
-
- foreach my $opt (@{$opts})
- {
- mtr_add_arg($args, $opt);
- }
-
- $instance_manager->{'pid'} =
- mtr_spawn(
- $::exe_im, # path to the executable
- $args, # cmd-line args
- '', # stdin
- $instance_manager->{'path_log'}, # stdout
- $instance_manager->{'path_err'}, # stderr
- '', # pid file path (not used)
- { append_log_file => 1 } # append log files
- );
-
- if ( ! $instance_manager->{'pid'} )
- {
- mtr_report('Could not start Instance Manager');
- return;
- }
-
- # Instance Manager can be run in daemon mode. In this case, it creates
- # several processes and the parent process, created by mtr_spawn(), exits just
- # after start. So, we have to obtain Instance Manager PID from the PID file.
-
- if ( ! sleep_until_file_created(
- $instance_manager->{'path_pid'},
- $instance_manager->{'start_timeout'},
- -1)) # real PID is still unknown
- {
- mtr_report("Instance Manager PID file is missing");
- return;
- }
-
- $instance_manager->{'pid'} =
- mtr_get_pid_from_file($instance_manager->{'path_pid'});
-
- mtr_debug("Instance Manager started. PID: $instance_manager->{pid}.");
-
- # Wait until we can connect to IM.
-
- my $IM_CONNECT_TIMEOUT= 30;
-
- unless (mtr_im_wait_for_connection($instance_manager,
- $IM_CONNECT_TIMEOUT, 1))
- {
- mtr_debug("Can not connect to Instance Manager " .
- "in $IM_CONNECT_TIMEOUT seconds after start.");
- mtr_debug("Aborting test suite...");
-
- mtr_kill_leftovers();
-
- mtr_error("Can not connect to Instance Manager " .
- "in $IM_CONNECT_TIMEOUT seconds after start.");
- }
-
- # Wait until we can connect to guarded mysqld-instances
- # (in other words -- wait for IM to start guarded instances).
-
- for (my $idx= 0; $idx < 2; ++$idx)
- {
- my $mysqld= $instance_manager->{'instances'}->[$idx];
-
- next if exists $mysqld->{'nonguarded'};
-
- mtr_debug("Waiting for mysqld[$idx] to start...");
-
- unless (mtr_im_wait_for_mysqld($mysqld, 30, 1))
- {
- mtr_debug("Can not connect to mysqld[$idx] " .
- "in $IM_CONNECT_TIMEOUT seconds after start.");
- mtr_debug("Aborting test suite...");
-
- mtr_kill_leftovers();
-
- mtr_error("Can not connect to mysqld[$idx] " .
- "in $IM_CONNECT_TIMEOUT seconds after start.");
- }
-
- mtr_debug("mysqld[$idx] started.");
- }
-
- mtr_debug("Instance Manager started.");
-
- mtr_im_load_pids($instance_manager);
-}
-
-##############################################################################
-
-sub mtr_im_stop($$) {
- my $instance_manager= shift;
- my $where= shift;
-
- mtr_debug("Stopping Instance Manager...");
-
- # Try graceful shutdown.
-
- mtr_im_terminate($instance_manager);
-
- # Check that all processes died.
-
- unless (mtr_im_check_alive($instance_manager))
- {
- mtr_debug("Instance Manager has been stopped successfully.");
- mtr_im_cleanup($instance_manager);
- return 1;
- }
-
- # Instance Manager don't want to die. We should kill it.
-
- mtr_im_errlog("[$where] Instance Manager did not shutdown gracefully.");
-
- mtr_im_kill($instance_manager);
-
- # Check again that all IM-related processes have been killed.
-
- my $im_is_alive= mtr_im_check_alive($instance_manager);
-
- mtr_im_cleanup($instance_manager);
-
- if ($im_is_alive)
- {
- mtr_error("Can not kill Instance Manager or its children.");
- return 0;
- }
-
- mtr_debug("Instance Manager has been killed successfully.");
- return 1;
-}
-
###########################################################################
1;
diff --git a/mysql-test/mysql-test-run.sh b/mysql-test/mysql-test-run-shell.sh
index f2200c4be07..f2200c4be07 100644
--- a/mysql-test/mysql-test-run.sh
+++ b/mysql-test/mysql-test-run-shell.sh
diff --git a/mysql-test/mysql-test-run.pl b/mysql-test/mysql-test-run.pl
index 13aa81dcc12..e5ed8a99304 100755
--- a/mysql-test/mysql-test-run.pl
+++ b/mysql-test/mysql-test-run.pl
@@ -88,6 +88,7 @@ use strict;
#use diagnostics;
require "lib/mtr_cases.pl";
+require "lib/mtr_im.pl";
require "lib/mtr_process.pl";
require "lib/mtr_timer.pl";
require "lib/mtr_io.pl";
@@ -256,7 +257,7 @@ our $opt_result_ext;
our $opt_skip;
our $opt_skip_rpl;
-our $use_slaves;
+our $max_slave_num= 0;
our $use_innodb;
our $opt_skip_test;
our $opt_skip_im;
@@ -268,7 +269,7 @@ our $opt_sleep_time_for_delete= 10;
our $opt_testcase_timeout;
our $opt_suite_timeout;
my $default_testcase_timeout= 15; # 15 min max
-my $default_suite_timeout= 120; # 2 hours max
+my $default_suite_timeout= 180; # 3 hours max
our $opt_socket;
@@ -427,7 +428,13 @@ sub main () {
{
$need_ndbcluster||= $test->{ndb_test};
$need_im||= $test->{component_id} eq 'im';
- $use_slaves||= $test->{slave_num};
+
+ # Count max number of slaves used by a test case
+ if ( $test->{slave_num} > $max_slave_num)
+ {
+ $max_slave_num= $test->{slave_num};
+ mtr_error("Too many slaves") if $max_slave_num > 3;
+ }
$use_innodb||= $test->{'innodb_test'};
}
$opt_skip_ndbcluster= $opt_skip_ndbcluster_slave= 1
@@ -905,13 +912,13 @@ sub command_line_setup () {
if ( ! $opt_testcase_timeout )
{
$opt_testcase_timeout= $default_testcase_timeout;
- $opt_testcase_timeout*= 10 if defined $opt_valgrind;
+ $opt_testcase_timeout*= 10 if $opt_valgrind;
}
if ( ! $opt_suite_timeout )
{
$opt_suite_timeout= $default_suite_timeout;
- $opt_suite_timeout*= 4 if defined $opt_valgrind;
+ $opt_suite_timeout*= 6 if $opt_valgrind;
}
# Increase times to wait for executables to start if using valgrind
@@ -943,6 +950,7 @@ sub command_line_setup () {
$master->[0]=
{
+ pid => 0,
type => "master",
idx => 0,
path_myddir => "$opt_vardir/master-data",
@@ -958,6 +966,7 @@ sub command_line_setup () {
$master->[1]=
{
+ pid => 0,
type => "master",
idx => 1,
path_myddir => "$opt_vardir/master1-data",
@@ -973,6 +982,7 @@ sub command_line_setup () {
$slave->[0]=
{
+ pid => 0,
type => "slave",
idx => 0,
path_myddir => "$opt_vardir/slave-data",
@@ -989,6 +999,7 @@ sub command_line_setup () {
$slave->[1]=
{
+ pid => 0,
type => "slave",
idx => 1,
path_myddir => "$opt_vardir/slave1-data",
@@ -1004,6 +1015,7 @@ sub command_line_setup () {
$slave->[2]=
{
+ pid => 0,
type => "slave",
idx => 2,
path_myddir => "$opt_vardir/slave2-data",
@@ -1040,6 +1052,7 @@ sub command_line_setup () {
path_datadir => "$opt_vardir/im_mysqld_1.data",
path_sock => "$sockdir/mysqld_1.sock",
path_pid => "$opt_vardir/run/mysqld_1.pid",
+ start_timeout => 400, # enough time create innodb tables
old_log_format => 1
};
@@ -1051,6 +1064,7 @@ sub command_line_setup () {
path_sock => "$sockdir/mysqld_2.sock",
path_pid => "$opt_vardir/run/mysqld_2.pid",
nonguarded => 1,
+ start_timeout => 400, # enough time create innodb tables
old_log_format => 1
};
@@ -1064,7 +1078,7 @@ sub command_line_setup () {
connect_string => "$opt_ndbconnectstring",
path_pid => "$data_dir/ndb_3.pid", # Nodes + 1
pid => 0, # pid of ndb_mgmd
- installed_ok => 'NO',
+ installed_ok => 0,
};
$data_dir= "$opt_vardir/ndbcluster-$opt_ndbcluster_port_slave";
@@ -1077,7 +1091,7 @@ sub command_line_setup () {
connect_string => "$opt_ndbconnectstring_slave",
path_pid => "$data_dir/ndb_2.pid", # Nodes + 1
pid => 0, # pid of ndb_mgmd
- installed_ok => 'NO',
+ installed_ok => 0,
};
# Init pids of ndbd's
@@ -1117,11 +1131,9 @@ sub snapshot_setup () {
$master->[0]->{'path_myddir'},
$master->[1]->{'path_myddir'});
- if ($use_slaves)
+ for (my $idx= 0; $idx < $max_slave_num; $idx++)
{
- push @data_dir_lst, ($slave->[0]->{'path_myddir'},
- $slave->[1]->{'path_myddir'},
- $slave->[2]->{'path_myddir'});
+ push(@data_dir_lst, $slave->[$idx]->{'path_myddir'});
}
unless ($opt_skip_im)
@@ -1172,9 +1184,9 @@ sub executable_setup () {
"$path_client_bindir/mysqld-nt",
"$path_client_bindir/mysqld",
"$path_client_bindir/mysqld-max",
+ "$path_client_bindir/mysqld-debug",
"$glob_basedir/sql/release/mysqld",
"$glob_basedir/sql/debug/mysqld");
- "$path_client_bindir/mysqld-debug",
$path_language= mtr_path_exists("$glob_basedir/share/english/",
"$glob_basedir/sql/share/english/");
$path_charsetsdir= mtr_path_exists("$glob_basedir/share/charsets",
@@ -1337,7 +1349,7 @@ sub environment_setup () {
umask(022);
- my $extra_ld_library_paths;
+ my @ld_library_paths;
# --------------------------------------------------------------------------
# Setup LD_LIBRARY_PATH so the libraries from this distro/clone
@@ -1345,34 +1357,50 @@ sub environment_setup () {
# --------------------------------------------------------------------------
if ( $opt_source_dist )
{
- $extra_ld_library_paths= "$glob_basedir/libmysql/.libs/" .
- ":$glob_basedir/libmysql_r/.libs/";
+ push(@ld_library_paths, "$glob_basedir/libmysql/.libs/",
+ "$glob_basedir/libmysql_r/.libs/");
}
else
{
- $extra_ld_library_paths= "$glob_basedir/lib";
+ push(@ld_library_paths, "$glob_basedir/lib");
+ }
+
+ # --------------------------------------------------------------------------
+ # Add the path where libndbclient can be found
+ # --------------------------------------------------------------------------
+ if ( $opt_ndbcluster_supported )
+ {
+ push(@ld_library_paths, "$glob_basedir/storage/ndb/src/.libs");
}
# --------------------------------------------------------------------------
# Add the path where mysqld will find udf_example.so
# --------------------------------------------------------------------------
- $extra_ld_library_paths .= ":" .
- ($lib_udf_example ? dirname($lib_udf_example) : "");
+ if ( $lib_udf_example )
+ {
+ push(@ld_library_paths, dirname($lib_udf_example));
+ }
# --------------------------------------------------------------------------
- # Add the path where libndbclient can be found
+ # Valgrind need to be run with debug libraries otherwise it's almost
+ # impossible to add correct supressions, that means if "/usr/lib/debug"
+ # is available, it should be added to
+ # LD_LIBRARY_PATH
# --------------------------------------------------------------------------
- if ( $opt_ndbcluster_supported )
+ my $debug_libraries_path= "/usr/lib/debug";
+ if ( $opt_valgrind and -d $debug_libraries_path )
{
- $extra_ld_library_paths .= ":$glob_basedir/storage/ndb/src/.libs";
+ push(@ld_library_paths, $debug_libraries_path);
}
- $ENV{'LD_LIBRARY_PATH'}=
- "$extra_ld_library_paths" .
- ($ENV{'LD_LIBRARY_PATH'} ? ":$ENV{'LD_LIBRARY_PATH'}" : "");
- $ENV{'DYLD_LIBRARY_PATH'}=
- "$extra_ld_library_paths" .
- ($ENV{'DYLD_LIBRARY_PATH'} ? ":$ENV{'DYLD_LIBRARY_PATH'}" : "");
+ $ENV{'LD_LIBRARY_PATH'}= join(":", @ld_library_paths,
+ split(':', $ENV{'LD_LIBRARY_PATH'}));
+ mtr_debug("LD_LIBRARY_PATH: $ENV{'LD_LIBRARY_PATH'}");
+
+ $ENV{'DYLD_LIBRARY_PATH'}= join(":", @ld_library_paths,
+ split(':', $ENV{'DYLD_LIBRARY_PATH'}));
+ mtr_debug("DYLD_LIBRARY_PATH: $ENV{'DYLD_LIBRARY_PATH'}");
+
# --------------------------------------------------------------------------
# Also command lines in .opt files may contain env vars
@@ -1539,7 +1567,8 @@ sub environment_setup () {
my $cmdline_mysql=
"$exe_mysql --no-defaults --host=localhost --user=root --password= " .
"--port=$master->[0]->{'port'} " .
- "--socket=$master->[0]->{'path_sock'}";
+ "--socket=$master->[0]->{'path_sock'} ".
+ "--character-sets-dir=$path_charsetsdir";
$ENV{'MYSQL'}= $cmdline_mysql;
@@ -1662,14 +1691,10 @@ sub kill_running_server () {
{
# Ensure that no old mysqld test servers are running
# This is different from terminating processes we have
- # started from ths run of the script, this is terminating
+ # started from this run of the script, this is terminating
# leftovers from previous runs.
- mtr_report("Killing Possible Leftover Processes");
- mkpath("$opt_vardir/log"); # Needed for mysqladmin log
-
mtr_kill_leftovers();
-
}
}
@@ -2254,11 +2279,10 @@ sub mysql_install_db () {
# FIXME check if testcase really is using second master
copy_install_db('master', $master->[1]->{'path_myddir'});
- if ( $use_slaves )
+ # Install the number of slave databses needed
+ for (my $idx= 0; $idx < $max_slave_num; $idx++)
{
- install_db('slave', $slave->[0]->{'path_myddir'});
- install_db('slave', $slave->[1]->{'path_myddir'});
- install_db('slave', $slave->[2]->{'path_myddir'});
+ copy_install_db("slave".($idx+1), $slave->[$idx]->{'path_myddir'});
}
if ( ! $opt_skip_im )
@@ -2269,7 +2293,7 @@ sub mysql_install_db () {
my $cluster_started_ok= 1; # Assume it can be started
if (ndbcluster_start_install($clusters->[0]) ||
- $use_slaves && ndbcluster_start_install($clusters->[1]))
+ $max_slave_num && ndbcluster_start_install($clusters->[1]))
{
mtr_warning("Failed to start install of cluster");
$cluster_started_ok= 0;
@@ -2280,21 +2304,18 @@ sub mysql_install_db () {
next if !$cluster->{'pid'};
- $cluster->{'installed_ok'}= "YES"; # Assume install suceeds
+ $cluster->{'installed_ok'}= 1; # Assume install suceeds
if (ndbcluster_wait_started($cluster, ""))
{
# failed to install, disable usage and flag that its no ok
mtr_report("ndbcluster_install of $cluster->{'name'} failed");
- $cluster->{"installed_ok"}= "NO";
+ $cluster->{"installed_ok"}= 0;
$cluster_started_ok= 0;
}
}
- $ENV{'NDB_STATUS_OK'}= $clusters->[0]->{'installed_ok'};
- $ENV{'NDB_SLAVE_STATUS_OK'}= $clusters->[1]->{'installed_ok'};;
-
if ( ! $cluster_started_ok )
{
if ( $opt_force)
@@ -2372,6 +2393,12 @@ sub install_db ($$) {
mtr_add_arg($args, "--skip-ndbcluster");
mtr_add_arg($args, "--tmpdir=.");
+ if ( $opt_debug )
+ {
+ mtr_add_arg($args, "--debug=d:t:i:A,%s/log/bootstrap_%s.trace",
+ $opt_vardir_trace, $type);
+ }
+
if ( ! $opt_netware )
{
mtr_add_arg($args, "--language=%s", $path_language);
@@ -2486,6 +2513,28 @@ sub im_prepare_data_dir($) {
}
}
+
+
+#
+# Restore snapshot of the installed slave databases
+# if the snapshot exists
+#
+sub restore_slave_databases ($) {
+ my ($num_slaves)= @_;
+
+ if ( -d $path_snapshot)
+ {
+ for (my $idx= 0; $idx < $num_slaves; $idx++)
+ {
+ my $data_dir= $slave->[$idx]->{'path_myddir'};
+ my $name= basename($data_dir);
+ rmtree($data_dir);
+ mtr_copy_dir("$path_snapshot/$name", $data_dir);
+ }
+ }
+}
+
+
sub run_testcase_check_skip_test($)
{
my ($tinfo)= @_;
@@ -2505,7 +2554,7 @@ sub run_testcase_check_skip_test($)
}
# If test needs cluster, check that master installed ok
- if ( $tinfo->{'ndb_test'} and $clusters->[0]->{'installed_ok'} eq "NO" )
+ if ( $tinfo->{'ndb_test'} and !$clusters->[0]->{'installed_ok'} )
{
mtr_report_test_name($tinfo);
mtr_report_test_failed($tinfo);
@@ -2514,7 +2563,7 @@ sub run_testcase_check_skip_test($)
# If test needs slave cluster, check that it installed ok
if ( $tinfo->{'ndb_test'} and $tinfo->{'slave_num'} and
- $clusters->[1]->{'installed_ok'} eq "NO" )
+ !$clusters->[1]->{'installed_ok'} )
{
mtr_report_test_name($tinfo);
mtr_report_test_failed($tinfo);
@@ -2593,7 +2642,6 @@ sub run_testcase ($) {
{
run_testcase_stop_servers($tinfo, $master_restart, $slave_restart);
}
-
my $died= mtr_record_dead_children();
if ($died or $master_restart or $slave_restart)
{
@@ -2657,7 +2705,10 @@ sub run_testcase ($) {
if ( ! $glob_use_running_server and $tinfo->{'component_id'} eq 'im' )
{
- mtr_im_stop($instance_manager, $tinfo->{'name'});
+ unless ( mtr_im_stop($instance_manager, $tinfo->{'name'}) )
+ {
+ mtr_error("Failed to stop Instance Manager.")
+ }
}
}
@@ -2879,7 +2930,7 @@ sub mysqld_arguments ($$$$$) {
mtr_add_arg($args, "%s--console", $prefix);
mtr_add_arg($args, "%s--basedir=%s", $prefix, $path_my_basedir);
mtr_add_arg($args, "%s--character-sets-dir=%s", $prefix, $path_charsetsdir);
- mtr_add_arg($args, "%s--core", $prefix);
+
mtr_add_arg($args, "%s--log-bin-trust-function-creators", $prefix);
mtr_add_arg($args, "%s--default-character-set=latin1", $prefix);
mtr_add_arg($args, "%s--language=%s", $prefix, $path_language);
@@ -2940,8 +2991,6 @@ sub mysqld_arguments ($$$$$) {
mtr_add_arg($args, "%s--datadir=%s", $prefix,
$slave->[$idx]->{'path_myddir'});
- # FIXME slave get this option twice?!
- mtr_add_arg($args, "%s--exit-info=256", $prefix);
mtr_add_arg($args, "%s--init-rpl-role=slave", $prefix);
if (! $opt_skip_slave_binlog)
{
@@ -3059,9 +3108,22 @@ sub mysqld_arguments ($$$$$) {
mtr_add_arg($args, "%s--user=root", $prefix);
}
+ my $found_skip_core= 0;
foreach my $arg ( @opt_extra_mysqld_opt, @$extra_opt )
{
- mtr_add_arg($args, "%s%s", $prefix, $arg);
+ # Allow --skip-core-file to be set in master.opt file
+ if ($arg eq "--skip-core-file")
+ {
+ $found_skip_core= 1;
+ }
+ else
+ {
+ mtr_add_arg($args, "%s%s", $prefix, $arg);
+ }
+ }
+ if ( !$found_skip_core )
+ {
+ mtr_add_arg($args, "%s%s", $prefix, "--core-file");
}
if ( $opt_bench )
@@ -3071,7 +3133,6 @@ sub mysqld_arguments ($$$$$) {
}
elsif ( $type eq 'master' )
{
- mtr_add_arg($args, "%s--exit-info=256", $prefix);
mtr_add_arg($args, "%s--open-files-limit=1024", $prefix);
mtr_add_arg($args, "%s--log=%s", $prefix, $master->[0]->{'path_mylog'});
}
@@ -3103,13 +3164,13 @@ sub mysqld_start ($$$) {
{
$exe= $exe_master_mysqld;
}
- if ( $type eq 'slave' )
+ elsif ( $type eq 'slave' )
{
$exe= $exe_slave_mysqld;
}
else
{
- $exe= $exe_mysqld;
+ mtr_error("Unknown 'type' \"$type\" passed to mysqld_start");
}
mtr_init_args(\$args);
@@ -3195,7 +3256,10 @@ sub stop_all_servers () {
print "Stopping All Servers\n";
print "Shutting-down Instance Manager\n";
- mtr_im_stop($instance_manager, "stop_all_servers");
+ unless (mtr_im_stop($instance_manager, "stop_all_servers"))
+ {
+ mtr_error("Failed to stop Instance Manager.")
+ }
my %admin_pids; # hash of admin processes that requests shutdown
my @kill_pids; # list of processes to shutdown/kill
@@ -3410,7 +3474,6 @@ sub run_testcase_stop_servers($$$) {
my %admin_pids; # hash of admin processes that requests shutdown
my @kill_pids; # list of processes to shutdown/kill
-
# Remember if we restarted for this test case
$tinfo->{'restarted'}= $do_restart;
@@ -3601,7 +3664,13 @@ sub run_testcase_start_servers($) {
im_create_defaults_file($instance_manager);
- mtr_im_start($instance_manager, $tinfo->{im_opts});
+ unless ( mtr_im_start($instance_manager, $tinfo->{im_opts}) )
+ {
+ report_failure_and_restart($tinfo);
+ mtr_report("Failed to start Instance Manager. " .
+ "The test '$tname' is marked as failed.");
+ return;
+ }
}
# ----------------------------------------------------------------------
@@ -3611,6 +3680,8 @@ sub run_testcase_start_servers($) {
{
mtr_tofile($slave->[0]->{'path_myerr'},"CURRENT_TEST: $tname\n");
+ restore_slave_databases($tinfo->{'slave_num'});
+
do_before_start_slave($tname,$tinfo->{'slave_sh'});
if ( ! $opt_skip_ndbcluster_slave and
@@ -3720,7 +3791,6 @@ sub run_check_testcase ($$) {
sub run_mysqltest ($) {
my ($tinfo)= @_;
-
my $exe= $exe_mysqltest;
my $args;
diff --git a/mysql-test/r/analyse.result b/mysql-test/r/analyse.result
index ba56a98b4a9..b1ed1ea2bed 100644
--- a/mysql-test/r/analyse.result
+++ b/mysql-test/r/analyse.result
@@ -141,3 +141,16 @@ test.t1.product Computer TV 2 8 0 0 4.2500 NULL ENUM('Computer','Phone','TV') NO
sum(profit) 10 6900 11 11 0 0 1946.2500 2867.6719 ENUM('10','275','600','6900') NOT NULL
avg(profit) 10.0000 1380.0000 16 16 0 0 394.68750000 570.20033144 ENUM('10.0000','68.7500','120.0000','1380.0000') NOT NULL
drop table t1,t2;
+create table t1 (f1 double(10,5), f2 char(10), f3 double(10,5));
+insert into t1 values (5.999, "5.9999", 5.99999), (9.555, "9.5555", 9.55555);
+select f1 from t1 procedure analyse(1, 1);
+Field_name Min_value Max_value Min_length Max_length Empties_or_zeros Nulls Avg_value_or_avg_length Std Optimal_fieldtype
+test.t1.f1 5.99900 9.55500 7 7 0 0 7.77700 1.77800 FLOAT(4,3) NOT NULL
+select f2 from t1 procedure analyse(1, 1);
+Field_name Min_value Max_value Min_length Max_length Empties_or_zeros Nulls Avg_value_or_avg_length Std Optimal_fieldtype
+test.t1.f2 5.9999 9.5555 6 6 0 0 6.0000 NULL FLOAT(5,4) UNSIGNED NOT NULL
+select f3 from t1 procedure analyse(1, 1);
+Field_name Min_value Max_value Min_length Max_length Empties_or_zeros Nulls Avg_value_or_avg_length Std Optimal_fieldtype
+test.t1.f3 5.99999 9.55555 7 7 0 0 7.77777 1.77778 FLOAT(6,5) NOT NULL
+drop table t1;
+End of 4.1 tests
diff --git a/mysql-test/r/binlog_row_binlog.result b/mysql-test/r/binlog_row_binlog.result
index 8d5025f7602..7cbfa525798 100644
--- a/mysql-test/r/binlog_row_binlog.result
+++ b/mysql-test/r/binlog_row_binlog.result
@@ -250,8 +250,22 @@ set @@session.auto_increment_increment=1, @@session.auto_increment_offset=1;
insert delayed into t1 values (207);
insert delayed into t1 values (null);
insert delayed into t1 values (300);
+show binlog events from 102;
+Log_name Pos Event_type Server_id End_log_pos Info
+master-bin.000001 # Query 1 # use `test`; create table t1 (id tinyint auto_increment primary key)
+master-bin.000001 # Table_map 1 # table_id: # (test.t1)
+master-bin.000001 # Write_rows 1 # table_id: # flags: STMT_END_F
+master-bin.000001 # Query 1 # use `test`; drop table t1
+master-bin.000001 # Query 1 # use `test`; create table t1 (a int not null auto_increment, primary key (a)) engine=myisam
+master-bin.000001 # Table_map 1 # table_id: # (test.t1)
+master-bin.000001 # Write_rows 1 # table_id: # flags: STMT_END_F
+master-bin.000001 # Table_map 1 # table_id: # (test.t1)
+master-bin.000001 # Write_rows 1 # table_id: # flags: STMT_END_F
+master-bin.000001 # Table_map 1 # table_id: # (test.t1)
+master-bin.000001 # Write_rows 1 # table_id: # flags: STMT_END_F
insert delayed into t1 values (null),(null),(null),(null);
insert delayed into t1 values (null),(null),(400),(null);
+11 == 11
select * from t1;
a
207
@@ -265,25 +279,4 @@ a
306
400
401
-show binlog events from 102;
-Log_name Pos Event_type Server_id End_log_pos Info
-master-bin.000001 # Query 1 # use `test`; create table t1 (id tinyint auto_increment primary key)
-master-bin.000001 # Table_map 1 # table_id: # (test.t1)
-master-bin.000001 # Write_rows 1 # table_id: # flags: STMT_END_F
-master-bin.000001 # Query 1 # use `test`; drop table t1
-master-bin.000001 # Query 1 # use `test`; create table t1 (a int not null auto_increment, primary key (a)) engine=myisam
-master-bin.000001 # Table_map 1 # table_id: # (test.t1)
-master-bin.000001 # Write_rows 1 # table_id: # flags: STMT_END_F
-master-bin.000001 # Table_map 1 # table_id: # (test.t1)
-master-bin.000001 # Write_rows 1 # table_id: # flags: STMT_END_F
-master-bin.000001 # Table_map 1 # table_id: # (test.t1)
-master-bin.000001 # Write_rows 1 # table_id: # flags: STMT_END_F
-master-bin.000001 # Table_map 1 # table_id: # (test.t1)
-master-bin.000001 # Write_rows 1 # table_id: # flags: STMT_END_F
-master-bin.000001 # Table_map 1 # table_id: # (test.t1)
-master-bin.000001 # Write_rows 1 # table_id: # flags: STMT_END_F
-master-bin.000001 # Table_map 1 # table_id: # (test.t1)
-master-bin.000001 # Write_rows 1 # table_id: # flags: STMT_END_F
-master-bin.000001 # Table_map 1 # table_id: # (test.t1)
-master-bin.000001 # Write_rows 1 # table_id: # flags: STMT_END_F
drop table t1;
diff --git a/mysql-test/r/binlog_row_mix_innodb_myisam.result b/mysql-test/r/binlog_row_mix_innodb_myisam.result
index ae66f98739d..a192d243bb0 100644
--- a/mysql-test/r/binlog_row_mix_innodb_myisam.result
+++ b/mysql-test/r/binlog_row_mix_innodb_myisam.result
@@ -359,15 +359,6 @@ show binlog events from 102;
Log_name Pos Event_type Server_id End_log_pos Info
master-bin.000001 # Table_map 1 # table_id: # (test.t1)
master-bin.000001 # Write_rows 1 # table_id: # flags: STMT_END_F
-master-bin.000001 # Query 1 # use `test`; BEGIN
-master-bin.000001 # Query 1 # use `test`; CREATE TABLE `t2` (
- `a` int(11) NOT NULL DEFAULT '0',
- `b` int(11) DEFAULT NULL,
- PRIMARY KEY (`a`)
-) ENGINE=InnoDB
-master-bin.000001 # Table_map 1 # table_id: # (test.t2)
-master-bin.000001 # Write_rows 1 # table_id: # flags: STMT_END_F
-master-bin.000001 # Xid 1 # COMMIT /* xid= */
master-bin.000001 # Query 1 # use `test`; DROP TABLE if exists t2
master-bin.000001 # Table_map 1 # table_id: # (test.t1)
master-bin.000001 # Write_rows 1 # table_id: # flags: STMT_END_F
@@ -375,15 +366,6 @@ master-bin.000001 # Query 1 # use `test`; DROP TABLE IF EXISTS t2
master-bin.000001 # Query 1 # use `test`; CREATE TABLE t2 (a int, b int, primary key (a)) engine=innodb
master-bin.000001 # Table_map 1 # table_id: # (test.t1)
master-bin.000001 # Write_rows 1 # table_id: # flags: STMT_END_F
-master-bin.000001 # Query 1 # use `test`; BEGIN
-master-bin.000001 # Query 1 # use `test`; CREATE TABLE `t2` (
- `a` int(11) NOT NULL DEFAULT '0',
- `b` int(11) DEFAULT NULL,
- PRIMARY KEY (`a`)
-) ENGINE=InnoDB
-master-bin.000001 # Table_map 1 # table_id: # (test.t2)
-master-bin.000001 # Write_rows 1 # table_id: # flags: STMT_END_F
-master-bin.000001 # Xid 1 # COMMIT /* xid= */
master-bin.000001 # Query 1 # use `test`; TRUNCATE table t2
master-bin.000001 # Xid 1 # COMMIT /* xid= */
master-bin.000001 # Table_map 1 # table_id: # (test.t1)
diff --git a/mysql-test/r/binlog_statement_insert_delayed.result b/mysql-test/r/binlog_statement_insert_delayed.result
index 3cf6ba14e02..7a1b9a7ec9b 100644
--- a/mysql-test/r/binlog_statement_insert_delayed.result
+++ b/mysql-test/r/binlog_statement_insert_delayed.result
@@ -3,8 +3,16 @@ set @@session.auto_increment_increment=1, @@session.auto_increment_offset=1;
insert delayed into t1 values (207);
insert delayed into t1 values (null);
insert delayed into t1 values (300);
+show binlog events from 102;
+Log_name Pos Event_type Server_id End_log_pos Info
+master-bin.000001 # Query 1 # use `test`; create table t1 (a int not null auto_increment, primary key (a)) engine=myisam
+master-bin.000001 # Query 1 # use `test`; insert delayed into t1 values (207)
+master-bin.000001 # Intvar 1 # INSERT_ID=208
+master-bin.000001 # Query 1 # use `test`; insert delayed into t1 values (null)
+master-bin.000001 # Query 1 # use `test`; insert delayed into t1 values (300)
insert delayed into t1 values (null),(null),(null),(null);
insert delayed into t1 values (null),(null),(400),(null);
+11 == 11
select * from t1;
a
207
@@ -18,15 +26,4 @@ a
306
400
401
-show binlog events from 102;
-Log_name Pos Event_type Server_id End_log_pos Info
-master-bin.000001 # Query 1 # use `test`; create table t1 (a int not null auto_increment, primary key (a)) engine=myisam
-master-bin.000001 # Query 1 # use `test`; insert delayed into t1 values (207)
-master-bin.000001 # Intvar 1 # INSERT_ID=208
-master-bin.000001 # Query 1 # use `test`; insert delayed into t1 values (null)
-master-bin.000001 # Query 1 # use `test`; insert delayed into t1 values (300)
-master-bin.000001 # Intvar 1 # INSERT_ID=301
-master-bin.000001 # Query 1 # use `test`; insert delayed into t1 values (null),(null),(null),(null)
-master-bin.000001 # Intvar 1 # INSERT_ID=305
-master-bin.000001 # Query 1 # use `test`; insert delayed into t1 values (null),(null),(400),(null)
drop table t1;
diff --git a/mysql-test/r/binlog_stm_binlog.result b/mysql-test/r/binlog_stm_binlog.result
index 6589392fe79..eed2df28d1f 100644
--- a/mysql-test/r/binlog_stm_binlog.result
+++ b/mysql-test/r/binlog_stm_binlog.result
@@ -160,8 +160,22 @@ set @@session.auto_increment_increment=1, @@session.auto_increment_offset=1;
insert delayed into t1 values (207);
insert delayed into t1 values (null);
insert delayed into t1 values (300);
+show binlog events from 102;
+Log_name Pos Event_type Server_id End_log_pos Info
+master-bin.000001 # Query 1 # use `test`; create table t1 (id tinyint auto_increment primary key)
+master-bin.000001 # Intvar 1 # INSERT_ID=127
+master-bin.000001 # Query 1 # use `test`; insert into t1 values(null)
+master-bin.000001 # Query 1 # use `test`; drop table t1
+master-bin.000001 # Query 1 # use `test`; create table t1 (a int not null auto_increment, primary key (a)) engine=myisam
+master-bin.000001 # Table_map 1 # table_id: # (test.t1)
+master-bin.000001 # Write_rows 1 # table_id: # flags: STMT_END_F
+master-bin.000001 # Table_map 1 # table_id: # (test.t1)
+master-bin.000001 # Write_rows 1 # table_id: # flags: STMT_END_F
+master-bin.000001 # Table_map 1 # table_id: # (test.t1)
+master-bin.000001 # Write_rows 1 # table_id: # flags: STMT_END_F
insert delayed into t1 values (null),(null),(null),(null);
insert delayed into t1 values (null),(null),(400),(null);
+11 == 11
select * from t1;
a
207
@@ -175,25 +189,4 @@ a
306
400
401
-show binlog events from 102;
-Log_name Pos Event_type Server_id End_log_pos Info
-master-bin.000001 # Query 1 # use `test`; create table t1 (id tinyint auto_increment primary key)
-master-bin.000001 # Intvar 1 # INSERT_ID=127
-master-bin.000001 # Query 1 # use `test`; insert into t1 values(null)
-master-bin.000001 # Query 1 # use `test`; drop table t1
-master-bin.000001 # Query 1 # use `test`; create table t1 (a int not null auto_increment, primary key (a)) engine=myisam
-master-bin.000001 # Table_map 1 # table_id: # (test.t1)
-master-bin.000001 # Write_rows 1 # table_id: # flags: STMT_END_F
-master-bin.000001 # Table_map 1 # table_id: # (test.t1)
-master-bin.000001 # Write_rows 1 # table_id: # flags: STMT_END_F
-master-bin.000001 # Table_map 1 # table_id: # (test.t1)
-master-bin.000001 # Write_rows 1 # table_id: # flags: STMT_END_F
-master-bin.000001 # Table_map 1 # table_id: # (test.t1)
-master-bin.000001 # Write_rows 1 # table_id: # flags: STMT_END_F
-master-bin.000001 # Table_map 1 # table_id: # (test.t1)
-master-bin.000001 # Write_rows 1 # table_id: # flags: STMT_END_F
-master-bin.000001 # Table_map 1 # table_id: # (test.t1)
-master-bin.000001 # Write_rows 1 # table_id: # flags: STMT_END_F
-master-bin.000001 # Table_map 1 # table_id: # (test.t1)
-master-bin.000001 # Write_rows 1 # table_id: # flags: STMT_END_F
drop table t1;
diff --git a/mysql-test/r/client_xml.result b/mysql-test/r/client_xml.result
index 24c05c7f9d6..7395b2433e8 100644
--- a/mysql-test/r/client_xml.result
+++ b/mysql-test/r/client_xml.result
@@ -68,7 +68,7 @@ insert into t1 values (1, 2, 'a&b a<b a>b');
<resultset statement="select null from dual
">
<row>
- <field name="NULL">NULL</field>
+ <field name="NULL" xsi:nil="true" />
</row>
</resultset>
drop table t1;
diff --git a/mysql-test/r/csv.result b/mysql-test/r/csv.result
index e342af32a80..222d4de8059 100644
--- a/mysql-test/r/csv.result
+++ b/mysql-test/r/csv.result
@@ -5205,3 +5205,22 @@ select * from bug15205;
val
drop table bug15205;
drop table bug15205_2;
+create table bug22080_1 (id int,string varchar(64)) Engine=CSV;
+create table bug22080_2 (id int,string varchar(64)) Engine=CSV;
+create table bug22080_3 (id int,string varchar(64)) Engine=CSV;
+insert into bug22080_1 values(1,'string');
+insert into bug22080_1 values(2,'string');
+insert into bug22080_1 values(3,'string');
+"1","string"
+2","string"
+"3","string"
+check table bug22080_2;
+Table Op Msg_type Msg_text
+test.bug22080_2 check error Corrupt
+"1","string"
+"2",string"
+"3","string"
+check table bug22080_3;
+Table Op Msg_type Msg_text
+test.bug22080_3 check error Corrupt
+drop tables bug22080_1,bug22080_2,bug22080_3;
diff --git a/mysql-test/r/ctype_gbk.result b/mysql-test/r/ctype_gbk.result
index 241539ecf42..3f5d8b0d8c6 100644
--- a/mysql-test/r/ctype_gbk.result
+++ b/mysql-test/r/ctype_gbk.result
@@ -168,3 +168,13 @@ DROP TABLE t1;
select hex(convert(_gbk 0xA14041 using ucs2));
hex(convert(_gbk 0xA14041 using ucs2))
003F0041
+create table t1 (c1 text not null, c2 text not null) character set gbk;
+alter table t1 change c1 c1 mediumtext character set gbk not null;
+show create table t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `c1` mediumtext NOT NULL,
+ `c2` text NOT NULL
+) ENGINE=MyISAM DEFAULT CHARSET=gbk
+drop table t1;
+End of 5.0 tests
diff --git a/mysql-test/r/ctype_ucs.result b/mysql-test/r/ctype_ucs.result
index 0d8975c94c7..4f08b97492f 100644
--- a/mysql-test/r/ctype_ucs.result
+++ b/mysql-test/r/ctype_ucs.result
@@ -755,6 +755,27 @@ select export_set(5, name, upper(name), ",", 5) from bug20536;
export_set(5, name, upper(name), ",", 5)
test1,TEST1,test1,TEST1,TEST1
'test\_2','TEST\_2','test\_2','TEST\_2','TEST\_2'
+CREATE TABLE t1 (
+status enum('active','passive') collate latin1_general_ci
+NOT NULL default 'passive'
+);
+SHOW CREATE TABLE t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `status` enum('active','passive') CHARACTER SET latin1 COLLATE latin1_general_ci NOT NULL DEFAULT 'passive'
+) ENGINE=MyISAM DEFAULT CHARSET=latin1
+ALTER TABLE t1 ADD a int NOT NULL AFTER status;
+CREATE TABLE t2 (
+status enum('active','passive') collate ucs2_turkish_ci
+NOT NULL default 'passive'
+);
+SHOW CREATE TABLE t2;
+Table Create Table
+t2 CREATE TABLE `t2` (
+ `status` enum('active','passive') CHARACTER SET ucs2 COLLATE ucs2_turkish_ci NOT NULL DEFAULT 'passive'
+) ENGINE=MyISAM DEFAULT CHARSET=latin1
+ALTER TABLE t2 ADD a int NOT NULL AFTER status;
+DROP TABLE t1,t2;
select password(name) from bug20536;
password(name)
????????????????????
diff --git a/mysql-test/r/ctype_utf8.result b/mysql-test/r/ctype_utf8.result
index f5e4054a385..f3351a2973b 100644
--- a/mysql-test/r/ctype_utf8.result
+++ b/mysql-test/r/ctype_utf8.result
@@ -1340,19 +1340,18 @@ select a from t1 group by a;
a
e
drop table t1;
-set names utf8;
-grant select on test.* to юзер_юзер@localhost;
-user()
-юзер_юзер@localhost
-revoke all on test.* from юзер_юзер@localhost;
-drop user юзер_юзер@localhost;
-create database имÑ_базы_в_кодировке_утф8_длиной_больше_чем_45;
-use имÑ_базы_в_кодировке_утф8_длиной_больше_чем_45;
-select database();
-database()
-имÑ_базы_в_кодировке_утф8_длиной_больше_чем_45
-drop database имÑ_базы_в_кодировке_утф8_длиной_больше_чем_45;
-use test;
+create table t1(a char(10)) default charset utf8;
+insert into t1 values ('123'), ('456');
+explain
+select substr(Z.a,-1), Z.a from t1 as Y join t1 as Z on Y.a=Z.a order by 1;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE Y ALL NULL NULL NULL NULL 2 Using temporary; Using filesort
+1 SIMPLE Z ALL NULL NULL NULL NULL 2 Using where
+select substr(Z.a,-1), Z.a from t1 as Y join t1 as Z on Y.a=Z.a order by 1;
+substr(Z.a,-1) a
+3 123
+6 456
+drop table t1;
CREATE TABLE t1(id varchar(20) NOT NULL) DEFAULT CHARSET=utf8;
INSERT INTO t1 VALUES ('xxx'), ('aa'), ('yyy'), ('aa');
SELECT id FROM t1;
@@ -1462,3 +1461,21 @@ set @a:=null;
execute my_stmt using @a;
a b
drop table if exists t1;
+CREATE TABLE t1 (
+colA int(11) NOT NULL,
+colB varchar(255) character set utf8 NOT NULL,
+PRIMARY KEY (colA)
+) ENGINE=InnoDB DEFAULT CHARSET=latin1;
+INSERT INTO t1 (colA, colB) VALUES (1, 'foo'), (2, 'foo bar');
+CREATE TABLE t2 (
+colA int(11) NOT NULL,
+colB varchar(255) character set utf8 NOT NULL,
+KEY bad (colA,colB(3))
+) ENGINE=InnoDB DEFAULT CHARSET=latin1;
+INSERT INTO t2 (colA, colB) VALUES (1, 'foo'),(2, 'foo bar');
+SELECT * FROM t1 JOIN t2 ON t1.colA=t2.colA AND t1.colB=t2.colB
+WHERE t1.colA < 3;
+colA colB colA colB
+1 foo 1 foo
+2 foo bar 2 foo bar
+DROP TABLE t1, t2;
diff --git a/mysql-test/r/delayed.result b/mysql-test/r/delayed.result
index a336f3b4108..a514ffcddd2 100644
--- a/mysql-test/r/delayed.result
+++ b/mysql-test/r/delayed.result
@@ -7,6 +7,7 @@ insert delayed into t1 set a = 4;
insert delayed into t1 set a = 5, tmsp = 19711006010203;
insert delayed into t1 (a, tmsp) values (6, 19711006010203);
insert delayed into t1 (a, tmsp) values (7, NULL);
+FLUSH TABLE t1;
insert into t1 set a = 8,tmsp=19711006010203;
select * from t1 where tmsp=0;
a tmsp
@@ -22,6 +23,7 @@ insert delayed into t1 values (null,"c");
insert delayed into t1 values (3,"d"),(null,"e");
insert delayed into t1 values (3,"this will give an","error");
ERROR 21S01: Column count doesn't match value count at row 1
+FLUSH TABLE t1;
show status like 'not_flushed_delayed_rows';
Variable_name Value
Not_flushed_delayed_rows 0
@@ -54,6 +56,7 @@ insert delayed into t1 values(null);
insert delayed into t1 values(null);
insert delayed into t1 values(null);
insert delayed into t1 values(null);
+FLUSH TABLE t1;
select * from t1 order by a;
a
1
@@ -69,3 +72,174 @@ a
12
13
DROP TABLE t1;
+SET @bug20627_old_auto_increment_offset=
+@@auto_increment_offset= 2;
+SET @bug20627_old_auto_increment_increment=
+@@auto_increment_increment= 3;
+SET @bug20627_old_session_auto_increment_offset=
+@@session.auto_increment_offset= 4;
+SET @bug20627_old_session_auto_increment_increment=
+@@session.auto_increment_increment= 5;
+SET @@auto_increment_offset= 2;
+SET @@auto_increment_increment= 3;
+SET @@session.auto_increment_offset= 4;
+SET @@session.auto_increment_increment= 5;
+CREATE TABLE t1 (
+c1 INT NOT NULL AUTO_INCREMENT,
+PRIMARY KEY (c1)
+);
+INSERT INTO t1 VALUES (NULL),(NULL),(NULL);
+SELECT * FROM t1;
+c1
+4
+9
+14
+DROP TABLE t1;
+CREATE TABLE t1 (
+c1 INT NOT NULL AUTO_INCREMENT,
+PRIMARY KEY (c1)
+);
+INSERT DELAYED INTO t1 VALUES (NULL),(NULL),(NULL);
+FLUSH TABLE t1;
+SELECT * FROM t1;
+c1
+4
+9
+14
+DROP TABLE t1;
+SET @@auto_increment_offset=
+@bug20627_old_auto_increment_offset;
+SET @@auto_increment_increment=
+@bug20627_old_auto_increment_increment;
+SET @@session.auto_increment_offset=
+@bug20627_old_session_auto_increment_offset;
+SET @@session.auto_increment_increment=
+@bug20627_old_session_auto_increment_increment;
+SET @bug20830_old_auto_increment_offset=
+@@auto_increment_offset= 2;
+SET @bug20830_old_auto_increment_increment=
+@@auto_increment_increment= 3;
+SET @bug20830_old_session_auto_increment_offset=
+@@session.auto_increment_offset= 4;
+SET @bug20830_old_session_auto_increment_increment=
+@@session.auto_increment_increment= 5;
+SET @@auto_increment_offset= 2;
+SET @@auto_increment_increment= 3;
+SET @@session.auto_increment_offset= 4;
+SET @@session.auto_increment_increment= 5;
+CREATE TABLE t1 (
+c1 INT(11) NOT NULL AUTO_INCREMENT,
+c2 INT(11) DEFAULT NULL,
+PRIMARY KEY (c1)
+);
+SET insert_id= 14;
+INSERT INTO t1 VALUES(NULL, 11), (NULL, 12), (NULL, 13);
+INSERT INTO t1 VALUES(NULL, 21), (NULL, 22), (NULL, 23);
+INSERT INTO t1 VALUES( 69, 31), (NULL, 32), (NULL, 33);
+INSERT INTO t1 VALUES(NULL, 41), (NULL, 42), (NULL, 43);
+SET insert_id= 114;
+INSERT INTO t1 VALUES(NULL, 51), (NULL, 52), (NULL, 53);
+INSERT INTO t1 VALUES(NULL, 61), (NULL, 62), (NULL, 63);
+INSERT INTO t1 VALUES( 49, 71), (NULL, 72), (NULL, 73);
+INSERT INTO t1 VALUES(NULL, 81), (NULL, 82), (NULL, 83);
+SET insert_id= 114;
+INSERT INTO t1 VALUES(NULL, 91);
+ERROR 23000: Duplicate entry '114' for key 'PRIMARY'
+INSERT INTO t1 VALUES (NULL, 92), (NULL, 93);
+SELECT * FROM t1;
+c1 c2
+14 11
+19 12
+24 13
+29 21
+34 22
+39 23
+69 31
+74 32
+79 33
+84 41
+89 42
+94 43
+114 51
+119 52
+124 53
+129 61
+134 62
+139 63
+49 71
+144 72
+149 73
+154 81
+159 82
+164 83
+169 92
+174 93
+SELECT COUNT(*) FROM t1;
+COUNT(*)
+26
+SELECT SUM(c1) FROM t1;
+SUM(c1)
+2569
+DROP TABLE t1;
+CREATE TABLE t1 (
+c1 INT(11) NOT NULL AUTO_INCREMENT,
+c2 INT(11) DEFAULT NULL,
+PRIMARY KEY (c1)
+);
+SET insert_id= 14;
+INSERT DELAYED INTO t1 VALUES(NULL, 11), (NULL, 12), (NULL, 13);
+INSERT DELAYED INTO t1 VALUES(NULL, 21), (NULL, 22), (NULL, 23);
+INSERT DELAYED INTO t1 VALUES( 69, 31), (NULL, 32), (NULL, 33);
+INSERT DELAYED INTO t1 VALUES(NULL, 41), (NULL, 42), (NULL, 43);
+SET insert_id= 114;
+INSERT DELAYED INTO t1 VALUES(NULL, 51), (NULL, 52), (NULL, 53);
+INSERT DELAYED INTO t1 VALUES(NULL, 61), (NULL, 62), (NULL, 63);
+INSERT DELAYED INTO t1 VALUES( 49, 71), (NULL, 72), (NULL, 73);
+INSERT DELAYED INTO t1 VALUES(NULL, 81), (NULL, 82), (NULL, 83);
+SET insert_id= 114;
+INSERT DELAYED INTO t1 VALUES(NULL, 91);
+INSERT DELAYED INTO t1 VALUES (NULL, 92), (NULL, 93);
+FLUSH TABLE t1;
+SELECT * FROM t1;
+c1 c2
+14 11
+19 12
+24 13
+29 21
+34 22
+39 23
+69 31
+74 32
+79 33
+84 41
+89 42
+94 43
+114 51
+119 52
+124 53
+129 61
+134 62
+139 63
+49 71
+144 72
+149 73
+154 81
+159 82
+164 83
+169 92
+174 93
+SELECT COUNT(*) FROM t1;
+COUNT(*)
+26
+SELECT SUM(c1) FROM t1;
+SUM(c1)
+2569
+DROP TABLE t1;
+SET @@auto_increment_offset=
+@bug20830_old_auto_increment_offset;
+SET @@auto_increment_increment=
+@bug20830_old_auto_increment_increment;
+SET @@session.auto_increment_offset=
+@bug20830_old_session_auto_increment_offset;
+SET @@session.auto_increment_increment=
+@bug20830_old_session_auto_increment_increment;
diff --git a/mysql-test/r/execution_constants.result b/mysql-test/r/execution_constants.result
new file mode 100644
index 00000000000..293c88dc506
--- /dev/null
+++ b/mysql-test/r/execution_constants.result
@@ -0,0 +1,12 @@
+CREATE TABLE `t_bug21476` (
+`ID_BOARD` smallint(5) unsigned NOT NULL default '0',
+`ID_MEMBER` mediumint(8) unsigned NOT NULL default '0',
+`logTime` int(10) unsigned NOT NULL default '0',
+`ID_MSG` mediumint(8) unsigned NOT NULL default '0',
+PRIMARY KEY (`ID_MEMBER`,`ID_BOARD`),
+KEY `logTime` (`logTime`)
+) ENGINE=MyISAM DEFAULT CHARSET=cp1251 COLLATE=cp1251_bulgarian_ci;
+INSERT INTO `t_bug21476` VALUES (2,2,1154870939,0),(1,2,1154870957,0),(2,183,1154941362,0),(2,84,1154904301,0),(1,84,1154905867,0),(2,13,1154947484,10271),(3,84,1154880549,0),(1,6,1154892183,0),(2,25,1154947581,10271),(3,25,1154904760,0),(1,25,1154947373,10271),(1,179,1154899992,0),(2,179,1154899410,0),(5,25,1154901666,0),(2,329,1154902026,0),(3,329,1154902040,0),(1,329,1154902058,0),(1,13,1154930841,0),(3,85,1154904987,0),(1,183,1154929665,0),(3,13,1154931268,0),(1,85,1154936888,0),(1,169,1154937959,0),(2,169,1154941717,0),(3,183,1154939810,0),(3,169,1154941734,0);
+Assertion: mysql_errno 1436 == 1436
+DROP TABLE `t_bug21476`;
+End of 5.0 tests.
diff --git a/mysql-test/r/func_gconcat.result b/mysql-test/r/func_gconcat.result
index aef29ef9525..43646bd3d0e 100644
--- a/mysql-test/r/func_gconcat.result
+++ b/mysql-test/r/func_gconcat.result
@@ -660,3 +660,12 @@ CHAR_LENGTH( GROUP_CONCAT(b) )
240001
SET GROUP_CONCAT_MAX_LEN = 1024;
DROP TABLE t1;
+CREATE TABLE t1 (a int, b int);
+INSERT INTO t1 VALUES (2,1), (1,2), (2,2), (1,3);
+SELECT GROUP_CONCAT(a), x
+FROM (SELECT a, GROUP_CONCAT(b) x FROM t1 GROUP BY a) AS s
+GROUP BY x;
+GROUP_CONCAT(a) x
+2 1,2
+1 2,3
+DROP TABLE t1;
diff --git a/mysql-test/r/func_group.result b/mysql-test/r/func_group.result
index 3838f04e20d..40ca0a38db2 100644
--- a/mysql-test/r/func_group.result
+++ b/mysql-test/r/func_group.result
@@ -851,8 +851,8 @@ CREATE TABLE t1 (a INT, b INT);
INSERT INTO t1 VALUES (1,1),(1,2),(2,3);
SELECT (SELECT COUNT(DISTINCT t1.b)) FROM t1 GROUP BY t1.a;
(SELECT COUNT(DISTINCT t1.b))
-0
2
+1
SELECT (SELECT COUNT(DISTINCT 12)) FROM t1 GROUP BY t1.a;
(SELECT COUNT(DISTINCT 12))
1
@@ -1004,7 +1004,7 @@ SELECT SQL_NO_CACHE
WHERE ttt.a = ccc.b AND ttt.a = t.a GROUP BY ttt.a) AS minid
FROM t1 t, t2 c WHERE t.a = c.b;
minid
-NULL
+1
DROP TABLE t1,t2;
create table t1 select variance(0);
show create table t1;
diff --git a/mysql-test/r/func_in.result b/mysql-test/r/func_in.result
index 0236cbfe26f..b88e5a66f96 100644
--- a/mysql-test/r/func_in.result
+++ b/mysql-test/r/func_in.result
@@ -343,3 +343,71 @@ some_id
1
2
drop table t1;
+create table t1(f1 char(1));
+insert into t1 values ('a'),('b'),('1');
+select f1 from t1 where f1 in ('a',1);
+f1
+a
+1
+select f1, case f1 when 'a' then '+' when 1 then '-' end from t1;
+f1 case f1 when 'a' then '+' when 1 then '-' end
+a +
+b NULL
+1 -
+create index t1f1_idx on t1(f1);
+select f1 from t1 where f1 in ('a',1);
+f1
+1
+a
+explain select f1 from t1 where f1 in ('a',1);
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 index NULL t1f1_idx 2 NULL 3 Using where; Using index
+select f1 from t1 where f1 in ('a','b');
+f1
+a
+b
+explain select f1 from t1 where f1 in ('a','b');
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 index t1f1_idx t1f1_idx 2 NULL 3 Using where; Using index
+select f1 from t1 where f1 in (2,1);
+f1
+1
+explain select f1 from t1 where f1 in (2,1);
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 index t1f1_idx t1f1_idx 2 NULL 3 Using where; Using index
+create table t2(f2 int, index t2f2(f2));
+insert into t2 values(0),(1),(2);
+select f2 from t2 where f2 in ('a',2);
+f2
+0
+2
+Warnings:
+Warning 1292 Truncated incorrect DOUBLE value: 'a'
+Warning 1292 Truncated incorrect DOUBLE value: 'a'
+Warning 1292 Truncated incorrect DOUBLE value: 'a'
+explain select f2 from t2 where f2 in ('a',2);
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t2 index NULL t2f2 5 NULL 3 Using where; Using index
+select f2 from t2 where f2 in ('a','b');
+f2
+0
+Warnings:
+Warning 1292 Truncated incorrect DOUBLE value: 'a'
+Warning 1292 Truncated incorrect DOUBLE value: 'b'
+explain select f2 from t2 where f2 in ('a','b');
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t2 index t2f2 t2f2 5 NULL 3 Using where; Using index
+Warnings:
+Warning 1292 Truncated incorrect DOUBLE value: 'a'
+Warning 1292 Truncated incorrect DOUBLE value: 'b'
+select f2 from t2 where f2 in (1,'b');
+f2
+0
+1
+Warnings:
+Warning 1292 Truncated incorrect DOUBLE value: 'b'
+Warning 1292 Truncated incorrect DOUBLE value: 'b'
+explain select f2 from t2 where f2 in (1,'b');
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t2 index NULL t2f2 5 NULL 3 Using where; Using index
+drop table t1, t2;
diff --git a/mysql-test/r/func_time.result b/mysql-test/r/func_time.result
index 34507e0491c..82c361edd39 100644
--- a/mysql-test/r/func_time.result
+++ b/mysql-test/r/func_time.result
@@ -890,6 +890,18 @@ t1 CREATE TABLE `t1` (
`from_unixtime(1) + 0` double(23,6) DEFAULT NULL
) ENGINE=MyISAM DEFAULT CHARSET=latin1
drop table t1;
+SET NAMES latin1;
+SET character_set_results = NULL;
+SHOW VARIABLES LIKE 'character_set_results';
+Variable_name Value
+character_set_results
+CREATE TABLE testBug8868 (field1 DATE, field2 VARCHAR(32) CHARACTER SET BINARY);
+INSERT INTO testBug8868 VALUES ('2006-09-04', 'abcd');
+SELECT DATE_FORMAT(field1,'%b-%e %l:%i%p') as fmtddate, field2 FROM testBug8868;
+fmtddate field2
+Sep-4 12:00AM abcd
+DROP TABLE testBug8868;
+SET NAMES DEFAULT;
(select time_format(timediff(now(), DATE_SUB(now(),INTERVAL 5 DAY)),'%H') As H)
union
(select time_format(timediff(now(), DATE_SUB(now(),INTERVAL 5 DAY)),'%H') As H);
diff --git a/mysql-test/r/greedy_optimizer.result b/mysql-test/r/greedy_optimizer.result
index 1da49fbedb0..b02ff04780b 100644
--- a/mysql-test/r/greedy_optimizer.result
+++ b/mysql-test/r/greedy_optimizer.result
@@ -233,7 +233,7 @@ id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t7 eq_ref PRIMARY PRIMARY 4 test.t1.c16 1 Using index
show status like 'Last_query_cost';
Variable_name Value
-Last_query_cost 274.418727
+Last_query_cost 289.418727
explain select t1.c11 from t7, t6, t5, t4, t3, t2, t1 where t1.c11 = t2.c21 and t1.c12 = t3.c31 and t1.c13 = t4.c41 and t1.c14 = t5.c51 and t1.c15 = t6.c61 and t1.c16 = t7.c71;
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t2 ALL NULL NULL NULL NULL 6
@@ -245,7 +245,7 @@ id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t7 eq_ref PRIMARY PRIMARY 4 test.t1.c16 1 Using index
show status like 'Last_query_cost';
Variable_name Value
-Last_query_cost 274.418727
+Last_query_cost 289.418727
explain select t1.c11 from t1, t2, t3, t4, t5, t6, t7 where t1.c11 = t2.c21 and t1.c12 = t3.c31 and t1.c13 = t4.c41 and t1.c14 = t5.c51 and t1.c15 = t6.c61 and t1.c16 = t7.c71 and t2.c22 = t3.c32 and t2.c23 = t4.c42 and t2.c24 = t5.c52 and t2.c25 = t6.c62 and t2.c26 = t7.c72 and t3.c33 = t4.c43 and t3.c34 = t5.c53 and t3.c35 = t6.c63 and t3.c36 = t7.c73 and t4.c42 = t5.c54 and t4.c43 = t6.c64 and t4.c44 = t7.c74 and t5.c52 = t6.c65 and t5.c53 = t7.c75 and t6.c62 = t7.c76;
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t2 ALL NULL NULL NULL NULL 6
@@ -257,7 +257,7 @@ id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t7 eq_ref PRIMARY PRIMARY 4 test.t1.c16 1 Using where
show status like 'Last_query_cost';
Variable_name Value
-Last_query_cost 274.418727
+Last_query_cost 289.418727
explain select t1.c11 from t7, t6, t5, t4, t3, t2, t1 where t1.c11 = t2.c21 and t1.c12 = t3.c31 and t1.c13 = t4.c41 and t1.c14 = t5.c51 and t1.c15 = t6.c61 and t1.c16 = t7.c71 and t2.c22 = t3.c32 and t2.c23 = t4.c42 and t2.c24 = t5.c52 and t2.c25 = t6.c62 and t2.c26 = t7.c72 and t3.c33 = t4.c43 and t3.c34 = t5.c53 and t3.c35 = t6.c63 and t3.c36 = t7.c73 and t4.c42 = t5.c54 and t4.c43 = t6.c64 and t4.c44 = t7.c74 and t5.c52 = t6.c65 and t5.c53 = t7.c75 and t6.c62 = t7.c76;
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t2 ALL NULL NULL NULL NULL 6
@@ -269,7 +269,7 @@ id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t7 eq_ref PRIMARY PRIMARY 4 test.t1.c16 1 Using where
show status like 'Last_query_cost';
Variable_name Value
-Last_query_cost 274.418727
+Last_query_cost 289.418727
set optimizer_search_depth=1;
select @@optimizer_search_depth;
@@optimizer_search_depth
@@ -385,7 +385,7 @@ id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t7 eq_ref PRIMARY PRIMARY 4 test.t1.c16 1 Using index
show status like 'Last_query_cost';
Variable_name Value
-Last_query_cost 274.418727
+Last_query_cost 289.418727
explain select t1.c11 from t7, t6, t5, t4, t3, t2, t1 where t1.c11 = t2.c21 and t1.c12 = t3.c31 and t1.c13 = t4.c41 and t1.c14 = t5.c51 and t1.c15 = t6.c61 and t1.c16 = t7.c71;
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t2 ALL NULL NULL NULL NULL 6
@@ -397,7 +397,7 @@ id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t7 eq_ref PRIMARY PRIMARY 4 test.t1.c16 1 Using index
show status like 'Last_query_cost';
Variable_name Value
-Last_query_cost 274.418727
+Last_query_cost 289.418727
explain select t1.c11 from t1, t2, t3, t4, t5, t6, t7 where t1.c11 = t2.c21 and t1.c12 = t3.c31 and t1.c13 = t4.c41 and t1.c14 = t5.c51 and t1.c15 = t6.c61 and t1.c16 = t7.c71 and t2.c22 = t3.c32 and t2.c23 = t4.c42 and t2.c24 = t5.c52 and t2.c25 = t6.c62 and t2.c26 = t7.c72 and t3.c33 = t4.c43 and t3.c34 = t5.c53 and t3.c35 = t6.c63 and t3.c36 = t7.c73 and t4.c42 = t5.c54 and t4.c43 = t6.c64 and t4.c44 = t7.c74 and t5.c52 = t6.c65 and t5.c53 = t7.c75 and t6.c62 = t7.c76;
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t2 ALL NULL NULL NULL NULL 6
@@ -409,7 +409,7 @@ id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t7 eq_ref PRIMARY PRIMARY 4 test.t1.c16 1 Using where
show status like 'Last_query_cost';
Variable_name Value
-Last_query_cost 274.418727
+Last_query_cost 289.418727
explain select t1.c11 from t7, t6, t5, t4, t3, t2, t1 where t1.c11 = t2.c21 and t1.c12 = t3.c31 and t1.c13 = t4.c41 and t1.c14 = t5.c51 and t1.c15 = t6.c61 and t1.c16 = t7.c71 and t2.c22 = t3.c32 and t2.c23 = t4.c42 and t2.c24 = t5.c52 and t2.c25 = t6.c62 and t2.c26 = t7.c72 and t3.c33 = t4.c43 and t3.c34 = t5.c53 and t3.c35 = t6.c63 and t3.c36 = t7.c73 and t4.c42 = t5.c54 and t4.c43 = t6.c64 and t4.c44 = t7.c74 and t5.c52 = t6.c65 and t5.c53 = t7.c75 and t6.c62 = t7.c76;
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t2 ALL NULL NULL NULL NULL 6
@@ -421,7 +421,7 @@ id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t7 eq_ref PRIMARY PRIMARY 4 test.t1.c16 1 Using where
show status like 'Last_query_cost';
Variable_name Value
-Last_query_cost 274.418727
+Last_query_cost 289.418727
set optimizer_prune_level=1;
select @@optimizer_prune_level;
@@optimizer_prune_level
diff --git a/mysql-test/r/have_ndb_status_ok.require b/mysql-test/r/have_ndb_status_ok.require
deleted file mode 100644
index 8a82871234b..00000000000
--- a/mysql-test/r/have_ndb_status_ok.require
+++ /dev/null
@@ -1,2 +0,0 @@
-ndb_status_ok
-YES
diff --git a/mysql-test/r/im_daemon_life_cycle.result b/mysql-test/r/im_daemon_life_cycle.result
index 86b196659bf..eee8479888a 100644
--- a/mysql-test/r/im_daemon_life_cycle.result
+++ b/mysql-test/r/im_daemon_life_cycle.result
@@ -8,3 +8,17 @@ mysqld2 offline
Killing the process...
Sleeping...
Success: the process was restarted.
+
+--------------------------------------------------------------------
+-- Test for BUG#12751
+--------------------------------------------------------------------
+START INSTANCE mysqld2;
+Success: the process has been started.
+Killing the process...
+Sleeping...
+Success: the process was restarted.
+SHOW INSTANCE STATUS mysqld1;
+instance_name state version_number version mysqld_compatible
+mysqld1 online VERSION_NUMBER VERSION no
+STOP INSTANCE mysqld2;
+Success: the process has been stopped.
diff --git a/mysql-test/r/join.result b/mysql-test/r/join.result
index 75daa0fd46d..897ec4f7a6a 100644
--- a/mysql-test/r/join.result
+++ b/mysql-test/r/join.result
@@ -776,3 +776,31 @@ id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t2 ALL a,b NULL NULL NULL 1000 Using where
1 SIMPLE t3 ref b b 5 test.t2.b 1 Using where
drop table t1, t2, t3;
+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, primary key(a));
+insert into t2 select @v:=A.a+10*B.a, @v from t1 A, t1 B;
+explain select * from t1;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 ALL NULL NULL NULL NULL 10
+show status like '%cost%';
+Variable_name Value
+Last_query_cost 4.016090
+select 'The cost of accessing t1 (dont care if it changes' '^';
+The cost of accessing t1 (dont care if it changes
+The cost of accessing t1 (dont care if it changes^
+select 'vv: Following query must use ALL(t1), eq_ref(A), eq_ref(B): vv' Z;
+Z
+vv: Following query must use ALL(t1), eq_ref(A), eq_ref(B): vv
+explain select * from t1, t2 A, t2 B where A.a = t1.a and B.a=A.b;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 ALL NULL NULL NULL NULL 10
+1 SIMPLE A eq_ref PRIMARY PRIMARY 4 test.t1.a 1
+1 SIMPLE B eq_ref PRIMARY PRIMARY 4 test.A.b 1
+show status like '%cost%';
+Variable_name Value
+Last_query_cost 24.016090
+select '^^: The above should be ~= 20 + cost(select * from t1). Value less than 20 is an error' Z;
+Z
+^^: The above should be ~= 20 + cost(select * from t1). Value less than 20 is an error
+drop table t1, t2;
diff --git a/mysql-test/r/loaddata.result b/mysql-test/r/loaddata.result
index 72beee4b2e3..481b3de9f02 100644
--- a/mysql-test/r/loaddata.result
+++ b/mysql-test/r/loaddata.result
@@ -43,9 +43,9 @@ drop table t1;
create table t1 (a int, b char(10));
load data infile '../std_data_ln/loaddata3.dat' into table t1 fields terminated by '' enclosed by '' ignore 1 lines;
Warnings:
-Warning 1264 Out of range value for column 'a' at row 3
+Warning 1366 Incorrect integer value: 'error ' for column 'a' at row 3
Warning 1262 Row 3 was truncated; it contained more data than there were input columns
-Warning 1264 Out of range value for column 'a' at row 5
+Warning 1366 Incorrect integer value: 'wrong end ' for column 'a' at row 5
Warning 1262 Row 5 was truncated; it contained more data than there were input columns
select * from t1;
a b
@@ -57,7 +57,8 @@ a b
truncate table t1;
load data infile '../std_data_ln/loaddata4.dat' into table t1 fields terminated by '' enclosed by '' lines terminated by '' ignore 1 lines;
Warnings:
-Warning 1264 Out of range value for column 'a' at row 4
+Warning 1366 Incorrect integer value: '
+' for column 'a' at row 4
Warning 1261 Row 4 doesn't contain data for all columns
select * from t1;
a b
diff --git a/mysql-test/r/log_tables.result b/mysql-test/r/log_tables.result
index 33f6c0c7af2..a9683cc7c56 100644
--- a/mysql-test/r/log_tables.result
+++ b/mysql-test/r/log_tables.result
@@ -112,8 +112,8 @@ slow_log CREATE TABLE `slow_log` (
alter table mysql.general_log engine=myisam;
alter table mysql.slow_log engine=myisam;
Warnings:
-Warning 1264 Out of range value for column 'last_insert_id' at row 0
-Warning 1264 Out of range value for column 'insert_id' at row 0
+Warning 1366 Incorrect integer value: '' for column 'last_insert_id' at row 0
+Warning 1366 Incorrect integer value: '' for column 'insert_id' at row 0
show create table mysql.general_log;
Table Create Table
general_log CREATE TABLE `general_log` (
diff --git a/mysql-test/r/merge.result b/mysql-test/r/merge.result
index db2c462398f..1e0207683ee 100644
--- a/mysql-test/r/merge.result
+++ b/mysql-test/r/merge.result
@@ -178,12 +178,12 @@ t3 CREATE TABLE `t3` (
) ENGINE=MRG_MyISAM DEFAULT CHARSET=latin1 UNION=(`t1`,`t2`)
create table t4 (a int not null, b char(10), key(a)) engine=MERGE UNION=(t1,t2);
select * from t4;
-ERROR HY000: All tables in the MERGE table are not identically defined
+ERROR HY000: Unable to open underlying table which is differently defined or of non-MyISAM type or doesn't exist
alter table t4 add column c int;
-ERROR HY000: All tables in the MERGE table are not identically defined
+ERROR HY000: Unable to open underlying table which is differently defined or of non-MyISAM type or doesn't exist
flush tables;
select * from t4;
-ERROR HY000: All tables in the MERGE table are not identically defined
+ERROR HY000: Unable to open underlying table which is differently defined or of non-MyISAM type or doesn't exist
create database mysqltest;
create table mysqltest.t6 (a int not null primary key auto_increment, message char(20));
create table t5 (a int not null, b char(20), key(a)) engine=MERGE UNION=(test.t1,mysqltest.t6);
@@ -277,7 +277,7 @@ t3 CREATE TABLE `t3` (
drop table t3,t2,t1;
create table t1 (a int not null, key(a)) engine=merge;
select * from t1;
-a
+ERROR HY000: Got error 124 from storage engine
drop table t1;
create table t1 (a int not null, b int not null, key(a,b));
create table t2 (a int not null, b int not null, key(a,b));
@@ -771,6 +771,21 @@ Table Op Msg_type Msg_text
test.t1 check status OK
test.t2 check status OK
drop table t1, t2, t3;
+CREATE TABLE t1(a INT);
+INSERT INTO t1 VALUES(2),(1);
+CREATE TABLE t2(a INT, KEY(a)) ENGINE=MERGE UNION=(t1);
+SELECT * FROM t2 WHERE a=2;
+ERROR HY000: Got error 124 from storage engine
+DROP TABLE t1, t2;
+CREATE TABLE t1(a INT) ENGINE=MEMORY;
+CREATE TABLE t2(a INT) ENGINE=MERGE UNION=(t1);
+SELECT * FROM t2;
+ERROR HY000: Unable to open underlying table which is differently defined or of non-MyISAM type or doesn't exist
+DROP TABLE t1, t2;
+CREATE TABLE t2(a INT) ENGINE=MERGE UNION=(t3);
+SELECT * FROM t2;
+ERROR HY000: Unable to open underlying table which is differently defined or of non-MyISAM type or doesn't exist
+DROP TABLE t2;
create table t1 (b bit(1));
create table t2 (b bit(1));
create table tm (b bit(1)) engine = merge union = (t1,t2);
diff --git a/mysql-test/r/mysql.result b/mysql-test/r/mysql.result
index 7dbff4beca5..1053b1918fb 100644
--- a/mysql-test/r/mysql.result
+++ b/mysql-test/r/mysql.result
@@ -76,6 +76,16 @@ c_cp932
| >a < | 0123456789 | 4 |
| >abcd< | | 4 |
+----------------------+------------+--------+
++-------------------+
+| __tañgè Ñãmé |
++-------------------+
+| John Doe |
++-------------------+
++-------------------+
+| John Doe |
++-------------------+
+| __tañgè Ñãmé |
++-------------------+
+------+------+---------------------------+
| i | j | k |
+------+------+---------------------------+
diff --git a/mysql-test/r/mysqltest.result b/mysql-test/r/mysqltest.result
index 10c89effa8b..ce9fb6941f3 100644
--- a/mysql-test/r/mysqltest.result
+++ b/mysql-test/r/mysqltest.result
@@ -217,8 +217,11 @@ hej
a long variable content
a long variable content
-a long $where variable content
+a long a long variable content variable content
+a long \$where variable content
+banana = banana
+Not a banana: ba\$cat\$cat
mysqltest: At line 1: Missing arguments to let
mysqltest: At line 1: Missing variable name in let
mysqltest: At line 1: Missing assignment operator in let
diff --git a/mysql-test/r/ndb_config.result b/mysql-test/r/ndb_config.result
index c364b8f1b5d..9495af29df6 100644
--- a/mysql-test/r/ndb_config.result
+++ b/mysql-test/r/ndb_config.result
@@ -8,3 +8,7 @@ ndbd,1,localhost,52428800,26214400 ndbd,2,localhost,52428800,36700160 ndbd,3,loc
ndbd,1,localhost ndbd,2,localhost ndbd,3,localhost ndbd,4,localhost ndb_mgmd,5,localhost mysqld,6, mysqld,7, mysqld,8, mysqld,9, mysqld,10,
ndbd,2,localhost ndbd,3,localhost ndbd,4,localhost ndbd,5,localhost ndb_mgmd,6,localhost mysqld,1, mysqld,7, mysqld,8, mysqld,9, mysqld,10,
ndbd,3,localhost ndbd,4,localhost ndbd,5,localhost ndbd,6,localhost ndb_mgmd,1,localhost ndb_mgmd,2,localhost mysqld,11, mysqld,12, mysqld,13, mysqld,14, mysqld,15,
+shm,3,4,35,3 shm,3,5,35,3 shm,3,6,35,3 shm,4,5,35,4 shm,4,6,35,4 shm,5,6,35,5 tcp,11,3,55,3 tcp,11,4,55,4 tcp,11,5,55,5 tcp,11,6,55,6 tcp,12,3,55,3 tcp,12,4,55,4 tcp,12,5,55,5 tcp,12,6,55,6 tcp,13,3,55,3 tcp,13,4,55,4 tcp,13,5,55,5 tcp,13,6,55,6 tcp,14,3,55,3 tcp,14,4,55,4 tcp,14,5,55,5 tcp,14,6,55,6 tcp,15,3,55,3 tcp,15,4,55,4 tcp,15,5,55,5 tcp,15,6,55,6 tcp,1,3,55,1 tcp,1,4,55,1 tcp,1,5,55,1 tcp,1,6,55,1 tcp,2,3,55,2 tcp,2,4,55,2 tcp,2,5,55,2 tcp,2,6,55,2
+1 2 3
+
+1 2 3
diff --git a/mysql-test/r/order_by.result b/mysql-test/r/order_by.result
index 64653de5e9c..6461696b0d0 100644
--- a/mysql-test/r/order_by.result
+++ b/mysql-test/r/order_by.result
@@ -495,17 +495,17 @@ gid sid uid
103853 5 250
EXPLAIN select t1.gid, t2.sid, t3.uid from t3, t2, t1 where t2.gid = t1.gid and t2.uid = t3.uid order by t1.gid, t3.uid;
id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 index PRIMARY PRIMARY 4 NULL 6 Using index
-1 SIMPLE t2 eq_ref PRIMARY,uid PRIMARY 4 test.t1.gid 1
+1 SIMPLE t2 ALL PRIMARY,uid NULL NULL NULL 6 Using temporary; Using filesort
1 SIMPLE t3 eq_ref PRIMARY PRIMARY 2 test.t2.uid 1 Using where; Using index
+1 SIMPLE t1 eq_ref PRIMARY PRIMARY 4 test.t2.gid 1 Using index
EXPLAIN SELECT t1.gid, t3.uid from t1, t3 where t1.gid = t3.uid order by t1.gid,t3.skr;
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t3 ALL PRIMARY NULL NULL NULL 6 Using temporary; Using filesort
1 SIMPLE t1 eq_ref PRIMARY PRIMARY 4 test.t3.uid 1 Using where; Using index
EXPLAIN SELECT t1.gid, t2.sid, t3.uid from t2, t1, t3 where t2.gid = t1.gid and t2.uid = t3.uid order by t3.uid, t1.gid;
id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 index PRIMARY PRIMARY 4 NULL 6 Using index; Using temporary; Using filesort
-1 SIMPLE t2 eq_ref PRIMARY,uid PRIMARY 4 test.t1.gid 1
+1 SIMPLE t2 ALL PRIMARY,uid NULL NULL NULL 6 Using temporary; Using filesort
+1 SIMPLE t1 eq_ref PRIMARY PRIMARY 4 test.t2.gid 1 Using index
1 SIMPLE t3 eq_ref PRIMARY PRIMARY 2 test.t2.uid 1 Using where; Using index
EXPLAIN SELECT t1.gid, t3.uid from t1, t3 where t1.gid = t3.uid order by t3.skr,t1.gid;
id select_type table type possible_keys key key_len ref rows Extra
diff --git a/mysql-test/r/partition.result b/mysql-test/r/partition.result
index 36f3610efe1..f3e44a1df60 100644
--- a/mysql-test/r/partition.result
+++ b/mysql-test/r/partition.result
@@ -2,7 +2,7 @@ drop table if exists t1;
create table t1 (a int)
partition by key(a)
partitions 0.2+e1;
-ERROR 42000: Only normal integers allowed as number here near '0.2+e1' at line 3
+ERROR 42000: Only integers allowed as number here near '0.2+e1' at line 3
create table t1 (a int)
partition by key(a)
partitions -1;
@@ -10,11 +10,11 @@ ERROR 42000: You have an error in your SQL syntax; check the manual that corresp
create table t1 (a int)
partition by key(a)
partitions 1.5;
-ERROR 42000: Only normal integers allowed as number here near '1.5' at line 3
+ERROR 42000: Only integers allowed as number here near '1.5' at line 3
create table t1 (a int)
partition by key(a)
partitions 1e+300;
-ERROR 42000: Only normal integers allowed as number here near '1e+300' at line 3
+ERROR 42000: Only integers allowed as number here near '1e+300' at line 3
create table t1 (a int)
partition by key (a)
(partition p0 DATA DIRECTORY 'part-data' INDEX DIRECTORY 'part-data');
@@ -37,7 +37,7 @@ create table t1 (a int)
engine = csv
partition by list (a)
(partition p0 values in (null));
-ERROR HY000: CSV handler cannot be used in partitioned tables
+ERROR HY000: Engine cannot be used in partitioned tables
create table t1 (a bigint)
partition by range (a)
(partition p0 values less than (0xFFFFFFFFFFFFFFFF),
@@ -71,7 +71,7 @@ create table t1 (a int)
engine = csv
partition by list (a)
(partition p0 values in (null));
-ERROR HY000: CSV handler cannot be used in partitioned tables
+ERROR HY000: Engine cannot be used in partitioned tables
create table t1 (a int)
partition by key(a)
(partition p0 engine = MEMORY);
@@ -1012,7 +1012,7 @@ drop table t1;
create table t1 (a int)
partition by key (a)
(partition p0 engine = MERGE);
-ERROR HY000: MyISAM Merge handler cannot be used in partitioned tables
+ERROR HY000: Engine cannot be used in partitioned tables
create table t1 (a varchar(1))
partition by key (a)
as select 'a';
diff --git a/mysql-test/r/ps.result b/mysql-test/r/ps.result
index e6bbd3f3124..b7dae03bf47 100644
--- a/mysql-test/r/ps.result
+++ b/mysql-test/r/ps.result
@@ -499,6 +499,54 @@ create temporary table if not exists t1 (a1 int);
execute stmt;
drop temporary table t1;
deallocate prepare stmt;
+CREATE TABLE t1(
+ID int(10) unsigned NOT NULL auto_increment,
+Member_ID varchar(15) NOT NULL default '',
+Action varchar(12) NOT NULL,
+Action_Date datetime NOT NULL,
+Track varchar(15) default NULL,
+User varchar(12) default NULL,
+Date_Updated timestamp NOT NULL default CURRENT_TIMESTAMP on update
+CURRENT_TIMESTAMP,
+PRIMARY KEY (ID),
+KEY Action (Action),
+KEY Action_Date (Action_Date)
+);
+INSERT INTO t1(Member_ID, Action, Action_Date, Track) VALUES
+('111111', 'Disenrolled', '2006-03-01', 'CAD' ),
+('111111', 'Enrolled', '2006-03-01', 'CAD' ),
+('111111', 'Disenrolled', '2006-07-03', 'CAD' ),
+('222222', 'Enrolled', '2006-03-07', 'CAD' ),
+('222222', 'Enrolled', '2006-03-07', 'CHF' ),
+('222222', 'Disenrolled', '2006-08-02', 'CHF' ),
+('333333', 'Enrolled', '2006-03-01', 'CAD' ),
+('333333', 'Disenrolled', '2006-03-01', 'CAD' ),
+('444444', 'Enrolled', '2006-03-01', 'CAD' ),
+('555555', 'Disenrolled', '2006-03-01', 'CAD' ),
+('555555', 'Enrolled', '2006-07-21', 'CAD' ),
+('555555', 'Disenrolled', '2006-03-01', 'CHF' ),
+('666666', 'Enrolled', '2006-02-09', 'CAD' ),
+('666666', 'Enrolled', '2006-05-12', 'CHF' ),
+('666666', 'Disenrolled', '2006-06-01', 'CAD' );
+PREPARE STMT FROM
+"SELECT GROUP_CONCAT(Track SEPARATOR ', ') FROM t1
+ WHERE Member_ID=? AND Action='Enrolled' AND
+ (Track,Action_Date) IN (SELECT Track, MAX(Action_Date) FROM t1
+ WHERE Member_ID=?
+ GROUP BY Track
+ HAVING Track>='CAD' AND
+ MAX(Action_Date)>'2006-03-01')";
+SET @id='111111';
+EXECUTE STMT USING @id,@id;
+GROUP_CONCAT(Track SEPARATOR ', ')
+NULL
+SET @id='222222';
+EXECUTE STMT USING @id,@id;
+GROUP_CONCAT(Track SEPARATOR ', ')
+CAD
+DEALLOCATE PREPARE STMT;
+DROP TABLE t1;
+End of 4.1 tests
create table t1 (a varchar(20));
insert into t1 values ('foo');
prepare stmt FROM 'SELECT char_length (a) FROM t1';
@@ -1291,6 +1339,27 @@ EXECUTE stmt USING @a;
i j i i j
DEALLOCATE PREPARE stmt;
DROP TABLE IF EXISTS t1, t2, t3;
+DROP TABLE IF EXISTS t1, t2;
+CREATE TABLE t1 (i INT KEY);
+CREATE TABLE t2 (i INT);
+INSERT INTO t1 VALUES (1), (2);
+INSERT INTO t2 VALUES (1);
+PREPARE stmt FROM "SELECT t2.i FROM t1 LEFT JOIN t2 ON t2.i = t1.i
+ WHERE t1.i = ?";
+SET @arg= 1;
+EXECUTE stmt USING @arg;
+i
+1
+SET @arg= 2;
+EXECUTE stmt USING @arg;
+i
+NULL
+SET @arg= 1;
+EXECUTE stmt USING @arg;
+i
+1
+DEALLOCATE PREPARE stmt;
+DROP TABLE t1, t2;
End of 5.0 tests.
create procedure proc_1() reset query cache;
call proc_1();
diff --git a/mysql-test/r/ps_2myisam.result b/mysql-test/r/ps_2myisam.result
index 783cca04383..2bfd6d31ac9 100644
--- a/mysql-test/r/ps_2myisam.result
+++ b/mysql-test/r/ps_2myisam.result
@@ -2689,21 +2689,21 @@ set @arg00= '1.11111111111111111111e+50' ;
execute my_insert using @arg00, @arg00, @arg00, @arg00, @arg00, @arg00,
@arg00, @arg00, @arg00, @arg00, @arg00 ;
Warnings:
-Warning 1265 Data truncated for column 'c1' at row 1
-Warning 1265 Data truncated for column 'c2' at row 1
-Warning 1265 Data truncated for column 'c3' at row 1
-Warning 1265 Data truncated for column 'c4' at row 1
-Warning 1265 Data truncated for column 'c5' at row 1
-Warning 1265 Data truncated for column 'c6' at row 1
+Warning 1264 Out of range value for column 'c1' at row 1
+Warning 1264 Out of range value for column 'c2' at row 1
+Warning 1264 Out of range value for column 'c3' at row 1
+Warning 1264 Out of range value for column 'c4' at row 1
+Warning 1264 Out of range value for column 'c5' at row 1
+Warning 1264 Out of range value for column 'c6' at row 1
Warning 1264 Out of range value for column 'c7' at row 1
Warning 1264 Out of range value for column 'c12' at row 1
execute my_select ;
-c1 1
-c2 1
-c3 1
-c4 1
-c5 1
-c6 1
+c1 127
+c2 32767
+c3 8388607
+c4 2147483647
+c5 2147483647
+c6 9223372036854775807
c7 3.40282e+38
c8 1.11111111111111e+50
c9 1.11111111111111e+50
@@ -2739,21 +2739,21 @@ set @arg00= '-1.11111111111111111111e+50' ;
execute my_insert using @arg00, @arg00, @arg00, @arg00, @arg00, @arg00,
@arg00, @arg00, @arg00, @arg00, @arg00 ;
Warnings:
-Warning 1265 Data truncated for column 'c1' at row 1
-Warning 1265 Data truncated for column 'c2' at row 1
-Warning 1265 Data truncated for column 'c3' at row 1
-Warning 1265 Data truncated for column 'c4' at row 1
-Warning 1265 Data truncated for column 'c5' at row 1
-Warning 1265 Data truncated for column 'c6' at row 1
+Warning 1264 Out of range value for column 'c1' at row 1
+Warning 1264 Out of range value for column 'c2' at row 1
+Warning 1264 Out of range value for column 'c3' at row 1
+Warning 1264 Out of range value for column 'c4' at row 1
+Warning 1264 Out of range value for column 'c5' at row 1
+Warning 1264 Out of range value for column 'c6' at row 1
Warning 1264 Out of range value for column 'c7' at row 1
Warning 1264 Out of range value for column 'c12' at row 1
execute my_select ;
-c1 -1
-c2 -1
-c3 -1
-c4 -1
-c5 -1
-c6 -1
+c1 -128
+c2 -32768
+c3 -8388608
+c4 -2147483648
+c5 -2147483648
+c6 -9223372036854775808
c7 -3.40282e+38
c8 -1.11111111111111e+50
c9 -1.11111111111111e+50
diff --git a/mysql-test/r/ps_3innodb.result b/mysql-test/r/ps_3innodb.result
index d87d23d941f..607a0426bd7 100644
--- a/mysql-test/r/ps_3innodb.result
+++ b/mysql-test/r/ps_3innodb.result
@@ -2672,21 +2672,21 @@ set @arg00= '1.11111111111111111111e+50' ;
execute my_insert using @arg00, @arg00, @arg00, @arg00, @arg00, @arg00,
@arg00, @arg00, @arg00, @arg00, @arg00 ;
Warnings:
-Warning 1265 Data truncated for column 'c1' at row 1
-Warning 1265 Data truncated for column 'c2' at row 1
-Warning 1265 Data truncated for column 'c3' at row 1
-Warning 1265 Data truncated for column 'c4' at row 1
-Warning 1265 Data truncated for column 'c5' at row 1
-Warning 1265 Data truncated for column 'c6' at row 1
+Warning 1264 Out of range value for column 'c1' at row 1
+Warning 1264 Out of range value for column 'c2' at row 1
+Warning 1264 Out of range value for column 'c3' at row 1
+Warning 1264 Out of range value for column 'c4' at row 1
+Warning 1264 Out of range value for column 'c5' at row 1
+Warning 1264 Out of range value for column 'c6' at row 1
Warning 1264 Out of range value for column 'c7' at row 1
Warning 1264 Out of range value for column 'c12' at row 1
execute my_select ;
-c1 1
-c2 1
-c3 1
-c4 1
-c5 1
-c6 1
+c1 127
+c2 32767
+c3 8388607
+c4 2147483647
+c5 2147483647
+c6 9223372036854775807
c7 3.40282e+38
c8 1.11111111111111e+50
c9 1.11111111111111e+50
@@ -2722,21 +2722,21 @@ set @arg00= '-1.11111111111111111111e+50' ;
execute my_insert using @arg00, @arg00, @arg00, @arg00, @arg00, @arg00,
@arg00, @arg00, @arg00, @arg00, @arg00 ;
Warnings:
-Warning 1265 Data truncated for column 'c1' at row 1
-Warning 1265 Data truncated for column 'c2' at row 1
-Warning 1265 Data truncated for column 'c3' at row 1
-Warning 1265 Data truncated for column 'c4' at row 1
-Warning 1265 Data truncated for column 'c5' at row 1
-Warning 1265 Data truncated for column 'c6' at row 1
+Warning 1264 Out of range value for column 'c1' at row 1
+Warning 1264 Out of range value for column 'c2' at row 1
+Warning 1264 Out of range value for column 'c3' at row 1
+Warning 1264 Out of range value for column 'c4' at row 1
+Warning 1264 Out of range value for column 'c5' at row 1
+Warning 1264 Out of range value for column 'c6' at row 1
Warning 1264 Out of range value for column 'c7' at row 1
Warning 1264 Out of range value for column 'c12' at row 1
execute my_select ;
-c1 -1
-c2 -1
-c3 -1
-c4 -1
-c5 -1
-c6 -1
+c1 -128
+c2 -32768
+c3 -8388608
+c4 -2147483648
+c5 -2147483648
+c6 -9223372036854775808
c7 -3.40282e+38
c8 -1.11111111111111e+50
c9 -1.11111111111111e+50
diff --git a/mysql-test/r/ps_4heap.result b/mysql-test/r/ps_4heap.result
index f90e06692d4..f4eec0c610c 100644
--- a/mysql-test/r/ps_4heap.result
+++ b/mysql-test/r/ps_4heap.result
@@ -2673,21 +2673,21 @@ set @arg00= '1.11111111111111111111e+50' ;
execute my_insert using @arg00, @arg00, @arg00, @arg00, @arg00, @arg00,
@arg00, @arg00, @arg00, @arg00, @arg00 ;
Warnings:
-Warning 1265 Data truncated for column 'c1' at row 1
-Warning 1265 Data truncated for column 'c2' at row 1
-Warning 1265 Data truncated for column 'c3' at row 1
-Warning 1265 Data truncated for column 'c4' at row 1
-Warning 1265 Data truncated for column 'c5' at row 1
-Warning 1265 Data truncated for column 'c6' at row 1
+Warning 1264 Out of range value for column 'c1' at row 1
+Warning 1264 Out of range value for column 'c2' at row 1
+Warning 1264 Out of range value for column 'c3' at row 1
+Warning 1264 Out of range value for column 'c4' at row 1
+Warning 1264 Out of range value for column 'c5' at row 1
+Warning 1264 Out of range value for column 'c6' at row 1
Warning 1264 Out of range value for column 'c7' at row 1
Warning 1264 Out of range value for column 'c12' at row 1
execute my_select ;
-c1 1
-c2 1
-c3 1
-c4 1
-c5 1
-c6 1
+c1 127
+c2 32767
+c3 8388607
+c4 2147483647
+c5 2147483647
+c6 9223372036854775807
c7 3.40282e+38
c8 1.11111111111111e+50
c9 1.11111111111111e+50
@@ -2723,21 +2723,21 @@ set @arg00= '-1.11111111111111111111e+50' ;
execute my_insert using @arg00, @arg00, @arg00, @arg00, @arg00, @arg00,
@arg00, @arg00, @arg00, @arg00, @arg00 ;
Warnings:
-Warning 1265 Data truncated for column 'c1' at row 1
-Warning 1265 Data truncated for column 'c2' at row 1
-Warning 1265 Data truncated for column 'c3' at row 1
-Warning 1265 Data truncated for column 'c4' at row 1
-Warning 1265 Data truncated for column 'c5' at row 1
-Warning 1265 Data truncated for column 'c6' at row 1
+Warning 1264 Out of range value for column 'c1' at row 1
+Warning 1264 Out of range value for column 'c2' at row 1
+Warning 1264 Out of range value for column 'c3' at row 1
+Warning 1264 Out of range value for column 'c4' at row 1
+Warning 1264 Out of range value for column 'c5' at row 1
+Warning 1264 Out of range value for column 'c6' at row 1
Warning 1264 Out of range value for column 'c7' at row 1
Warning 1264 Out of range value for column 'c12' at row 1
execute my_select ;
-c1 -1
-c2 -1
-c3 -1
-c4 -1
-c5 -1
-c6 -1
+c1 -128
+c2 -32768
+c3 -8388608
+c4 -2147483648
+c5 -2147483648
+c6 -9223372036854775808
c7 -3.40282e+38
c8 -1.11111111111111e+50
c9 -1.11111111111111e+50
diff --git a/mysql-test/r/ps_5merge.result b/mysql-test/r/ps_5merge.result
index adcc272727a..38e4626d59c 100644
--- a/mysql-test/r/ps_5merge.result
+++ b/mysql-test/r/ps_5merge.result
@@ -2609,21 +2609,21 @@ set @arg00= '1.11111111111111111111e+50' ;
execute my_insert using @arg00, @arg00, @arg00, @arg00, @arg00, @arg00,
@arg00, @arg00, @arg00, @arg00, @arg00 ;
Warnings:
-Warning 1265 Data truncated for column 'c1' at row 1
-Warning 1265 Data truncated for column 'c2' at row 1
-Warning 1265 Data truncated for column 'c3' at row 1
-Warning 1265 Data truncated for column 'c4' at row 1
-Warning 1265 Data truncated for column 'c5' at row 1
-Warning 1265 Data truncated for column 'c6' at row 1
+Warning 1264 Out of range value for column 'c1' at row 1
+Warning 1264 Out of range value for column 'c2' at row 1
+Warning 1264 Out of range value for column 'c3' at row 1
+Warning 1264 Out of range value for column 'c4' at row 1
+Warning 1264 Out of range value for column 'c5' at row 1
+Warning 1264 Out of range value for column 'c6' at row 1
Warning 1264 Out of range value for column 'c7' at row 1
Warning 1264 Out of range value for column 'c12' at row 1
execute my_select ;
-c1 1
-c2 1
-c3 1
-c4 1
-c5 1
-c6 1
+c1 127
+c2 32767
+c3 8388607
+c4 2147483647
+c5 2147483647
+c6 9223372036854775807
c7 3.40282e+38
c8 1.11111111111111e+50
c9 1.11111111111111e+50
@@ -2659,21 +2659,21 @@ set @arg00= '-1.11111111111111111111e+50' ;
execute my_insert using @arg00, @arg00, @arg00, @arg00, @arg00, @arg00,
@arg00, @arg00, @arg00, @arg00, @arg00 ;
Warnings:
-Warning 1265 Data truncated for column 'c1' at row 1
-Warning 1265 Data truncated for column 'c2' at row 1
-Warning 1265 Data truncated for column 'c3' at row 1
-Warning 1265 Data truncated for column 'c4' at row 1
-Warning 1265 Data truncated for column 'c5' at row 1
-Warning 1265 Data truncated for column 'c6' at row 1
+Warning 1264 Out of range value for column 'c1' at row 1
+Warning 1264 Out of range value for column 'c2' at row 1
+Warning 1264 Out of range value for column 'c3' at row 1
+Warning 1264 Out of range value for column 'c4' at row 1
+Warning 1264 Out of range value for column 'c5' at row 1
+Warning 1264 Out of range value for column 'c6' at row 1
Warning 1264 Out of range value for column 'c7' at row 1
Warning 1264 Out of range value for column 'c12' at row 1
execute my_select ;
-c1 -1
-c2 -1
-c3 -1
-c4 -1
-c5 -1
-c6 -1
+c1 -128
+c2 -32768
+c3 -8388608
+c4 -2147483648
+c5 -2147483648
+c6 -9223372036854775808
c7 -3.40282e+38
c8 -1.11111111111111e+50
c9 -1.11111111111111e+50
@@ -5623,21 +5623,21 @@ set @arg00= '1.11111111111111111111e+50' ;
execute my_insert using @arg00, @arg00, @arg00, @arg00, @arg00, @arg00,
@arg00, @arg00, @arg00, @arg00, @arg00 ;
Warnings:
-Warning 1265 Data truncated for column 'c1' at row 1
-Warning 1265 Data truncated for column 'c2' at row 1
-Warning 1265 Data truncated for column 'c3' at row 1
-Warning 1265 Data truncated for column 'c4' at row 1
-Warning 1265 Data truncated for column 'c5' at row 1
-Warning 1265 Data truncated for column 'c6' at row 1
+Warning 1264 Out of range value for column 'c1' at row 1
+Warning 1264 Out of range value for column 'c2' at row 1
+Warning 1264 Out of range value for column 'c3' at row 1
+Warning 1264 Out of range value for column 'c4' at row 1
+Warning 1264 Out of range value for column 'c5' at row 1
+Warning 1264 Out of range value for column 'c6' at row 1
Warning 1264 Out of range value for column 'c7' at row 1
Warning 1264 Out of range value for column 'c12' at row 1
execute my_select ;
-c1 1
-c2 1
-c3 1
-c4 1
-c5 1
-c6 1
+c1 127
+c2 32767
+c3 8388607
+c4 2147483647
+c5 2147483647
+c6 9223372036854775807
c7 3.40282e+38
c8 1.11111111111111e+50
c9 1.11111111111111e+50
@@ -5673,21 +5673,21 @@ set @arg00= '-1.11111111111111111111e+50' ;
execute my_insert using @arg00, @arg00, @arg00, @arg00, @arg00, @arg00,
@arg00, @arg00, @arg00, @arg00, @arg00 ;
Warnings:
-Warning 1265 Data truncated for column 'c1' at row 1
-Warning 1265 Data truncated for column 'c2' at row 1
-Warning 1265 Data truncated for column 'c3' at row 1
-Warning 1265 Data truncated for column 'c4' at row 1
-Warning 1265 Data truncated for column 'c5' at row 1
-Warning 1265 Data truncated for column 'c6' at row 1
+Warning 1264 Out of range value for column 'c1' at row 1
+Warning 1264 Out of range value for column 'c2' at row 1
+Warning 1264 Out of range value for column 'c3' at row 1
+Warning 1264 Out of range value for column 'c4' at row 1
+Warning 1264 Out of range value for column 'c5' at row 1
+Warning 1264 Out of range value for column 'c6' at row 1
Warning 1264 Out of range value for column 'c7' at row 1
Warning 1264 Out of range value for column 'c12' at row 1
execute my_select ;
-c1 -1
-c2 -1
-c3 -1
-c4 -1
-c5 -1
-c6 -1
+c1 -128
+c2 -32768
+c3 -8388608
+c4 -2147483648
+c5 -2147483648
+c6 -9223372036854775808
c7 -3.40282e+38
c8 -1.11111111111111e+50
c9 -1.11111111111111e+50
diff --git a/mysql-test/r/ps_7ndb.result b/mysql-test/r/ps_7ndb.result
index 772848dcf38..9e0577f8ae2 100644
--- a/mysql-test/r/ps_7ndb.result
+++ b/mysql-test/r/ps_7ndb.result
@@ -2672,21 +2672,21 @@ set @arg00= '1.11111111111111111111e+50' ;
execute my_insert using @arg00, @arg00, @arg00, @arg00, @arg00, @arg00,
@arg00, @arg00, @arg00, @arg00, @arg00 ;
Warnings:
-Warning 1265 Data truncated for column 'c1' at row 1
-Warning 1265 Data truncated for column 'c2' at row 1
-Warning 1265 Data truncated for column 'c3' at row 1
-Warning 1265 Data truncated for column 'c4' at row 1
-Warning 1265 Data truncated for column 'c5' at row 1
-Warning 1265 Data truncated for column 'c6' at row 1
+Warning 1264 Out of range value for column 'c1' at row 1
+Warning 1264 Out of range value for column 'c2' at row 1
+Warning 1264 Out of range value for column 'c3' at row 1
+Warning 1264 Out of range value for column 'c4' at row 1
+Warning 1264 Out of range value for column 'c5' at row 1
+Warning 1264 Out of range value for column 'c6' at row 1
Warning 1264 Out of range value for column 'c7' at row 1
Warning 1264 Out of range value for column 'c12' at row 1
execute my_select ;
-c1 1
-c2 1
-c3 1
-c4 1
-c5 1
-c6 1
+c1 127
+c2 32767
+c3 8388607
+c4 2147483647
+c5 2147483647
+c6 9223372036854775807
c7 3.40282e+38
c8 1.11111111111111e+50
c9 1.11111111111111e+50
@@ -2722,21 +2722,21 @@ set @arg00= '-1.11111111111111111111e+50' ;
execute my_insert using @arg00, @arg00, @arg00, @arg00, @arg00, @arg00,
@arg00, @arg00, @arg00, @arg00, @arg00 ;
Warnings:
-Warning 1265 Data truncated for column 'c1' at row 1
-Warning 1265 Data truncated for column 'c2' at row 1
-Warning 1265 Data truncated for column 'c3' at row 1
-Warning 1265 Data truncated for column 'c4' at row 1
-Warning 1265 Data truncated for column 'c5' at row 1
-Warning 1265 Data truncated for column 'c6' at row 1
+Warning 1264 Out of range value for column 'c1' at row 1
+Warning 1264 Out of range value for column 'c2' at row 1
+Warning 1264 Out of range value for column 'c3' at row 1
+Warning 1264 Out of range value for column 'c4' at row 1
+Warning 1264 Out of range value for column 'c5' at row 1
+Warning 1264 Out of range value for column 'c6' at row 1
Warning 1264 Out of range value for column 'c7' at row 1
Warning 1264 Out of range value for column 'c12' at row 1
execute my_select ;
-c1 -1
-c2 -1
-c3 -1
-c4 -1
-c5 -1
-c6 -1
+c1 -128
+c2 -32768
+c3 -8388608
+c4 -2147483648
+c5 -2147483648
+c6 -9223372036854775808
c7 -3.40282e+38
c8 -1.11111111111111e+50
c9 -1.11111111111111e+50
diff --git a/mysql-test/r/range.result b/mysql-test/r/range.result
index a7074b9a9ed..cfdee6e630e 100644
--- a/mysql-test/r/range.result
+++ b/mysql-test/r/range.result
@@ -941,3 +941,17 @@ item started price
A1 2005-11-01 08:00:00 1000.000
A1 2005-11-15 00:00:00 2000.000
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, filler char(100));
+insert into t2 select A.a + 10 * (B.a + 10 * C.a), 10, 'filler' from t1 A,
+t1 B, t1 C where A.a < 5;
+insert into t2 select 1000, b, 'filler' from t2;
+alter table t2 add index (a,b);
+select 'In following EXPLAIN the access method should be ref, #rows~=500 (and not 2)' Z;
+Z
+In following EXPLAIN the access method should be ref, #rows~=500 (and not 2)
+explain select * from t2 where a=1000 and b<11;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t2 ref a a 5 const 502 Using where
+drop table t1, t2;
diff --git a/mysql-test/r/round.result b/mysql-test/r/round.result
new file mode 100644
index 00000000000..49a00885f34
--- /dev/null
+++ b/mysql-test/r/round.result
@@ -0,0 +1,272 @@
+DROP TABLE IF EXISTS t1;
+CREATE TABLE t1 (sint8 tinyint not null);
+INSERT INTO t1 VALUES ('0.1');
+INSERT INTO t1 VALUES ('0.5');
+INSERT INTO t1 VALUES ('127.4');
+INSERT INTO t1 VALUES ('127.5');
+Warnings:
+Warning 1264 Out of range value for column 'sint8' at row 1
+INSERT INTO t1 VALUES ('-0.1');
+INSERT INTO t1 VALUES ('-0.5');
+INSERT INTO t1 VALUES ('-127.4');
+INSERT INTO t1 VALUES ('-127.5');
+INSERT INTO t1 VALUES ('-128.4');
+INSERT INTO t1 VALUES ('-128.5');
+Warnings:
+Warning 1264 Out of range value for column 'sint8' at row 1
+SELECT * FROM t1;
+sint8
+0
+1
+127
+127
+0
+-1
+-127
+-128
+-128
+-128
+DROP TABLE t1;
+CREATE TABLE t1 (uint8 tinyint unsigned not null);
+INSERT INTO t1 VALUES ('0.1');
+INSERT INTO t1 VALUES ('0.5');
+INSERT INTO t1 VALUES ('127.4');
+INSERT INTO t1 VALUES ('127.5');
+INSERT INTO t1 VALUES ('-0.1');
+INSERT INTO t1 VALUES ('-0.5');
+Warnings:
+Warning 1264 Out of range value for column 'uint8' at row 1
+INSERT INTO t1 VALUES ('255.4');
+INSERT INTO t1 VALUES ('255.5');
+Warnings:
+Warning 1264 Out of range value for column 'uint8' at row 1
+SELECT * FROM t1;
+uint8
+0
+1
+127
+128
+0
+0
+255
+255
+DROP TABLE t1;
+CREATE TABLE t1 (sint16 smallint not null);
+INSERT INTO t1 VALUES ('0.1');
+INSERT INTO t1 VALUES ('0.5');
+INSERT INTO t1 VALUES ('32767.4');
+INSERT INTO t1 VALUES ('32767.5');
+Warnings:
+Warning 1264 Out of range value for column 'sint16' at row 1
+INSERT INTO t1 VALUES ('-0.1');
+INSERT INTO t1 VALUES ('-0.5');
+INSERT INTO t1 VALUES ('-32767.4');
+INSERT INTO t1 VALUES ('-32767.5');
+INSERT INTO t1 VALUES ('-32768.4');
+INSERT INTO t1 VALUES ('-32768.5');
+Warnings:
+Warning 1264 Out of range value for column 'sint16' at row 1
+SELECT * FROM t1;
+sint16
+0
+1
+32767
+32767
+0
+-1
+-32767
+-32768
+-32768
+-32768
+DROP TABLE t1;
+CREATE TABLE t1 (uint16 smallint unsigned not null);
+INSERT INTO t1 VALUES ('0.1');
+INSERT INTO t1 VALUES ('0.5');
+INSERT INTO t1 VALUES ('32767.4');
+INSERT INTO t1 VALUES ('32767.5');
+INSERT INTO t1 VALUES ('-0.1');
+INSERT INTO t1 VALUES ('-0.5');
+Warnings:
+Warning 1264 Out of range value for column 'uint16' at row 1
+INSERT INTO t1 VALUES ('65535.4');
+INSERT INTO t1 VALUES ('65535.5');
+Warnings:
+Warning 1264 Out of range value for column 'uint16' at row 1
+SELECT * FROM t1;
+uint16
+0
+1
+32767
+32768
+0
+0
+65535
+65535
+DROP TABLE t1;
+CREATE TABLE t1 (sint24 mediumint not null);
+INSERT INTO t1 VALUES ('0.1');
+INSERT INTO t1 VALUES ('0.5');
+INSERT INTO t1 VALUES ('8388607.4');
+INSERT INTO t1 VALUES ('8388607.5');
+Warnings:
+Warning 1264 Out of range value for column 'sint24' at row 1
+INSERT INTO t1 VALUES ('-0.1');
+INSERT INTO t1 VALUES ('-0.5');
+INSERT INTO t1 VALUES ('-8388607.4');
+INSERT INTO t1 VALUES ('-8388607.5');
+INSERT INTO t1 VALUES ('-8388608.4');
+INSERT INTO t1 VALUES ('-8388608.5');
+Warnings:
+Warning 1264 Out of range value for column 'sint24' at row 1
+SELECT * FROM t1;
+sint24
+0
+1
+8388607
+8388607
+0
+-1
+-8388607
+-8388608
+-8388608
+-8388608
+DROP TABLE t1;
+CREATE TABLE t1 (uint24 mediumint unsigned not null);
+INSERT INTO t1 VALUES ('0.1');
+INSERT INTO t1 VALUES ('0.5');
+INSERT INTO t1 VALUES ('8388607.4');
+INSERT INTO t1 VALUES ('8388607.5');
+INSERT INTO t1 VALUES ('-0.1');
+INSERT INTO t1 VALUES ('-0.5');
+Warnings:
+Warning 1264 Out of range value for column 'uint24' at row 1
+INSERT INTO t1 VALUES ('16777215.4');
+INSERT INTO t1 VALUES ('16777215.5');
+Warnings:
+Warning 1264 Out of range value for column 'uint24' at row 1
+SELECT * FROM t1;
+uint24
+0
+1
+8388607
+8388608
+0
+0
+16777215
+16777215
+DROP TABLE t1;
+CREATE TABLE t1 (sint64 bigint not null);
+INSERT INTO t1 VALUES ('0.1');
+INSERT INTO t1 VALUES ('0.5');
+INSERT INTO t1 VALUES ('9223372036854775807.4');
+INSERT INTO t1 VALUES ('9223372036854775807.5');
+Warnings:
+Warning 1264 Out of range value for column 'sint64' at row 1
+INSERT INTO t1 VALUES ('-0.1');
+INSERT INTO t1 VALUES ('-0.5');
+INSERT INTO t1 VALUES ('-9223372036854775807.4');
+INSERT INTO t1 VALUES ('-9223372036854775807.5');
+INSERT INTO t1 VALUES ('-9223372036854775808.4');
+INSERT INTO t1 VALUES ('-9223372036854775808.5');
+Warnings:
+Warning 1264 Out of range value for column 'sint64' at row 1
+SELECT * FROM t1;
+sint64
+0
+1
+9223372036854775807
+9223372036854775807
+0
+-1
+-9223372036854775807
+-9223372036854775808
+-9223372036854775808
+-9223372036854775808
+DROP TABLE t1;
+CREATE TABLE t1 (uint64 bigint unsigned not null);
+INSERT INTO t1 VALUES ('0.1');
+INSERT INTO t1 VALUES ('0.5');
+INSERT INTO t1 VALUES ('9223372036854775807.4');
+INSERT INTO t1 VALUES ('9223372036854775807.5');
+INSERT INTO t1 VALUES ('-0.1');
+INSERT INTO t1 VALUES ('-0.5');
+Warnings:
+Warning 1264 Out of range value for column 'uint64' at row 1
+INSERT INTO t1 VALUES ('18446744073709551615.4');
+INSERT INTO t1 VALUES ('18446744073709551615.5');
+Warnings:
+Warning 1264 Out of range value for column 'uint64' at row 1
+INSERT INTO t1 VALUES ('1844674407370955161.0');
+INSERT INTO t1 VALUES ('1844674407370955161.1');
+INSERT INTO t1 VALUES ('1844674407370955161.2');
+INSERT INTO t1 VALUES ('1844674407370955161.3');
+INSERT INTO t1 VALUES ('1844674407370955161.4');
+INSERT INTO t1 VALUES ('1844674407370955161.5');
+INSERT INTO t1 VALUES ('1844674407370955161.0e1');
+INSERT INTO t1 VALUES ('1844674407370955161.1e1');
+INSERT INTO t1 VALUES ('1844674407370955161.2e1');
+INSERT INTO t1 VALUES ('1844674407370955161.3e1');
+INSERT INTO t1 VALUES ('1844674407370955161.4e1');
+INSERT INTO t1 VALUES ('1844674407370955161.5e1');
+INSERT INTO t1 VALUES ('18446744073709551610e-1');
+INSERT INTO t1 VALUES ('18446744073709551611e-1');
+INSERT INTO t1 VALUES ('18446744073709551612e-1');
+INSERT INTO t1 VALUES ('18446744073709551613e-1');
+INSERT INTO t1 VALUES ('18446744073709551614e-1');
+INSERT INTO t1 VALUES ('18446744073709551615e-1');
+SELECT * FROM t1;
+uint64
+0
+1
+9223372036854775807
+9223372036854775808
+0
+0
+18446744073709551615
+18446744073709551615
+1844674407370955161
+1844674407370955161
+1844674407370955161
+1844674407370955161
+1844674407370955161
+1844674407370955162
+18446744073709551610
+18446744073709551611
+18446744073709551612
+18446744073709551613
+18446744073709551614
+18446744073709551615
+1844674407370955161
+1844674407370955161
+1844674407370955161
+1844674407370955161
+1844674407370955161
+1844674407370955162
+DROP TABLE t1;
+CREATE TABLE t1 (str varchar(128), sint64 bigint not null default 0);
+INSERT INTO t1 (str) VALUES ('1.5');
+INSERT INTO t1 (str) VALUES ('1.00005e4');
+INSERT INTO t1 (str) VALUES ('1.0005e3');
+INSERT INTO t1 (str) VALUES ('1.005e2');
+INSERT INTO t1 (str) VALUES ('1.05e1');
+INSERT INTO t1 (str) VALUES ('1.5e0');
+INSERT INTO t1 (str) VALUES ('100005e-1');
+INSERT INTO t1 (str) VALUES ('100050e-2');
+INSERT INTO t1 (str) VALUES ('100500e-3');
+INSERT INTO t1 (str) VALUES ('105000e-4');
+INSERT INTO t1 (str) VALUES ('150000e-5');
+UPDATE t1 SET sint64=str;
+SELECT * FROM t1;
+str sint64
+1.5 2
+1.00005e4 10001
+1.0005e3 1001
+1.005e2 101
+1.05e1 11
+1.5e0 2
+100005e-1 10001
+100050e-2 1001
+100500e-3 101
+105000e-4 11
+150000e-5 2
+DROP TABLE t1;
diff --git a/mysql-test/r/rpl_insert_id.result b/mysql-test/r/rpl_insert_id.result
index 0afbbf3adba..63be35b8720 100644
--- a/mysql-test/r/rpl_insert_id.result
+++ b/mysql-test/r/rpl_insert_id.result
@@ -263,9 +263,161 @@ n b
2 100
3 350
drop table t1;
+DROP PROCEDURE IF EXISTS p1;
+DROP TABLE IF EXISTS t1, t2;
+SELECT LAST_INSERT_ID(0);
+LAST_INSERT_ID(0)
+0
+CREATE TABLE t1 (
+id INT NOT NULL DEFAULT 0,
+last_id INT,
+PRIMARY KEY (id)
+);
+CREATE TABLE t2 (
+id INT NOT NULL AUTO_INCREMENT,
+last_id INT,
+PRIMARY KEY (id)
+);
+CREATE PROCEDURE p1()
+BEGIN
+INSERT INTO t2 (last_id) VALUES (LAST_INSERT_ID());
+INSERT INTO t1 (last_id) VALUES (LAST_INSERT_ID());
+END|
+CALL p1();
+SELECT * FROM t1;
+id last_id
+0 1
+SELECT * FROM t2;
+id last_id
+1 0
+SELECT * FROM t1;
+id last_id
+0 1
+SELECT * FROM t2;
+id last_id
+1 0
+DROP PROCEDURE p1;
+DROP TABLE t1, t2;
+DROP PROCEDURE IF EXISTS p1;
+DROP FUNCTION IF EXISTS f1;
+DROP FUNCTION IF EXISTS f2;
+DROP FUNCTION IF EXISTS f3;
+DROP TABLE IF EXISTS t1, t2;
+CREATE TABLE t1 (
+i INT NOT NULL AUTO_INCREMENT PRIMARY KEY,
+j INT DEFAULT 0
+);
+CREATE TABLE t2 (i INT);
+CREATE PROCEDURE p1()
+BEGIN
+INSERT INTO t1 (i) VALUES (NULL);
+INSERT INTO t2 (i) VALUES (LAST_INSERT_ID());
+INSERT INTO t1 (i) VALUES (NULL), (NULL);
+INSERT INTO t2 (i) VALUES (LAST_INSERT_ID());
+END |
+CREATE FUNCTION f1() RETURNS INT MODIFIES SQL DATA
+BEGIN
+INSERT INTO t1 (i) VALUES (NULL);
+INSERT INTO t2 (i) VALUES (LAST_INSERT_ID());
+INSERT INTO t1 (i) VALUES (NULL), (NULL);
+INSERT INTO t2 (i) VALUES (LAST_INSERT_ID());
+RETURN 0;
+END |
+CREATE FUNCTION f2() RETURNS INT NOT DETERMINISTIC
+RETURN LAST_INSERT_ID() |
+CREATE FUNCTION f3() RETURNS INT MODIFIES SQL DATA
+BEGIN
+INSERT INTO t2 (i) VALUES (LAST_INSERT_ID());
+RETURN 0;
+END |
+INSERT INTO t1 VALUES (NULL, -1);
+CALL p1();
+SELECT f1();
+f1()
+0
+INSERT INTO t1 VALUES (NULL, f2()), (NULL, LAST_INSERT_ID()),
+(NULL, LAST_INSERT_ID()), (NULL, f2()), (NULL, f2());
+INSERT INTO t1 VALUES (NULL, f2());
+INSERT INTO t1 VALUES (NULL, LAST_INSERT_ID()), (NULL, LAST_INSERT_ID(5)),
+(NULL, @@LAST_INSERT_ID);
+INSERT INTO t1 VALUES (NULL, 0), (NULL, LAST_INSERT_ID());
+UPDATE t1 SET j= -1 WHERE i IS NULL;
+INSERT INTO t1 (i) VALUES (NULL);
+INSERT INTO t1 (i) VALUES (NULL);
+SELECT f3();
+f3()
+0
+SELECT * FROM t1;
+i j
+1 -1
+2 0
+3 0
+4 0
+5 0
+6 0
+7 0
+8 3
+9 3
+10 3
+11 3
+12 3
+13 8
+14 13
+15 5
+16 13
+17 -1
+18 14
+19 0
+20 0
+SELECT * FROM t2;
+i
+2
+3
+5
+6
+19
+SELECT * FROM t1;
+i j
+1 -1
+2 0
+3 0
+4 0
+5 0
+6 0
+7 0
+8 3
+9 3
+10 3
+11 3
+12 3
+13 8
+14 13
+15 5
+16 13
+17 -1
+18 14
+19 0
+20 0
+SELECT * FROM t2;
+i
+2
+3
+5
+6
+19
+DROP PROCEDURE p1;
+DROP FUNCTION f1;
+DROP FUNCTION f2;
+DROP FUNCTION f3;
+DROP TABLE t1, t2;
#
# End of 5.0 tests
#
+create table t2 (
+id int not null auto_increment,
+last_id int,
+primary key (id)
+);
truncate table t2;
create table t1 (id tinyint primary key);
create function insid() returns int
diff --git a/mysql-test/r/rpl_rewrt_db.result b/mysql-test/r/rpl_rewrt_db.result
index 0c33ffc918f..1b843bffdca 100644
--- a/mysql-test/r/rpl_rewrt_db.result
+++ b/mysql-test/r/rpl_rewrt_db.result
@@ -67,9 +67,9 @@ drop table t1;
create table t1 (a int, b char(10));
load data infile '../std_data_ln/loaddata3.dat' into table t1 fields terminated by '' enclosed by '' ignore 1 lines;
Warnings:
-Warning 1264 Out of range value for column 'a' at row 3
+Warning 1366 Incorrect integer value: 'error ' for column 'a' at row 3
Warning 1262 Row 3 was truncated; it contained more data than there were input columns
-Warning 1264 Out of range value for column 'a' at row 5
+Warning 1366 Incorrect integer value: 'wrong end ' for column 'a' at row 5
Warning 1262 Row 5 was truncated; it contained more data than there were input columns
select * from rewrite.t1;
a b
@@ -81,7 +81,8 @@ a b
truncate table t1;
load data infile '../std_data_ln/loaddata4.dat' into table t1 fields terminated by '' enclosed by '' lines terminated by '' ignore 1 lines;
Warnings:
-Warning 1264 Out of range value for column 'a' at row 4
+Warning 1366 Incorrect integer value: '
+' for column 'a' at row 4
Warning 1261 Row 4 doesn't contain data for all columns
select * from rewrite.t1;
a b
diff --git a/mysql-test/r/rpl_row_basic_11bugs.result b/mysql-test/r/rpl_row_basic_11bugs.result
index d768797717b..e49facd2d70 100644
--- a/mysql-test/r/rpl_row_basic_11bugs.result
+++ b/mysql-test/r/rpl_row_basic_11bugs.result
@@ -99,4 +99,24 @@ a
7
8
9
-DROP TABLE t1;
+================ Test for BUG#22550 ================
+drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9;
+reset master;
+reset slave;
+drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9;
+start slave;
+CREATE TABLE t1 (a BIT(1), b INT) ENGINE=MYISAM;
+INSERT INTO t1 VALUES(1,2);
+SELECT HEX(a),b FROM t1;
+HEX(a) b
+1 2
+SELECT HEX(a),b FROM t1;
+HEX(a) b
+1 2
+UPDATE t1 SET a=0 WHERE b=2;
+SELECT HEX(a),b FROM t1;
+HEX(a) b
+0 2
+SELECT HEX(a),b FROM t1;
+HEX(a) b
+0 2
diff --git a/mysql-test/r/select.result b/mysql-test/r/select.result
index 85c36c8d41c..8800ce248d5 100644
--- a/mysql-test/r/select.result
+++ b/mysql-test/r/select.result
@@ -2809,7 +2809,7 @@ CREATE TABLE t1 (i BIGINT UNSIGNED NOT NULL);
INSERT INTO t1 VALUES (10);
SELECT i='1e+01',i=1e+01, i in (1e+01,1e+01), i in ('1e+01','1e+01') FROM t1;
i='1e+01' i=1e+01 i in (1e+01,1e+01) i in ('1e+01','1e+01')
-0 1 1 1
+1 1 1 1
DROP TABLE t1;
CREATE TABLE t1 (
K2C4 varchar(4) character set latin1 collate latin1_bin NOT NULL default '',
diff --git a/mysql-test/r/sp-vars.result b/mysql-test/r/sp-vars.result
index 6335870caa9..d41d98113a1 100644
--- a/mysql-test/r/sp-vars.result
+++ b/mysql-test/r/sp-vars.result
@@ -896,7 +896,7 @@ sp_var
@user_var
0
Warnings:
-Warning 1264 Out of range value for column 'sp_var' at row 1
+Warning 1366 Incorrect integer value: 'Hello, world!' for column 'sp_var' at row 1
DROP PROCEDURE p1;
DROP TABLE t1;
diff --git a/mysql-test/r/sp.result b/mysql-test/r/sp.result
index 55006f8f63d..79e32b921cc 100644
--- a/mysql-test/r/sp.result
+++ b/mysql-test/r/sp.result
@@ -5359,6 +5359,21 @@ a
2
DROP TABLE t11, t12|
DROP FUNCTION bug19862|
+drop table if exists t3|
+drop database if exists mysqltest1|
+create table t3 (a int)|
+insert into t3 (a) values (1), (2)|
+create database mysqltest1|
+use mysqltest1|
+drop database mysqltest1|
+select database()|
+database()
+NULL
+select * from (select 1 as a) as t1 natural join (select * from test.t3) as t2|
+a
+1
+use test|
+drop table t3|
DROP PROCEDURE IF EXISTS bug16899_p1|
DROP FUNCTION IF EXISTS bug16899_f1|
CREATE DEFINER=1234567890abcdefGHIKL@localhost PROCEDURE bug16899_p1()
@@ -5387,6 +5402,13 @@ ERROR HY000: Can't execute the query because you have a conflicting read lock
UNLOCK TABLES|
The following should succeed.
DROP PROCEDURE bug21414|
+set names utf8|
+drop database if exists това_е_дълго_име_за_база_данни_нали|
+create database това_е_дълго_име_за_база_данни_нали|
+INSERT INTO mysql.proc VALUES ('това_е_дълго_име_за_база_данни_нали','това_е_процедура_Ñ_доÑта_дълго_име_нали_и_още_по_дълго','PROCEDURE','това_е_процедура_Ñ_доÑта_дълго_име_нали_и_още_по_дълго','SQL','CONTAINS_SQL','NO','DEFINER','','','bad_body','root@localhost',now(), now(),'','')|
+call това_е_дълго_име_за_база_данни_нали.това_е_процедура_Ñ_доÑта_дълго_име_нали_и_още_по_дълго()|
+ERROR HY000: Failed to load routine това_е_дълго_име_за_база_данни_нали.. The table mysql.proc is missing, corrupt, or contains bad data (internal code -6)
+drop database това_е_дълго_име_за_база_данни_нали|
CREATE TABLE t3 (
Member_ID varchar(15) NOT NULL,
PRIMARY KEY (Member_ID)
@@ -5423,8 +5445,6 @@ INSERT INTO t4(Member_ID, Action, Action_Date, Track) VALUES
('666666', 'Enrolled', '2006-05-12', 'CHF' ),
('666666', 'Disenrolled', '2006-06-01', 'CAD' )|
DROP FUNCTION IF EXISTS bug21493|
-Warnings:
-Note 1305 FUNCTION bug21493 does not exist
CREATE FUNCTION bug21493(paramMember VARCHAR(15)) RETURNS varchar(45)
BEGIN
DECLARE tracks VARCHAR(45);
diff --git a/mysql-test/r/strict.result b/mysql-test/r/strict.result
index 25475b8cd45..0e21ff80e29 100644
--- a/mysql-test/r/strict.result
+++ b/mysql-test/r/strict.result
@@ -619,9 +619,9 @@ ERROR 22012: Division by 0
UPDATE t1 SET col1= MOD(col1,0) WHERE col1 > 0;
ERROR 22012: Division by 0
INSERT INTO t1 (col1) VALUES ('');
-ERROR 22003: Out of range value for column 'col1' at row 1
+ERROR HY000: Incorrect integer value: '' for column 'col1' at row 1
INSERT INTO t1 (col1) VALUES ('a59b');
-ERROR 22003: Out of range value for column 'col1' at row 1
+ERROR HY000: Incorrect integer value: 'a59b' for column 'col1' at row 1
INSERT INTO t1 (col1) VALUES ('1a');
ERROR 01000: Data truncated for column 'col1' at row 1
INSERT IGNORE INTO t1 (col1) VALUES ('2a');
@@ -701,9 +701,9 @@ ERROR 22012: Division by 0
UPDATE t1 SET col1= MOD(col1,0) WHERE col1 > 0;
ERROR 22012: Division by 0
INSERT INTO t1 (col1) VALUES ('');
-ERROR 22003: Out of range value for column 'col1' at row 1
+ERROR HY000: Incorrect integer value: '' for column 'col1' at row 1
INSERT INTO t1 (col1) VALUES ('a59b');
-ERROR 22003: Out of range value for column 'col1' at row 1
+ERROR HY000: Incorrect integer value: 'a59b' for column 'col1' at row 1
INSERT INTO t1 (col1) VALUES ('1a');
ERROR 01000: Data truncated for column 'col1' at row 1
INSERT IGNORE INTO t1 (col1) VALUES ('2a');
@@ -925,10 +925,10 @@ Warning 1264 Out of range value for column 'col2' at row 1
Warning 1264 Out of range value for column 'col2' at row 1
SELECT * FROM t1;
col1 col2
-0 0
+-2.2e-307 0
1e-303 0
1.7e+308 1.7e+308
-0 0
+-2.2e-307 0
-2e-307 0
1.7e+308 1.7e+308
0 NULL
diff --git a/mysql-test/r/strict_autoinc_4bdb.result b/mysql-test/r/strict_autoinc_4bdb.result
index 73683b645e2..48ebe196baf 100644
--- a/mysql-test/r/strict_autoinc_4bdb.result
+++ b/mysql-test/r/strict_autoinc_4bdb.result
@@ -6,21 +6,21 @@ primary key (`a`)
) engine = 'BDB' ;
set @@sql_mode='strict_all_tables';
insert into t1 values(1000);
-ERROR 22003: Out of range value adjusted for column 'a' at row 1
+ERROR 22003: Out of range value for column 'a' at row 1
select count(*) from t1;
count(*)
0
set auto_increment_increment=1000;
set auto_increment_offset=700;
insert into t1 values(null);
-ERROR 22003: Out of range value adjusted for column 'a' at row 1
+ERROR 22003: Out of range value for column 'a' at row 1
select count(*) from t1;
count(*)
0
set @@sql_mode=@org_mode;
insert into t1 values(null);
Warnings:
-Warning 1264 Out of range value adjusted for column 'a' at row 1
+Warning 1264 Out of range value for column 'a' at row 1
select * from t1;
a
127
diff --git a/mysql-test/r/subselect.result b/mysql-test/r/subselect.result
index ba16bb9410b..a1463bc2b3c 100644
--- a/mysql-test/r/subselect.result
+++ b/mysql-test/r/subselect.result
@@ -1160,7 +1160,7 @@ Code2 char(2) NOT NULL default '',
PRIMARY KEY (Code)
) ENGINE=MyISAM;
INSERT INTO t2 VALUES ('AUS','Australia','Oceania','Australia and New Zealand',7741220.00,1901,18886000,79.8,351182.00,392911.00,'Australia','Constitutional Monarchy, Federation','Elisabeth II',135,'AU');
-INSERT INTO t2 VALUES ('AZE','Azerbaijan','Asia','Middle East',86600.00,1991,7734000,62.9,4127.00,4100.00,'Azärbaycan','Federal Republic','Heydär Äliyev',144,'AZ');
+INSERT INTO t2 VALUES ('AZE','Azerbaijan','Asia','Middle East',86600.00,1991,7734000,62.9,4127.00,4100.00,'Azärbaycan','Federal Republic','Heydär Äliyev',144,'AZ');
select t2.Continent, t1.Name, t1.Population from t2 LEFT JOIN t1 ON t2.Code = t1.t2 where t1.Population IN (select max(t1.Population) AS Population from t1, t2 where t1.t2 = t2.Code group by Continent);
Continent Name Population
Oceania Sydney 3276207
@@ -2512,7 +2512,7 @@ Code2 char(2) NOT NULL default ''
) ENGINE=MyISAM;
INSERT INTO t1 VALUES ('XXX','Xxxxx','Oceania','Xxxxxx',26.00,0,0,0,0,0,'Xxxxx','Xxxxx','Xxxxx',NULL,'XX');
INSERT INTO t1 VALUES ('ASM','American Samoa','Oceania','Polynesia',199.00,0,68000,75.1,334.00,NULL,'Amerika Samoa','US Territory','George W. Bush',54,'AS');
-INSERT INTO t1 VALUES ('ATF','French Southern territories','Antarctica','Antarctica',7780.00,0,0,NULL,0.00,NULL,'Terres australes françaises','Nonmetropolitan Territory of France','Jacques Chirac',NULL,'TF');
+INSERT INTO t1 VALUES ('ATF','French Southern territories','Antarctica','Antarctica',7780.00,0,0,NULL,0.00,NULL,'Terres australes françaises','Nonmetropolitan Territory of France','Jacques Chirac',NULL,'TF');
INSERT INTO t1 VALUES ('UMI','United States Minor Outlying Islands','Oceania','Micronesia/Caribbean',16.00,0,0,NULL,0.00,NULL,'United States Minor Outlying Islands','Dependent Territory of the US','George W. Bush',NULL,'UM');
/*!40000 ALTER TABLE t1 ENABLE KEYS */;
SELECT DISTINCT Continent AS c FROM t1 WHERE Code <> SOME ( SELECT Code FROM t1 WHERE Continent = c AND Population < 200);
@@ -2966,6 +2966,42 @@ ORDER BY t2.c, t2.b LIMIT 1) WHERE t1.a = 10;
a a b
10 1 359
drop table t1,t2;
+CREATE TABLE t1 (
+field1 int NOT NULL,
+field2 int NOT NULL,
+field3 int NOT NULL,
+PRIMARY KEY (field1,field2,field3)
+);
+CREATE TABLE t2 (
+fieldA int NOT NULL,
+fieldB int NOT NULL,
+PRIMARY KEY (fieldA,fieldB)
+);
+INSERT INTO t1 VALUES
+(1,1,1), (1,1,2), (1,2,1), (1,2,2), (1,2,3), (1,3,1);
+INSERT INTO t2 VALUES (1,1), (1,2), (1,3);
+SELECT field1, field2, COUNT(*)
+FROM t1 GROUP BY field1, field2;
+field1 field2 COUNT(*)
+1 1 2
+1 2 3
+1 3 1
+SELECT field1, field2
+FROM t1
+GROUP BY field1, field2
+HAVING COUNT(*) >= ALL (SELECT fieldB
+FROM t2 WHERE fieldA = field1);
+field1 field2
+1 2
+SELECT field1, field2
+FROM t1
+GROUP BY field1, field2
+HAVING COUNT(*) < ANY (SELECT fieldB
+FROM t2 WHERE fieldA = field1);
+field1 field2
+1 1
+1 3
+DROP TABLE t1, t2;
create table t1 (df decimal(5,1));
insert into t1 values(1.1);
insert into t1 values(2.2);
@@ -3422,3 +3458,64 @@ id select_type table type possible_keys key key_len ref rows Extra
4 UNION t12 system NULL NULL NULL NULL 0 const row not found
NULL UNION RESULT <union2,4> ALL NULL NULL NULL NULL NULL
DROP TABLE t1;
+CREATE TABLE t1 (a INT, b INT);
+CREATE TABLE t2 (a INT);
+INSERT INTO t2 values (1);
+INSERT INTO t1 VALUES (1,1),(1,2),(2,3),(3,4);
+SELECT (SELECT COUNT(DISTINCT t1.b) from t2) FROM t1 GROUP BY t1.a;
+(SELECT COUNT(DISTINCT t1.b) from t2)
+2
+1
+1
+SELECT (SELECT COUNT(DISTINCT t1.b) from t2 union select 1 from t2 where 12 < 3)
+FROM t1 GROUP BY t1.a;
+(SELECT COUNT(DISTINCT t1.b) from t2 union select 1 from t2 where 12 < 3)
+2
+1
+1
+SELECT COUNT(DISTINCT t1.b), (SELECT COUNT(DISTINCT t1.b)) FROM t1 GROUP BY t1.a;
+COUNT(DISTINCT t1.b) (SELECT COUNT(DISTINCT t1.b))
+2 2
+1 1
+1 1
+SELECT COUNT(DISTINCT t1.b),
+(SELECT COUNT(DISTINCT t1.b) union select 1 from DUAL where 12 < 3)
+FROM t1 GROUP BY t1.a;
+COUNT(DISTINCT t1.b) (SELECT COUNT(DISTINCT t1.b) union select 1 from DUAL where 12 < 3)
+2 2
+1 1
+1 1
+SELECT (
+SELECT (
+SELECT COUNT(DISTINCT t1.b)
+)
+)
+FROM t1 GROUP BY t1.a;
+(
+SELECT (
+SELECT COUNT(DISTINCT t1.b)
+)
+)
+2
+1
+1
+SELECT (
+SELECT (
+SELECT (
+SELECT COUNT(DISTINCT t1.b)
+)
+)
+FROM t1 GROUP BY t1.a LIMIT 1)
+FROM t1 t2
+GROUP BY t2.a;
+(
+SELECT (
+SELECT (
+SELECT COUNT(DISTINCT t1.b)
+)
+)
+FROM t1 GROUP BY t1.a LIMIT 1)
+2
+2
+2
+DROP TABLE t1,t2;
diff --git a/mysql-test/r/temp_table.result b/mysql-test/r/temp_table.result
index 637f74a1d50..6c9a389c1f4 100644
--- a/mysql-test/r/temp_table.result
+++ b/mysql-test/r/temp_table.result
@@ -135,6 +135,23 @@ d c
bar 2
foo 1
drop table t1, t2;
+DROP TABLE IF EXISTS t1;
+CREATE TABLE t1 (i INT);
+LOCK TABLE t1 WRITE;
+CREATE TEMPORARY TABLE t1 (i INT);
+The following command should not block
+DROP TEMPORARY TABLE t1;
+DROP TABLE t1;
+CREATE TABLE t1 (i INT);
+CREATE TEMPORARY TABLE t2 (i INT);
+DROP TEMPORARY TABLE t2, t1;
+ERROR 42S02: Unknown table 't1'
+SELECT * FROM t2;
+ERROR 42S02: Table 'test.t2' doesn't exist
+SELECT * FROM t1;
+i
+DROP TABLE t1;
+End of 4.1 tests.
create temporary table t1 (a int);
insert into t1 values (4711);
select * from t1;
diff --git a/mysql-test/r/trigger.result b/mysql-test/r/trigger.result
index 7fe3194304c..5f027195e2e 100644
--- a/mysql-test/r/trigger.result
+++ b/mysql-test/r/trigger.result
@@ -1173,4 +1173,16 @@ TRIGGER t2_bi BEFORE INSERT ON t2 FOR EACH ROW SET @a = 2;
ERROR HY000: String '1234567890abcdefghij1234567890abcdefghij1234567890abcdefghijQWERTY' is too long for host name (should be no longer than 60)
DROP TABLE t1;
DROP TABLE t2;
+drop table if exists t1;
+create table t1 (i int, j int key);
+insert into t1 values (1,1), (2,2), (3,3);
+create trigger t1_bu before update on t1 for each row
+set new.j = new.j + 10;
+update t1 set i= i+ 10 where j > 2;
+select * from t1;
+i j
+1 1
+2 2
+13 13
+drop table t1;
End of 5.0 tests
diff --git a/mysql-test/r/type_bit.result b/mysql-test/r/type_bit.result
index 08a1b229491..5c9b70fadc3 100644
--- a/mysql-test/r/type_bit.result
+++ b/mysql-test/r/type_bit.result
@@ -602,4 +602,12 @@ NULL NULL
0 0
11111111 11111111
drop table bug15583;
+create table t1(a bit(1), b smallint unsigned);
+insert into t1 (b, a) values ('2', '1');
+Warnings:
+Warning 1264 Out of range value for column 'a' at row 1
+select hex(a), b from t1;
+hex(a) b
+1 2
+drop table t1;
End of 5.0 tests
diff --git a/mysql-test/r/type_float.result b/mysql-test/r/type_float.result
index cfae61d5e91..d28131cc456 100644
--- a/mysql-test/r/type_float.result
+++ b/mysql-test/r/type_float.result
@@ -262,6 +262,13 @@ desc t3;
Field Type Null Key Default Extra
a decimal(21,2) NO 0.00
drop table t1,t2,t3;
+select 1e-308, 1.00000001e-300, 100000000e-300;
+1e-308 1.00000001e-300 100000000e-300
+0 1.00000001e-300 1e-292
+select 10e307;
+10e307
+1e+308
+End of 4.1 tests
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').
create table t1 (s1 float(1,2));
diff --git a/mysql-test/r/view.result b/mysql-test/r/view.result
index 5d009ed7840..2fa467727f1 100644
--- a/mysql-test/r/view.result
+++ b/mysql-test/r/view.result
@@ -472,11 +472,11 @@ create view v3 (x,y,z) as select b, a, b from t1;
create view v4 (x,y,z) as select c+1, b, a from t1;
create algorithm=temptable view v5 (x,y,z) as select c, b, a from t1;
insert into v3 values (-60,4,30);
-ERROR HY000: The target table v3 of the INSERT is not updatable
+ERROR HY000: The target table v3 of the INSERT is not insertable-into
insert into v4 values (-60,4,30);
-ERROR HY000: The target table v4 of the INSERT is not updatable
+ERROR HY000: The target table v4 of the INSERT is not insertable-into
insert into v5 values (-60,4,30);
-ERROR HY000: The target table v5 of the INSERT is not updatable
+ERROR HY000: The target table v5 of the INSERT is not insertable-into
insert into v1 values (-60,4,30);
insert into v1 (z,y,x) values (50,6,-100);
insert into v2 values (5,40);
@@ -499,11 +499,11 @@ create view v3 (x,y,z) as select b, a, b from t1;
create view v4 (x,y,z) as select c+1, b, a from t1;
create algorithm=temptable view v5 (x,y,z) as select c, b, a from t1;
insert into v3 select c, b, a from t2;
-ERROR HY000: The target table v3 of the INSERT is not updatable
+ERROR HY000: The target table v3 of the INSERT is not insertable-into
insert into v4 select c, b, a from t2;
-ERROR HY000: The target table v4 of the INSERT is not updatable
+ERROR HY000: The target table v4 of the INSERT is not insertable-into
insert into v5 select c, b, a from t2;
-ERROR HY000: The target table v5 of the INSERT is not updatable
+ERROR HY000: The target table v5 of the INSERT is not insertable-into
insert into v1 select c, b, a from t2;
insert into v1 (z,y,x) select a+20,b+2,-100 from t2;
insert into v2 select b+1, a+10 from t2;
@@ -1306,9 +1306,9 @@ a b
delete from t1;
load data infile '../std_data_ln/loaddata3.dat' ignore into table v1 fields terminated by '' enclosed by '' ignore 1 lines;
Warnings:
-Warning 1264 Out of range value for column 'a' at row 3
+Warning 1366 Incorrect integer value: 'error ' for column 'a' at row 3
Error 1369 CHECK OPTION failed 'test.v1'
-Warning 1264 Out of range value for column 'a' at row 4
+Warning 1366 Incorrect integer value: 'wrong end ' for column 'a' at row 4
Error 1369 CHECK OPTION failed 'test.v1'
select * from t1 order by a,b;
a b
@@ -1352,14 +1352,14 @@ drop table t1;
create table t1 (s1 smallint);
create view v1 as select * from t1 where 20 < (select (s1) from t1);
insert into v1 values (30);
-ERROR HY000: The target table v1 of the INSERT is not updatable
+ERROR HY000: The target table v1 of the INSERT is not insertable-into
create view v2 as select * from t1;
create view v3 as select * from t1 where 20 < (select (s1) from v2);
insert into v3 values (30);
-ERROR HY000: The target table v3 of the INSERT is not updatable
+ERROR HY000: The target table v3 of the INSERT is not insertable-into
create view v4 as select * from v2 where 20 < (select (s1) from t1);
insert into v4 values (30);
-ERROR HY000: The target table v4 of the INSERT is not updatable
+ERROR HY000: The target table v4 of the INSERT is not insertable-into
drop view v4, v3, v2, v1;
drop table t1;
create table t1 (a int);
@@ -2911,7 +2911,7 @@ INSERT INTO v2 VALUES (0);
RETURN 0;
END |
SELECT f2();
-ERROR HY000: The target table v2 of the INSERT is not updatable
+ERROR HY000: The target table v2 of the INSERT is not insertable-into
DROP FUNCTION f1;
DROP FUNCTION f2;
DROP VIEW v1, v2;
@@ -2935,4 +2935,25 @@ id select_type table type possible_keys key key_len ref rows Extra
2 SUBQUERY t1 ALL NULL NULL NULL NULL 3
DROP VIEW v1;
DROP TABLE t1;
+create table t1 (s1 int);
+create view v1 as select s1 as a, s1 as b from t1;
+insert into v1 values (1,1);
+ERROR HY000: The target table v1 of the INSERT is not insertable-into
+update v1 set a = 5;
+drop view v1;
+drop table t1;
+CREATE TABLE t1(pk int PRIMARY KEY);
+CREATE TABLE t2(pk int PRIMARY KEY, fk int, ver int, org int);
+CREATE ALGORITHM=MERGE VIEW v1 AS
+SELECT t1.*
+FROM t1 JOIN t2
+ON t2.fk = t1.pk AND
+t2.ver = (SELECT MAX(t.ver) FROM t2 t WHERE t.org = t2.org);
+SHOW WARNINGS;
+Level Code Message
+SHOW CREATE VIEW v1;
+View Create View
+v1 CREATE ALGORITHM=MERGE DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `v1` AS select `t1`.`pk` AS `pk` from (`t1` join `t2` on(((`t2`.`fk` = `t1`.`pk`) and (`t2`.`ver` = (select max(`t`.`ver`) AS `MAX(t.ver)` from `t2` `t` where (`t`.`org` = `t2`.`org`))))))
+DROP VIEW v1;
+DROP TABLE t1, t2;
End of 5.0 tests.
diff --git a/mysql-test/r/warnings.result b/mysql-test/r/warnings.result
index 26b3c1625aa..d07f90d41b9 100644
--- a/mysql-test/r/warnings.result
+++ b/mysql-test/r/warnings.result
@@ -31,19 +31,19 @@ Error 1064 You have an error in your SQL syntax; check the manual that correspon
insert into t1 values (1);
insert into t1 values ("hej");
Warnings:
-Warning 1264 Out of range value for column 'a' at row 1
+Warning 1366 Incorrect integer value: 'hej' for column 'a' at row 1
insert into t1 values ("hej"),("då");
Warnings:
-Warning 1264 Out of range value for column 'a' at row 1
-Warning 1264 Out of range value for column 'a' at row 2
+Warning 1366 Incorrect integer value: 'hej' for column 'a' at row 1
+Warning 1366 Incorrect integer value: 'd?' for column 'a' at row 2
set SQL_WARNINGS=1;
insert into t1 values ("hej");
Warnings:
-Warning 1264 Out of range value for column 'a' at row 1
+Warning 1366 Incorrect integer value: 'hej' for column 'a' at row 1
insert into t1 values ("hej"),("då");
Warnings:
-Warning 1264 Out of range value for column 'a' at row 1
-Warning 1264 Out of range value for column 'a' at row 2
+Warning 1366 Incorrect integer value: 'hej' for column 'a' at row 1
+Warning 1366 Incorrect integer value: 'd?' for column 'a' at row 2
drop table t1;
set SQL_WARNINGS=0;
drop temporary table if exists not_exists;
@@ -180,44 +180,44 @@ create table t1 (a int);
insert into t1 (a) values (1), (2), (3), (4), (5), (6), (7), (8), (9), (10);
update t1 set a='abc';
Warnings:
-Warning 1264 Out of range value for column 'a' at row 1
-Warning 1264 Out of range value for column 'a' at row 2
-Warning 1264 Out of range value for column 'a' at row 3
-Warning 1264 Out of range value for column 'a' at row 4
-Warning 1264 Out of range value for column 'a' at row 5
-Warning 1264 Out of range value for column 'a' at row 6
-Warning 1264 Out of range value for column 'a' at row 7
-Warning 1264 Out of range value for column 'a' at row 8
-Warning 1264 Out of range value for column 'a' at row 9
-Warning 1264 Out of range value for column 'a' at row 10
+Warning 1366 Incorrect integer value: 'abc' for column 'a' at row 1
+Warning 1366 Incorrect integer value: 'abc' for column 'a' at row 2
+Warning 1366 Incorrect integer value: 'abc' for column 'a' at row 3
+Warning 1366 Incorrect integer value: 'abc' for column 'a' at row 4
+Warning 1366 Incorrect integer value: 'abc' for column 'a' at row 5
+Warning 1366 Incorrect integer value: 'abc' for column 'a' at row 6
+Warning 1366 Incorrect integer value: 'abc' for column 'a' at row 7
+Warning 1366 Incorrect integer value: 'abc' for column 'a' at row 8
+Warning 1366 Incorrect integer value: 'abc' for column 'a' at row 9
+Warning 1366 Incorrect integer value: 'abc' for column 'a' at row 10
show warnings limit 2, 1;
Level Code Message
-Warning 1264 Out of range value for column 'a' at row 3
+Warning 1366 Incorrect integer value: 'abc' for column 'a' at row 3
show warnings limit 0, 10;
Level Code Message
-Warning 1264 Out of range value for column 'a' at row 1
-Warning 1264 Out of range value for column 'a' at row 2
-Warning 1264 Out of range value for column 'a' at row 3
-Warning 1264 Out of range value for column 'a' at row 4
-Warning 1264 Out of range value for column 'a' at row 5
-Warning 1264 Out of range value for column 'a' at row 6
-Warning 1264 Out of range value for column 'a' at row 7
-Warning 1264 Out of range value for column 'a' at row 8
-Warning 1264 Out of range value for column 'a' at row 9
-Warning 1264 Out of range value for column 'a' at row 10
+Warning 1366 Incorrect integer value: 'abc' for column 'a' at row 1
+Warning 1366 Incorrect integer value: 'abc' for column 'a' at row 2
+Warning 1366 Incorrect integer value: 'abc' for column 'a' at row 3
+Warning 1366 Incorrect integer value: 'abc' for column 'a' at row 4
+Warning 1366 Incorrect integer value: 'abc' for column 'a' at row 5
+Warning 1366 Incorrect integer value: 'abc' for column 'a' at row 6
+Warning 1366 Incorrect integer value: 'abc' for column 'a' at row 7
+Warning 1366 Incorrect integer value: 'abc' for column 'a' at row 8
+Warning 1366 Incorrect integer value: 'abc' for column 'a' at row 9
+Warning 1366 Incorrect integer value: 'abc' for column 'a' at row 10
show warnings limit 9, 1;
Level Code Message
-Warning 1264 Out of range value for column 'a' at row 10
+Warning 1366 Incorrect integer value: 'abc' for column 'a' at row 10
show warnings limit 10, 1;
Level Code Message
show warnings limit 9, 2;
Level Code Message
-Warning 1264 Out of range value for column 'a' at row 10
+Warning 1366 Incorrect integer value: 'abc' for column 'a' at row 10
show warnings limit 0, 0;
Level Code Message
show warnings limit 1;
Level Code Message
-Warning 1264 Out of range value for column 'a' at row 1
+Warning 1366 Incorrect integer value: 'abc' for column 'a' at row 1
show warnings limit 0;
Level Code Message
show warnings limit 1, 0;
@@ -229,3 +229,59 @@ a
select * from t1 limit 0, 0;
a
drop table t1;
+End of 4.1 tests
+CREATE TABLE t1( f1 CHAR(20) );
+CREATE TABLE t2( f1 CHAR(20), f2 CHAR(25) );
+CREATE TABLE t3( f1 CHAR(20), f2 CHAR(25), f3 DATE );
+INSERT INTO t1 VALUES ( 'a`' );
+INSERT INTO t2 VALUES ( 'a`', 'a`' );
+INSERT INTO t3 VALUES ( 'a`', 'a`', '1000-01-1' );
+DROP PROCEDURE IF EXISTS sp1;
+Warnings:
+Note 1305 PROCEDURE sp1 does not exist
+DROP PROCEDURE IF EXISTS sp2;
+Warnings:
+Note 1305 PROCEDURE sp2 does not exist
+DROP PROCEDURE IF EXISTS sp3;
+Warnings:
+Note 1305 PROCEDURE sp3 does not exist
+CREATE PROCEDURE sp1()
+BEGIN
+DECLARE x NUMERIC ZEROFILL;
+SELECT f1 INTO x FROM t1 LIMIT 1;
+END//
+CREATE PROCEDURE sp2()
+BEGIN
+DECLARE x NUMERIC ZEROFILL;
+SELECT f1 INTO x FROM t2 LIMIT 1;
+END//
+CREATE PROCEDURE sp3()
+BEGIN
+DECLARE x NUMERIC ZEROFILL;
+SELECT f1 INTO x FROM t3 LIMIT 1;
+END//
+CALL sp1();
+Warnings:
+Warning 1366 Incorrect decimal value: 'a`' for column 'x' at row 1
+CALL sp2();
+Warnings:
+Warning 1366 Incorrect decimal value: 'a`' for column 'x' at row 1
+CALL sp3();
+Warnings:
+Warning 1366 Incorrect decimal value: 'a`' for column 'x' at row 1
+DROP PROCEDURE IF EXISTS sp1;
+CREATE PROCEDURE sp1()
+BEGIN
+declare x numeric unsigned zerofill;
+SELECT f1 into x from t2 limit 1;
+END//
+CALL sp1();
+Warnings:
+Warning 1366 Incorrect decimal value: 'a`' for column 'x' at row 1
+DROP TABLE t1;
+DROP TABLE t2;
+DROP TABLE t3;
+DROP PROCEDURE sp1;
+DROP PROCEDURE sp2;
+DROP PROCEDURE sp3;
+End of 5.0 tests
diff --git a/mysql-test/r/windows.result b/mysql-test/r/windows.result
index e3241daf719..039c5b1476e 100644
--- a/mysql-test/r/windows.result
+++ b/mysql-test/r/windows.result
@@ -6,31 +6,3 @@ use prn;
ERROR 42000: Unknown database 'prn'
create table nu (a int);
drop table nu;
-CREATE TABLE `t1` (
-`TIM` datetime NOT NULL,
-`VAL` double default NULL
-) ENGINE=MyISAM DEFAULT CHARSET=latin1;
-CREATE TABLE `t2` (
-`TIM` datetime NOT NULL,
-`VAL` double default NULL
-) ENGINE=MyISAM DEFAULT CHARSET=latin1;
-CREATE TABLE `mt` (
-`TIM` datetime NOT NULL,
-`VAL` double default NULL
-) ENGINE=MRG_MyISAM DEFAULT CHARSET=latin1 INSERT_METHOD=LAST
-UNION=(`t1`,`t2`);
-INSERT INTO mt VALUES ('2006-01-01',0);
-ALTER TABLE `t2` RENAME TO `t`;
-INSERT INTO mt VALUES ('2006-01-01',0);
-ERROR HY000: Can't lock file (errno: 155)
-select * from mt;
-ERROR HY000: Can't lock file (errno: 155)
-FLUSH TABLES;
-select * from mt;
-ERROR HY000: Can't find file: 'mt' (errno: 2)
-ALTER TABLE `t` RENAME TO `t2`;
-INSERT INTO mt VALUES ('2006-01-01',0);
-select * from mt;
-TIM VAL
-2006-01-01 00:00:00 0
-2006-01-01 00:00:00 0
diff --git a/mysql-test/r/xml.result b/mysql-test/r/xml.result
index 780be01d7ce..efe7d14095d 100644
--- a/mysql-test/r/xml.result
+++ b/mysql-test/r/xml.result
@@ -570,7 +570,7 @@ select extractvalue('<a>a<b>B</b></a>','a|/b');
extractvalue('<a>a<b>B</b></a>','a|/b')
a
select extractvalue('<a>A</a>','/<a>');
-ERROR HY000: XPATH syntax error: '<a>'
+ERROR HY000: XPATH error: comparison of two nodesets is not supported: '<a>'
select extractvalue('<a><b>b</b><b!>b!</b!></a>','//b!');
ERROR HY000: XPATH syntax error: '!'
select extractvalue('<a>A<b>B<c>C</c></b></a>','/a/descendant::*');
@@ -710,3 +710,29 @@ Data
select extractValue('<foo><foo.bar>Data</foo.bar><something>Otherdata</something></foo>','/foo/something');
extractValue('<foo><foo.bar>Data</foo.bar><something>Otherdata</something></foo>','/foo/something')
Otherdata
+select extractValue('<zot><tim0><01>10:39:15</01><02>140</02></tim0></zot>','/zot/tim0/02');
+ERROR HY000: XPATH syntax error: '02'
+select extractValue('<zot><tim0><01>10:39:15</01><02>140</02></tim0></zot>','//*');
+extractValue('<zot><tim0><01>10:39:15</01><02>140</02></tim0></zot>','//*')
+NULL
+Warnings:
+Warning 1512 Incorrect XML value: 'parse error at line 1 pos 13: unknown token unexpected (ident or '/' wanted)'
+select extractValue('<.>test</.>','//*');
+extractValue('<.>test</.>','//*')
+NULL
+Warnings:
+Warning 1512 Incorrect XML value: 'parse error at line 1 pos 2: unknown token unexpected (ident or '/' wanted)'
+select extractValue('<->test</->','//*');
+extractValue('<->test</->','//*')
+NULL
+Warnings:
+Warning 1512 Incorrect XML value: 'parse error at line 1 pos 2: unknown token unexpected (ident or '/' wanted)'
+select extractValue('<:>test</:>','//*');
+extractValue('<:>test</:>','//*')
+test
+select extractValue('<_>test</_>','//*');
+extractValue('<_>test</_>','//*')
+test
+select extractValue('<x.-_:>test</x.-_:>','//*');
+extractValue('<x.-_:>test</x.-_:>','//*')
+test
diff --git a/mysql-test/t/analyse.test b/mysql-test/t/analyse.test
index a248c671c18..efcf5f6421c 100644
--- a/mysql-test/t/analyse.test
+++ b/mysql-test/t/analyse.test
@@ -90,5 +90,16 @@ create table t2 (country_id int primary key, country char(20) not null);
insert into t2 values (1, 'USA'),(2,'India'), (3,'Finland');
select product, sum(profit),avg(profit) from t1 group by product with rollup procedure analyse();
drop table t1,t2;
-# End of 4.1 tests
+#
+# Bug #20305 PROCEDURE ANALYSE() returns wrong M for FLOAT(M, D) and DOUBLE(M, D)
+#
+
+create table t1 (f1 double(10,5), f2 char(10), f3 double(10,5));
+insert into t1 values (5.999, "5.9999", 5.99999), (9.555, "9.5555", 9.55555);
+select f1 from t1 procedure analyse(1, 1);
+select f2 from t1 procedure analyse(1, 1);
+select f3 from t1 procedure analyse(1, 1);
+drop table t1;
+
+--echo End of 4.1 tests
diff --git a/mysql-test/t/crash_commit_before-master.opt b/mysql-test/t/crash_commit_before-master.opt
new file mode 100644
index 00000000000..a745693594e
--- /dev/null
+++ b/mysql-test/t/crash_commit_before-master.opt
@@ -0,0 +1,2 @@
+--skip-stack-trace --skip-core-file
+
diff --git a/mysql-test/t/crash_commit_before.test b/mysql-test/t/crash_commit_before.test
index c46340d44dc..a10cf254a83 100644
--- a/mysql-test/t/crash_commit_before.test
+++ b/mysql-test/t/crash_commit_before.test
@@ -1,4 +1,9 @@
+# Don't test this under valgrind, memory leaks will occur
+--source include/not_valgrind.inc
+
+# Binary must be compiled with debug for crash to occur
--source include/have_debug.inc
+
--source include/have_innodb.inc
CREATE TABLE t1(a int) engine=innodb;
diff --git a/mysql-test/t/csv.test b/mysql-test/t/csv.test
index 9815da4fb55..f70b5b40766 100644
--- a/mysql-test/t/csv.test
+++ b/mysql-test/t/csv.test
@@ -1582,3 +1582,26 @@ select * from bug15205_2;
select * from bug15205;
drop table bug15205;
drop table bug15205_2;
+
+#
+# Bug#22080 "CHECK fails to identify some corruption"
+#
+
+create table bug22080_1 (id int,string varchar(64)) Engine=CSV;
+create table bug22080_2 (id int,string varchar(64)) Engine=CSV;
+create table bug22080_3 (id int,string varchar(64)) Engine=CSV;
+insert into bug22080_1 values(1,'string');
+insert into bug22080_1 values(2,'string');
+insert into bug22080_1 values(3,'string');
+
+# Currupt the file as described in the bug report
+--exec sed -e 's/"2"/2"/' $MYSQLTEST_VARDIR/master-data/test/bug22080_1.CSV > $MYSQLTEST_VARDIR/master-data/test/bug22080_2.CSV
+--exec sed -e 's/2","/2",/' $MYSQLTEST_VARDIR/master-data/test/bug22080_1.CSV > $MYSQLTEST_VARDIR/master-data/test/bug22080_3.CSV
+
+--exec cat $MYSQLTEST_VARDIR/master-data/test/bug22080_2.CSV
+check table bug22080_2;
+
+--exec cat $MYSQLTEST_VARDIR/master-data/test/bug22080_3.CSV
+check table bug22080_3;
+
+drop tables bug22080_1,bug22080_2,bug22080_3;
diff --git a/mysql-test/t/ctype_gbk.test b/mysql-test/t/ctype_gbk.test
index 7aec48586d8..5ff138fa97b 100644
--- a/mysql-test/t/ctype_gbk.test
+++ b/mysql-test/t/ctype_gbk.test
@@ -42,3 +42,13 @@ DROP TABLE t1;
select hex(convert(_gbk 0xA14041 using ucs2));
# End of 4.1 tests
+
+#
+# Bug#21620 ALTER TABLE affects other columns
+#
+create table t1 (c1 text not null, c2 text not null) character set gbk;
+alter table t1 change c1 c1 mediumtext character set gbk not null;
+show create table t1;
+drop table t1;
+
+--echo End of 5.0 tests
diff --git a/mysql-test/t/ctype_ucs.test b/mysql-test/t/ctype_ucs.test
index 8116d39e3db..6c814368c88 100644
--- a/mysql-test/t/ctype_ucs.test
+++ b/mysql-test/t/ctype_ucs.test
@@ -484,6 +484,27 @@ select make_set(3, name, upper(name)) from bug20536;
select export_set(5, name, upper(name)) from bug20536;
select export_set(5, name, upper(name), ",", 5) from bug20536;
+#
+# Bug #20108: corrupted default enum value for a ucs2 field
+#
+
+CREATE TABLE t1 (
+ status enum('active','passive') collate latin1_general_ci
+ NOT NULL default 'passive'
+);
+SHOW CREATE TABLE t1;
+ALTER TABLE t1 ADD a int NOT NULL AFTER status;
+
+CREATE TABLE t2 (
+ status enum('active','passive') collate ucs2_turkish_ci
+ NOT NULL default 'passive'
+);
+SHOW CREATE TABLE t2;
+ALTER TABLE t2 ADD a int NOT NULL AFTER status;
+
+DROP TABLE t1,t2;
+
+
# Some broken functions: add these tests just to document current behavior.
# PASSWORD and OLD_PASSWORD don't work with UCS2 strings, but to fix it would
diff --git a/mysql-test/t/ctype_utf8.test b/mysql-test/t/ctype_utf8.test
index 54ded650a1e..ecf118dae59 100644
--- a/mysql-test/t/ctype_utf8.test
+++ b/mysql-test/t/ctype_utf8.test
@@ -1070,21 +1070,15 @@ select a from t1 group by a;
drop table t1;
#
-# Bug#20393: User name truncation in mysql client
-# Bug#21432: Database/Table name limited to 64 bytes, not chars, problems with multi-byte
+# Bug #20204: "order by" changes the results returned
#
-set names utf8;
-#create user юзер_юзер@localhost;
-grant select on test.* to юзер_юзер@localhost;
---exec $MYSQL --default-character-set=utf8 --user=юзер_юзер -e "select user()"
-revoke all on test.* from юзер_юзер@localhost;
-drop user юзер_юзер@localhost;
-
-create database имÑ_базы_в_кодировке_утф8_длиной_больше_чем_45;
-use имÑ_базы_в_кодировке_утф8_длиной_больше_чем_45;
-select database();
-drop database имÑ_базы_в_кодировке_утф8_длиной_больше_чем_45;
-use test;
+
+create table t1(a char(10)) default charset utf8;
+insert into t1 values ('123'), ('456');
+explain
+ select substr(Z.a,-1), Z.a from t1 as Y join t1 as Z on Y.a=Z.a order by 1;
+select substr(Z.a,-1), Z.a from t1 as Y join t1 as Z on Y.a=Z.a order by 1;
+drop table t1;
# End of 4.1 tests
@@ -1164,3 +1158,23 @@ execute my_stmt using @a;
set @a:=null;
execute my_stmt using @a;
drop table if exists t1;
+
+#
+# Bug#19960: Inconsistent results when joining
+# InnoDB tables using partial UTF8 indexes
+#
+CREATE TABLE t1 (
+ colA int(11) NOT NULL,
+ colB varchar(255) character set utf8 NOT NULL,
+ PRIMARY KEY (colA)
+) ENGINE=InnoDB DEFAULT CHARSET=latin1;
+INSERT INTO t1 (colA, colB) VALUES (1, 'foo'), (2, 'foo bar');
+CREATE TABLE t2 (
+ colA int(11) NOT NULL,
+ colB varchar(255) character set utf8 NOT NULL,
+ KEY bad (colA,colB(3))
+) ENGINE=InnoDB DEFAULT CHARSET=latin1;
+INSERT INTO t2 (colA, colB) VALUES (1, 'foo'),(2, 'foo bar');
+SELECT * FROM t1 JOIN t2 ON t1.colA=t2.colA AND t1.colB=t2.colB
+WHERE t1.colA < 3;
+DROP TABLE t1, t2;
diff --git a/mysql-test/t/delayed.test b/mysql-test/t/delayed.test
index 55e8f81f763..03d8e20dd8f 100644
--- a/mysql-test/t/delayed.test
+++ b/mysql-test/t/delayed.test
@@ -17,7 +17,8 @@ insert delayed into t1 set a = 4;
insert delayed into t1 set a = 5, tmsp = 19711006010203;
insert delayed into t1 (a, tmsp) values (6, 19711006010203);
insert delayed into t1 (a, tmsp) values (7, NULL);
---sleep 2
+# Wait until the rows are flushed to the table files.
+FLUSH TABLE t1;
insert into t1 set a = 8,tmsp=19711006010203;
select * from t1 where tmsp=0;
select * from t1 where tmsp=19711006010203;
@@ -34,8 +35,8 @@ insert delayed into t1 values (null,"c");
insert delayed into t1 values (3,"d"),(null,"e");
--error 1136
insert delayed into t1 values (3,"this will give an","error");
-# 2 was not enough for --ps-protocol
---sleep 4
+# Wait until the rows are flushed to the table files.
+FLUSH TABLE t1;
show status like 'not_flushed_delayed_rows';
select * from t1;
drop table t1;
@@ -92,10 +93,145 @@ insert delayed into t1 values(null);
# Works, since the delayed-counter is 8, which is unused
insert delayed into t1 values(null);
+# Wait until the rows are flushed to the table files.
+FLUSH TABLE t1;
# Check what we have now
-# must wait so that the delayed thread finishes
-# Note: this must be increased if the test fails
---sleep 1
select * from t1 order by a;
DROP TABLE t1;
+
+#
+# Bug#20627 - INSERT DELAYED does not honour auto_increment_* variables
+#
+SET @bug20627_old_auto_increment_offset=
+ @@auto_increment_offset= 2;
+SET @bug20627_old_auto_increment_increment=
+ @@auto_increment_increment= 3;
+SET @bug20627_old_session_auto_increment_offset=
+ @@session.auto_increment_offset= 4;
+SET @bug20627_old_session_auto_increment_increment=
+ @@session.auto_increment_increment= 5;
+SET @@auto_increment_offset= 2;
+SET @@auto_increment_increment= 3;
+SET @@session.auto_increment_offset= 4;
+SET @@session.auto_increment_increment= 5;
+#
+# Normal insert as reference.
+CREATE TABLE t1 (
+ c1 INT NOT NULL AUTO_INCREMENT,
+ PRIMARY KEY (c1)
+ );
+INSERT INTO t1 VALUES (NULL),(NULL),(NULL);
+# Check what we have now
+SELECT * FROM t1;
+DROP TABLE t1;
+#
+# Delayed insert.
+CREATE TABLE t1 (
+ c1 INT NOT NULL AUTO_INCREMENT,
+ PRIMARY KEY (c1)
+ );
+INSERT DELAYED INTO t1 VALUES (NULL),(NULL),(NULL);
+# Wait until the rows are flushed to the table files.
+FLUSH TABLE t1;
+# Check what we have now
+SELECT * FROM t1;
+DROP TABLE t1;
+#
+# Cleanup
+SET @@auto_increment_offset=
+ @bug20627_old_auto_increment_offset;
+SET @@auto_increment_increment=
+ @bug20627_old_auto_increment_increment;
+SET @@session.auto_increment_offset=
+ @bug20627_old_session_auto_increment_offset;
+SET @@session.auto_increment_increment=
+ @bug20627_old_session_auto_increment_increment;
+
+#
+# Bug#20830 - INSERT DELAYED does not honour SET INSERT_ID
+#
+SET @bug20830_old_auto_increment_offset=
+ @@auto_increment_offset= 2;
+SET @bug20830_old_auto_increment_increment=
+ @@auto_increment_increment= 3;
+SET @bug20830_old_session_auto_increment_offset=
+ @@session.auto_increment_offset= 4;
+SET @bug20830_old_session_auto_increment_increment=
+ @@session.auto_increment_increment= 5;
+SET @@auto_increment_offset= 2;
+SET @@auto_increment_increment= 3;
+SET @@session.auto_increment_offset= 4;
+SET @@session.auto_increment_increment= 5;
+#
+# Normal insert as reference.
+CREATE TABLE t1 (
+ c1 INT(11) NOT NULL AUTO_INCREMENT,
+ c2 INT(11) DEFAULT NULL,
+ PRIMARY KEY (c1)
+ );
+SET insert_id= 14;
+INSERT INTO t1 VALUES(NULL, 11), (NULL, 12), (NULL, 13);
+INSERT INTO t1 VALUES(NULL, 21), (NULL, 22), (NULL, 23);
+# Restart sequence at a different value.
+INSERT INTO t1 VALUES( 69, 31), (NULL, 32), (NULL, 33);
+INSERT INTO t1 VALUES(NULL, 41), (NULL, 42), (NULL, 43);
+# Restart sequence at a different value.
+SET insert_id= 114;
+INSERT INTO t1 VALUES(NULL, 51), (NULL, 52), (NULL, 53);
+INSERT INTO t1 VALUES(NULL, 61), (NULL, 62), (NULL, 63);
+# Set one value below the maximum value.
+INSERT INTO t1 VALUES( 49, 71), (NULL, 72), (NULL, 73);
+INSERT INTO t1 VALUES(NULL, 81), (NULL, 82), (NULL, 83);
+# Create a duplicate value.
+SET insert_id= 114;
+--error 1062
+INSERT INTO t1 VALUES(NULL, 91);
+INSERT INTO t1 VALUES (NULL, 92), (NULL, 93);
+# Check what we have now
+SELECT * FROM t1;
+SELECT COUNT(*) FROM t1;
+SELECT SUM(c1) FROM t1;
+DROP TABLE t1;
+#
+# Delayed insert.
+CREATE TABLE t1 (
+ c1 INT(11) NOT NULL AUTO_INCREMENT,
+ c2 INT(11) DEFAULT NULL,
+ PRIMARY KEY (c1)
+ );
+SET insert_id= 14;
+INSERT DELAYED INTO t1 VALUES(NULL, 11), (NULL, 12), (NULL, 13);
+INSERT DELAYED INTO t1 VALUES(NULL, 21), (NULL, 22), (NULL, 23);
+# Restart sequence at a different value.
+INSERT DELAYED INTO t1 VALUES( 69, 31), (NULL, 32), (NULL, 33);
+INSERT DELAYED INTO t1 VALUES(NULL, 41), (NULL, 42), (NULL, 43);
+# Restart sequence at a different value.
+SET insert_id= 114;
+INSERT DELAYED INTO t1 VALUES(NULL, 51), (NULL, 52), (NULL, 53);
+INSERT DELAYED INTO t1 VALUES(NULL, 61), (NULL, 62), (NULL, 63);
+# Set one value below the maximum value.
+INSERT DELAYED INTO t1 VALUES( 49, 71), (NULL, 72), (NULL, 73);
+INSERT DELAYED INTO t1 VALUES(NULL, 81), (NULL, 82), (NULL, 83);
+# Create a duplicate value.
+SET insert_id= 114;
+INSERT DELAYED INTO t1 VALUES(NULL, 91);
+INSERT DELAYED INTO t1 VALUES (NULL, 92), (NULL, 93);
+# Wait until the rows are flushed to the table files.
+FLUSH TABLE t1;
+# Check what we have now
+SELECT * FROM t1;
+SELECT COUNT(*) FROM t1;
+SELECT SUM(c1) FROM t1;
+DROP TABLE t1;
+#
+# Cleanup
+SET @@auto_increment_offset=
+ @bug20830_old_auto_increment_offset;
+SET @@auto_increment_increment=
+ @bug20830_old_auto_increment_increment;
+SET @@session.auto_increment_offset=
+ @bug20830_old_session_auto_increment_offset;
+SET @@session.auto_increment_increment=
+ @bug20830_old_session_auto_increment_increment;
+
diff --git a/mysql-test/t/disabled.def b/mysql-test/t/disabled.def
index aa301eb5566..8c4a76c78a9 100644
--- a/mysql-test/t/disabled.def
+++ b/mysql-test/t/disabled.def
@@ -42,8 +42,5 @@ rpl_multi_engine : BUG#22583 2006-09-23 lars
#rpl_ndb_idempotent : BUG#21298 2006-07-27 msvensson
#rpl_row_basic_7ndb : BUG#21298 2006-07-27 msvensson
#rpl_truncate_7ndb : BUG#21298 2006-07-27 msvensson
-crash_commit_before : 2006-08-02 msvensson
-func_group : BUG#21924 2006-08-30 reggie
-func_in : BUG#21925 2006-08-30 reggie
ndb_binlog_discover : bug#21806 2006-08-24
ndb_autodiscover3 : bug#21806
diff --git a/mysql-test/t/execution_constants.test b/mysql-test/t/execution_constants.test
new file mode 100644
index 00000000000..00967b2eeba
--- /dev/null
+++ b/mysql-test/t/execution_constants.test
@@ -0,0 +1,74 @@
+#
+# Bug#21476: Lost Database Connection During Query
+#
+# When the amount of stack space we think we need to report an error is
+# actually too small, then we can get SEGVs. But, we don't want to reserve
+# space that we could use to get real work done. So, we want the reserved
+# space small, and this test verifies that the reservation is not too small.
+
+CREATE TABLE `t_bug21476` (
+ `ID_BOARD` smallint(5) unsigned NOT NULL default '0',
+ `ID_MEMBER` mediumint(8) unsigned NOT NULL default '0',
+ `logTime` int(10) unsigned NOT NULL default '0',
+ `ID_MSG` mediumint(8) unsigned NOT NULL default '0',
+ PRIMARY KEY (`ID_MEMBER`,`ID_BOARD`),
+ KEY `logTime` (`logTime`)
+) ENGINE=MyISAM DEFAULT CHARSET=cp1251 COLLATE=cp1251_bulgarian_ci;
+
+INSERT INTO `t_bug21476` VALUES (2,2,1154870939,0),(1,2,1154870957,0),(2,183,1154941362,0),(2,84,1154904301,0),(1,84,1154905867,0),(2,13,1154947484,10271),(3,84,1154880549,0),(1,6,1154892183,0),(2,25,1154947581,10271),(3,25,1154904760,0),(1,25,1154947373,10271),(1,179,1154899992,0),(2,179,1154899410,0),(5,25,1154901666,0),(2,329,1154902026,0),(3,329,1154902040,0),(1,329,1154902058,0),(1,13,1154930841,0),(3,85,1154904987,0),(1,183,1154929665,0),(3,13,1154931268,0),(1,85,1154936888,0),(1,169,1154937959,0),(2,169,1154941717,0),(3,183,1154939810,0),(3,169,1154941734,0);
+
+delimiter //;
+let $query_head=UPDATE t_bug21476 SET ID_MSG = IF(logTime BETWEEN 1 AND 1101770053, 2, //
+let $query_tail =) WHERE logTime BETWEEN 1 AND 1104091539 AND ID_MSG = 0//
+
+# Scan over the possible stack heights, trying to recurse to exactly that
+# depth. Eventually, we will reach our imposed limit on height and try to
+# raise an error. If the remaining stack space is enough to raise that error,
+# we will get an error-number of 1436 and quit the loop. If it's not enough
+# space, we should get a SEGV
+
+# Well more than enough recursions to find the end of our stack.
+let $i = 100000//
+disable_query_log//
+disable_result_log//
+while ($i)
+{
+ # If we SEGV because the min stack size is exceeded, this would return error
+ # 2013 .
+ error 0,1436 //
+ eval $query_head 0 $query_tail//
+
+ if ($mysql_errno != 1436)
+ {
+ # We reached the place where we reported an error about the stack limit,
+ # and we successfully returned the error. That means that at the stack
+ # limit, we still have enough space reserved to report an error.
+ let $i = 1//
+ }
+
+ # Multiplying by three stack frames should be fine enough resolution.
+ # Trading exactness for speed.
+
+ # go one more level deep
+ let $query_head = $query_head IF(logTime <= 1104091$i, $i, //
+ let $query_tail =) $query_tail//
+
+ # go one more level deep
+ let $query_head = $query_head IF(logTime <= 1105091$i, $i, //
+ let $query_tail =) $query_tail//
+
+ # go one more level deep
+ let $query_head = $query_head IF(logTime <= 1106091$i, $i, //
+ let $query_tail =) $query_tail//
+
+ dec $i//
+}
+enable_result_log//
+enable_query_log//
+
+echo Assertion: mysql_errno 1436 == $mysql_errno//
+
+delimiter ;//
+DROP TABLE `t_bug21476`;
+
+--echo End of 5.0 tests.
diff --git a/mysql-test/t/func_gconcat.test b/mysql-test/t/func_gconcat.test
index 7a0d90961e4..19753430dde 100644
--- a/mysql-test/t/func_gconcat.test
+++ b/mysql-test/t/func_gconcat.test
@@ -447,3 +447,18 @@ SELECT a, CHAR_LENGTH(b) FROM t1;
SELECT CHAR_LENGTH( GROUP_CONCAT(b) ) FROM t1;
SET GROUP_CONCAT_MAX_LEN = 1024;
DROP TABLE t1;
+
+#
+# Bug #22015: crash with GROUP_CONCAT over a derived table that
+# returns the results of aggregation by GROUP_CONCAT
+#
+
+CREATE TABLE t1 (a int, b int);
+
+INSERT INTO t1 VALUES (2,1), (1,2), (2,2), (1,3);
+
+SELECT GROUP_CONCAT(a), x
+ FROM (SELECT a, GROUP_CONCAT(b) x FROM t1 GROUP BY a) AS s
+ GROUP BY x;
+
+DROP TABLE t1;
diff --git a/mysql-test/t/func_in.test b/mysql-test/t/func_in.test
index 8ddf1fbe314..906747c2f78 100644
--- a/mysql-test/t/func_in.test
+++ b/mysql-test/t/func_in.test
@@ -232,3 +232,27 @@ 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;
+
+#
+# Bug#18360: Type aggregation for IN and CASE may lead to a wrong result
+#
+create table t1(f1 char(1));
+insert into t1 values ('a'),('b'),('1');
+select f1 from t1 where f1 in ('a',1);
+select f1, case f1 when 'a' then '+' when 1 then '-' end from t1;
+create index t1f1_idx on t1(f1);
+select f1 from t1 where f1 in ('a',1);
+explain select f1 from t1 where f1 in ('a',1);
+select f1 from t1 where f1 in ('a','b');
+explain select f1 from t1 where f1 in ('a','b');
+select f1 from t1 where f1 in (2,1);
+explain select f1 from t1 where f1 in (2,1);
+create table t2(f2 int, index t2f2(f2));
+insert into t2 values(0),(1),(2);
+select f2 from t2 where f2 in ('a',2);
+explain select f2 from t2 where f2 in ('a',2);
+select f2 from t2 where f2 in ('a','b');
+explain select f2 from t2 where f2 in ('a','b');
+select f2 from t2 where f2 in (1,'b');
+explain select f2 from t2 where f2 in (1,'b');
+drop table t1, t2;
diff --git a/mysql-test/t/func_time.test b/mysql-test/t/func_time.test
index 08d3ff14ca1..d49a4fed9d2 100644
--- a/mysql-test/t/func_time.test
+++ b/mysql-test/t/func_time.test
@@ -447,6 +447,25 @@ show create table t1;
drop table t1;
#
+# 21913: DATE_FORMAT() Crashes mysql server if I use it through
+# mysql-connector-j driver.
+#
+
+SET NAMES latin1;
+SET character_set_results = NULL;
+SHOW VARIABLES LIKE 'character_set_results';
+
+CREATE TABLE testBug8868 (field1 DATE, field2 VARCHAR(32) CHARACTER SET BINARY);
+INSERT INTO testBug8868 VALUES ('2006-09-04', 'abcd');
+
+SELECT DATE_FORMAT(field1,'%b-%e %l:%i%p') as fmtddate, field2 FROM testBug8868;
+
+DROP TABLE testBug8868;
+
+SET NAMES DEFAULT;
+
+
+#
# Bug #19844 time_format in Union truncates values
#
diff --git a/mysql-test/t/im_daemon_life_cycle.imtest b/mysql-test/t/im_daemon_life_cycle.imtest
index a07da161279..55e52f4e464 100644
--- a/mysql-test/t/im_daemon_life_cycle.imtest
+++ b/mysql-test/t/im_daemon_life_cycle.imtest
@@ -14,3 +14,47 @@
# process.
--exec $MYSQL_TEST_DIR/t/kill_n_check.sh $IM_PATH_PID restarted 30
+
+###########################################################################
+
+#
+# BUG#12751: Instance Manager: client hangs
+#
+
+--echo
+--echo --------------------------------------------------------------------
+--echo -- Test for BUG#12751
+--echo --------------------------------------------------------------------
+
+# Give some time to begin accepting connections after restart.
+# FIXME: race condition here.
+
+--sleep 3
+
+# 1. Start mysqld;
+
+START INSTANCE mysqld2;
+# FIXME: START INSTANCE should be synchronous.
+--exec $MYSQL_TEST_DIR/t/wait_for_process.sh $IM_MYSQLD2_PATH_PID 30 started
+
+# 2. Restart IM-main: kill it and IM-angel will restart it.
+
+--exec $MYSQL_TEST_DIR/t/kill_n_check.sh $IM_PATH_PID restarted 30
+
+# 3. Issue some statement -- connection should be re-established.
+
+# Give some time to begin accepting connections after restart.
+# FIXME: race condition here.
+
+--sleep 3
+
+--replace_column 3 VERSION_NUMBER 4 VERSION
+SHOW INSTANCE STATUS mysqld1;
+
+# 4. Stop mysqld2, because it will not be stopped by IM, as it is nonguarded.
+# So, if it we do not stop it, it will be stopped by mysql-test-run.pl with
+# warning.
+
+STOP INSTANCE mysqld2;
+# FIXME: STOP INSTANCE should be synchronous.
+--exec $MYSQL_TEST_DIR/t/wait_for_process.sh $IM_MYSQLD2_PATH_PID 30 stopped
diff --git a/mysql-test/t/join.test b/mysql-test/t/join.test
index 98bfb33b1e6..d0005f3b8f7 100644
--- a/mysql-test/t/join.test
+++ b/mysql-test/t/join.test
@@ -609,3 +609,24 @@ explain select * from t2,t3 where t2.a < 200 and t2.b=t3.b;
drop table t1, t2, t3;
+# BUG#14940 {Wrong query plan is chosen because of odd results of
+# prev_record_reads() function }
+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, primary key(a));
+insert into t2 select @v:=A.a+10*B.a, @v from t1 A, t1 B;
+
+explain select * from t1;
+show status like '%cost%';
+select 'The cost of accessing t1 (dont care if it changes' '^';
+
+select 'vv: Following query must use ALL(t1), eq_ref(A), eq_ref(B): vv' Z;
+
+explain select * from t1, t2 A, t2 B where A.a = t1.a and B.a=A.b;
+show status like '%cost%';
+select '^^: The above should be ~= 20 + cost(select * from t1). Value less than 20 is an error' Z;
+
+
+
+drop table t1, t2;
diff --git a/mysql-test/t/kill_n_check.sh b/mysql-test/t/kill_n_check.sh
index 64cc869d1ec..a54fb6ef8bb 100755
--- a/mysql-test/t/kill_n_check.sh
+++ b/mysql-test/t/kill_n_check.sh
@@ -49,7 +49,7 @@ if [ -z "$pid_path" ]; then
exit 0
fi
-if [ $expected_result = 'killed' -a ! -r "$pid_path" ]; then
+if [ ! -r "$pid_path" ]; then
echo "Error: PID file ($pid_path) does not exist."
exit 0
fi
diff --git a/mysql-test/t/lowercase_fs_off.test b/mysql-test/t/lowercase_fs_off.test
index 7f7b573e7ee..883315994fe 100644
--- a/mysql-test/t/lowercase_fs_off.test
+++ b/mysql-test/t/lowercase_fs_off.test
@@ -3,6 +3,7 @@
# i.e. lower_case_filesystem=OFF
#
-- source include/have_case_sensitive_file_system.inc
+-- source include/not_embedded.inc
connect (master,localhost,root,,);
connection master;
diff --git a/mysql-test/t/merge.test b/mysql-test/t/merge.test
index f8bed9c92cd..5498468d902 100644
--- a/mysql-test/t/merge.test
+++ b/mysql-test/t/merge.test
@@ -124,6 +124,7 @@ drop table t3,t2,t1;
# Test table without unions
#
create table t1 (a int not null, key(a)) engine=merge;
+--error 1030
select * from t1;
drop table t1;
@@ -381,6 +382,31 @@ select * from t3;
check table t1, t2;
drop table t1, t2, t3;
+#
+# BUG#21617 - crash when selecting from merge table with inconsistent
+# indexes
+#
+CREATE TABLE t1(a INT);
+INSERT INTO t1 VALUES(2),(1);
+CREATE TABLE t2(a INT, KEY(a)) ENGINE=MERGE UNION=(t1);
+--error 1030
+SELECT * FROM t2 WHERE a=2;
+DROP TABLE t1, t2;
+
+#
+# BUG#10974 - No error message if merge table based on union of innodb,
+# memory
+#
+CREATE TABLE t1(a INT) ENGINE=MEMORY;
+CREATE TABLE t2(a INT) ENGINE=MERGE UNION=(t1);
+--error 1168
+SELECT * FROM t2;
+DROP TABLE t1, t2;
+CREATE TABLE t2(a INT) ENGINE=MERGE UNION=(t3);
+--error 1168
+SELECT * FROM t2;
+DROP TABLE t2;
+
# End of 4.1 tests
#
diff --git a/mysql-test/t/mysql.test b/mysql-test/t/mysql.test
index 9e3eabf474b..f3296e6f706 100644
--- a/mysql-test/t/mysql.test
+++ b/mysql-test/t/mysql.test
@@ -63,6 +63,12 @@ drop table t1;
--exec $MYSQL -t test -e "create table t1 (col1 binary(4), col2 varchar(10), col3 int); insert into t1 values ('a', 'b', 123421),('a ', '0123456789', 4), ('abcd', '', 4); select concat('>',col1,'<'), col2, col3 from t1; drop table t1;" 2>&1
#
+# Bug#17939 Wrong table format when using UTF8 strings
+#
+--exec $MYSQL --default-character-set=utf8 --table -e "SELECT 'John Doe' as '__tañgè Ñãmé'" 2>&1
+--exec $MYSQL --default-character-set=utf8 --table -e "SELECT '__tañgè Ñãmé' as 'John Doe'" 2>&1
+
+#
# Bug#18265 -- mysql client: No longer right-justifies numeric columns
#
--exec $MYSQL -t --default-character-set utf8 test -e "create table t1 (i int, j int, k char(25) charset utf8); insert into t1 (i) values (1); insert into t1 (k) values ('<----------------------->'); insert into t1 (k) values ('<-----'); insert into t1 (k) values ('Τη γλώσσα'); insert into t1 (k) values ('á›–áš´ áš·á›–á›'); select * from t1; DROP TABLE t1;"
diff --git a/mysql-test/t/mysqltest.test b/mysql-test/t/mysqltest.test
index 04e0532851a..25f8d63d0b2 100644
--- a/mysql-test/t/mysqltest.test
+++ b/mysql-test/t/mysqltest.test
@@ -507,9 +507,21 @@ echo $where2;
let $where3=a long $where variable content;
echo $where3;
+let $where3=a long \\\$where variable content;
+echo $where3;
+
let $novar1= $novar2;
echo $novar1;
+let $cat=na;
+let $cat=ba$cat$cat;
+echo banana = $cat;
+
+# ba\$cat\$cat should have been sufficient.
+# ba\\\$cat\\\$cat -> ba\$cat\$cat -> ba$cat$cat -> banana
+# Magnus' upcoming patch will fix the missing second interpretation.
+let $cat=ba\\\$cat\\\$cat;
+echo Not a banana: $cat;
# Test illegal uses of let
diff --git a/mysql-test/t/ndb_config.test b/mysql-test/t/ndb_config.test
index 2fe54cac048..f63c0087c1e 100644
--- a/mysql-test/t/ndb_config.test
+++ b/mysql-test/t/ndb_config.test
@@ -15,3 +15,9 @@
--exec $NDB_TOOLS_DIR/ndb_config --defaults-group-suffix=.cluster0 --defaults-file=$MYSQL_TEST_DIR/std_data/ndb_config_mycnf2.cnf --query=type,nodeid,host --mycnf 2> /dev/null
--exec $NDB_TOOLS_DIR/ndb_config --defaults-group-suffix=.cluster1 --defaults-file=$MYSQL_TEST_DIR/std_data/ndb_config_mycnf2.cnf --query=type,nodeid,host --mycnf 2> /dev/null
--exec $NDB_TOOLS_DIR/ndb_config --defaults-group-suffix=.cluster2 --defaults-file=$MYSQL_TEST_DIR/std_data/ndb_config_mycnf2.cnf --query=type,nodeid,host --mycnf 2> /dev/null
+--exec $NDB_TOOLS_DIR/ndb_config --defaults-group-suffix=.cluster2 --defaults-file=$MYSQL_TEST_DIR/std_data/ndb_config_mycnf2.cnf --ndb-shm --connections --query=type,nodeid1,nodeid2,group,nodeidserver --mycnf 2> /dev/null
+
+
+--exec $NDB_TOOLS_DIR/ndb_config --no-defaults --query=nodeid --host=localhost --config-file=$NDB_BACKUP_DIR/config.ini 2> /dev/null
+--exec $NDB_TOOLS_DIR/ndb_config --no-defaults --query=nodeid --host=1.2.3.4 --config-file=$NDB_BACKUP_DIR/config.ini 2> /dev/null
+--exec $NDB_TOOLS_DIR/ndb_config --no-defaults --query=nodeid --host=127.0.0.1 --config-file=$NDB_BACKUP_DIR/config.ini 2> /dev/null
diff --git a/mysql-test/t/ps.test b/mysql-test/t/ps.test
index e86420f4364..ac79dbc3434 100644
--- a/mysql-test/t/ps.test
+++ b/mysql-test/t/ps.test
@@ -988,6 +988,58 @@ execute stmt;
drop temporary table t1;
deallocate prepare stmt;
+#
+# BUG#22085: Crash on the execution of a prepared statement that
+# uses an IN subquery with aggregate functions in HAVING
+#
+
+CREATE TABLE t1(
+ ID int(10) unsigned NOT NULL auto_increment,
+ Member_ID varchar(15) NOT NULL default '',
+ Action varchar(12) NOT NULL,
+ Action_Date datetime NOT NULL,
+ Track varchar(15) default NULL,
+ User varchar(12) default NULL,
+ Date_Updated timestamp NOT NULL default CURRENT_TIMESTAMP on update
+ CURRENT_TIMESTAMP,
+ PRIMARY KEY (ID),
+ KEY Action (Action),
+ KEY Action_Date (Action_Date)
+);
+
+INSERT INTO t1(Member_ID, Action, Action_Date, Track) VALUES
+ ('111111', 'Disenrolled', '2006-03-01', 'CAD' ),
+ ('111111', 'Enrolled', '2006-03-01', 'CAD' ),
+ ('111111', 'Disenrolled', '2006-07-03', 'CAD' ),
+ ('222222', 'Enrolled', '2006-03-07', 'CAD' ),
+ ('222222', 'Enrolled', '2006-03-07', 'CHF' ),
+ ('222222', 'Disenrolled', '2006-08-02', 'CHF' ),
+ ('333333', 'Enrolled', '2006-03-01', 'CAD' ),
+ ('333333', 'Disenrolled', '2006-03-01', 'CAD' ),
+ ('444444', 'Enrolled', '2006-03-01', 'CAD' ),
+ ('555555', 'Disenrolled', '2006-03-01', 'CAD' ),
+ ('555555', 'Enrolled', '2006-07-21', 'CAD' ),
+ ('555555', 'Disenrolled', '2006-03-01', 'CHF' ),
+ ('666666', 'Enrolled', '2006-02-09', 'CAD' ),
+ ('666666', 'Enrolled', '2006-05-12', 'CHF' ),
+ ('666666', 'Disenrolled', '2006-06-01', 'CAD' );
+
+PREPARE STMT FROM
+"SELECT GROUP_CONCAT(Track SEPARATOR ', ') FROM t1
+ WHERE Member_ID=? AND Action='Enrolled' AND
+ (Track,Action_Date) IN (SELECT Track, MAX(Action_Date) FROM t1
+ WHERE Member_ID=?
+ GROUP BY Track
+ HAVING Track>='CAD' AND
+ MAX(Action_Date)>'2006-03-01')";
+SET @id='111111';
+EXECUTE STMT USING @id,@id;
+SET @id='222222';
+EXECUTE STMT USING @id,@id;
+
+DEALLOCATE PREPARE STMT;
+DROP TABLE t1;
+
--echo End of 4.1 tests
############################# 5.0 tests start ################################
#
@@ -1358,6 +1410,33 @@ DEALLOCATE PREPARE stmt;
DROP TABLE IF EXISTS t1, t2, t3;
+#
+# BUG#21081: SELECT inside stored procedure returns wrong results
+#
+--disable_warnings
+DROP TABLE IF EXISTS t1, t2;
+--enable_warnings
+
+CREATE TABLE t1 (i INT KEY);
+CREATE TABLE t2 (i INT);
+
+INSERT INTO t1 VALUES (1), (2);
+INSERT INTO t2 VALUES (1);
+
+PREPARE stmt FROM "SELECT t2.i FROM t1 LEFT JOIN t2 ON t2.i = t1.i
+ WHERE t1.i = ?";
+
+SET @arg= 1;
+EXECUTE stmt USING @arg;
+SET @arg= 2;
+EXECUTE stmt USING @arg;
+SET @arg= 1;
+EXECUTE stmt USING @arg;
+
+DEALLOCATE PREPARE stmt;
+DROP TABLE t1, t2;
+
+
--echo End of 5.0 tests.
#
diff --git a/mysql-test/t/range.test b/mysql-test/t/range.test
index 89508f468a7..1a80234e485 100644
--- a/mysql-test/t/range.test
+++ b/mysql-test/t/range.test
@@ -740,3 +740,30 @@ SELECT * FROM t1 WHERE item='A1' AND started<='2005-12-02 00:00:00';
DROP TABLE t1;
# End of 5.0 tests
+
+# BUG#22393 fix: Adjust 'ref' estimate if we have 'range' estimate for
+# a smaller scan interval
+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, filler char(100));
+insert into t2 select A.a + 10 * (B.a + 10 * C.a), 10, 'filler' from t1 A,
+t1 B, t1 C where A.a < 5;
+
+insert into t2 select 1000, b, 'filler' from t2;
+alter table t2 add index (a,b);
+# t2 values
+# ( 1 , 10, 'filler')
+# ( 2 , 10, 'filler')
+# ( 3 , 10, 'filler')
+# (... , 10, 'filler')
+# ...
+# (1000, 10, 'filler') - 500 times
+
+# 500 rows, 1 row
+
+select 'In following EXPLAIN the access method should be ref, #rows~=500 (and not 2)' Z;
+explain select * from t2 where a=1000 and b<11;
+
+drop table t1, t2;
+
diff --git a/mysql-test/t/round.test b/mysql-test/t/round.test
new file mode 100644
index 00000000000..d018fa7e34e
--- /dev/null
+++ b/mysql-test/t/round.test
@@ -0,0 +1,145 @@
+--disable_warnings
+DROP TABLE IF EXISTS t1;
+--enable_warnings
+
+CREATE TABLE t1 (sint8 tinyint not null);
+INSERT INTO t1 VALUES ('0.1');
+INSERT INTO t1 VALUES ('0.5');
+INSERT INTO t1 VALUES ('127.4');
+INSERT INTO t1 VALUES ('127.5');
+INSERT INTO t1 VALUES ('-0.1');
+INSERT INTO t1 VALUES ('-0.5');
+INSERT INTO t1 VALUES ('-127.4');
+INSERT INTO t1 VALUES ('-127.5');
+INSERT INTO t1 VALUES ('-128.4');
+INSERT INTO t1 VALUES ('-128.5');
+SELECT * FROM t1;
+DROP TABLE t1;
+
+CREATE TABLE t1 (uint8 tinyint unsigned not null);
+INSERT INTO t1 VALUES ('0.1');
+INSERT INTO t1 VALUES ('0.5');
+INSERT INTO t1 VALUES ('127.4');
+INSERT INTO t1 VALUES ('127.5');
+INSERT INTO t1 VALUES ('-0.1');
+INSERT INTO t1 VALUES ('-0.5');
+INSERT INTO t1 VALUES ('255.4');
+INSERT INTO t1 VALUES ('255.5');
+SELECT * FROM t1;
+DROP TABLE t1;
+
+
+CREATE TABLE t1 (sint16 smallint not null);
+INSERT INTO t1 VALUES ('0.1');
+INSERT INTO t1 VALUES ('0.5');
+INSERT INTO t1 VALUES ('32767.4');
+INSERT INTO t1 VALUES ('32767.5');
+INSERT INTO t1 VALUES ('-0.1');
+INSERT INTO t1 VALUES ('-0.5');
+INSERT INTO t1 VALUES ('-32767.4');
+INSERT INTO t1 VALUES ('-32767.5');
+INSERT INTO t1 VALUES ('-32768.4');
+INSERT INTO t1 VALUES ('-32768.5');
+SELECT * FROM t1;
+DROP TABLE t1;
+
+
+CREATE TABLE t1 (uint16 smallint unsigned not null);
+INSERT INTO t1 VALUES ('0.1');
+INSERT INTO t1 VALUES ('0.5');
+INSERT INTO t1 VALUES ('32767.4');
+INSERT INTO t1 VALUES ('32767.5');
+INSERT INTO t1 VALUES ('-0.1');
+INSERT INTO t1 VALUES ('-0.5');
+INSERT INTO t1 VALUES ('65535.4');
+INSERT INTO t1 VALUES ('65535.5');
+SELECT * FROM t1;
+DROP TABLE t1;
+
+CREATE TABLE t1 (sint24 mediumint not null);
+INSERT INTO t1 VALUES ('0.1');
+INSERT INTO t1 VALUES ('0.5');
+INSERT INTO t1 VALUES ('8388607.4');
+INSERT INTO t1 VALUES ('8388607.5');
+INSERT INTO t1 VALUES ('-0.1');
+INSERT INTO t1 VALUES ('-0.5');
+INSERT INTO t1 VALUES ('-8388607.4');
+INSERT INTO t1 VALUES ('-8388607.5');
+INSERT INTO t1 VALUES ('-8388608.4');
+INSERT INTO t1 VALUES ('-8388608.5');
+SELECT * FROM t1;
+DROP TABLE t1;
+
+CREATE TABLE t1 (uint24 mediumint unsigned not null);
+INSERT INTO t1 VALUES ('0.1');
+INSERT INTO t1 VALUES ('0.5');
+INSERT INTO t1 VALUES ('8388607.4');
+INSERT INTO t1 VALUES ('8388607.5');
+INSERT INTO t1 VALUES ('-0.1');
+INSERT INTO t1 VALUES ('-0.5');
+INSERT INTO t1 VALUES ('16777215.4');
+INSERT INTO t1 VALUES ('16777215.5');
+SELECT * FROM t1;
+DROP TABLE t1;
+
+CREATE TABLE t1 (sint64 bigint not null);
+INSERT INTO t1 VALUES ('0.1');
+INSERT INTO t1 VALUES ('0.5');
+INSERT INTO t1 VALUES ('9223372036854775807.4');
+INSERT INTO t1 VALUES ('9223372036854775807.5');
+INSERT INTO t1 VALUES ('-0.1');
+INSERT INTO t1 VALUES ('-0.5');
+INSERT INTO t1 VALUES ('-9223372036854775807.4');
+INSERT INTO t1 VALUES ('-9223372036854775807.5');
+INSERT INTO t1 VALUES ('-9223372036854775808.4');
+INSERT INTO t1 VALUES ('-9223372036854775808.5');
+SELECT * FROM t1;
+DROP TABLE t1;
+
+CREATE TABLE t1 (uint64 bigint unsigned not null);
+INSERT INTO t1 VALUES ('0.1');
+INSERT INTO t1 VALUES ('0.5');
+INSERT INTO t1 VALUES ('9223372036854775807.4');
+INSERT INTO t1 VALUES ('9223372036854775807.5');
+INSERT INTO t1 VALUES ('-0.1');
+INSERT INTO t1 VALUES ('-0.5');
+INSERT INTO t1 VALUES ('18446744073709551615.4');
+INSERT INTO t1 VALUES ('18446744073709551615.5');
+INSERT INTO t1 VALUES ('1844674407370955161.0');
+INSERT INTO t1 VALUES ('1844674407370955161.1');
+INSERT INTO t1 VALUES ('1844674407370955161.2');
+INSERT INTO t1 VALUES ('1844674407370955161.3');
+INSERT INTO t1 VALUES ('1844674407370955161.4');
+INSERT INTO t1 VALUES ('1844674407370955161.5');
+INSERT INTO t1 VALUES ('1844674407370955161.0e1');
+INSERT INTO t1 VALUES ('1844674407370955161.1e1');
+INSERT INTO t1 VALUES ('1844674407370955161.2e1');
+INSERT INTO t1 VALUES ('1844674407370955161.3e1');
+INSERT INTO t1 VALUES ('1844674407370955161.4e1');
+INSERT INTO t1 VALUES ('1844674407370955161.5e1');
+INSERT INTO t1 VALUES ('18446744073709551610e-1');
+INSERT INTO t1 VALUES ('18446744073709551611e-1');
+INSERT INTO t1 VALUES ('18446744073709551612e-1');
+INSERT INTO t1 VALUES ('18446744073709551613e-1');
+INSERT INTO t1 VALUES ('18446744073709551614e-1');
+INSERT INTO t1 VALUES ('18446744073709551615e-1');
+SELECT * FROM t1;
+DROP TABLE t1;
+
+CREATE TABLE t1 (str varchar(128), sint64 bigint not null default 0);
+INSERT INTO t1 (str) VALUES ('1.5');
+INSERT INTO t1 (str) VALUES ('1.00005e4');
+INSERT INTO t1 (str) VALUES ('1.0005e3');
+INSERT INTO t1 (str) VALUES ('1.005e2');
+INSERT INTO t1 (str) VALUES ('1.05e1');
+INSERT INTO t1 (str) VALUES ('1.5e0');
+INSERT INTO t1 (str) VALUES ('100005e-1');
+INSERT INTO t1 (str) VALUES ('100050e-2');
+INSERT INTO t1 (str) VALUES ('100500e-3');
+INSERT INTO t1 (str) VALUES ('105000e-4');
+INSERT INTO t1 (str) VALUES ('150000e-5');
+UPDATE t1 SET sint64=str;
+SELECT * FROM t1;
+DROP TABLE t1;
+
+
diff --git a/mysql-test/t/rpl_row_basic_11bugs.test b/mysql-test/t/rpl_row_basic_11bugs.test
index e636824284d..37bfd01e260 100644
--- a/mysql-test/t/rpl_row_basic_11bugs.test
+++ b/mysql-test/t/rpl_row_basic_11bugs.test
@@ -93,4 +93,24 @@ INSERT INTO t1 VALUES (7),(8),(9);
sync_slave_with_master;
SELECT * FROM t1;
-DROP TABLE t1;
+# Bug#22550: Replication of BIT columns failing
+--echo ================ Test for BUG#22550 ================
+--disable_query_log
+--source include/master-slave-reset.inc
+--enable_query_log
+
+connection master;
+CREATE TABLE t1 (a BIT(1), b INT) ENGINE=MYISAM;
+sync_slave_with_master;
+
+connection master;
+INSERT INTO t1 VALUES(1,2);
+SELECT HEX(a),b FROM t1;
+sync_slave_with_master;
+SELECT HEX(a),b FROM t1;
+
+connection master;
+UPDATE t1 SET a=0 WHERE b=2;
+SELECT HEX(a),b FROM t1;
+sync_slave_with_master;
+SELECT HEX(a),b FROM t1;
diff --git a/mysql-test/t/rpl_row_basic_2myisam.test b/mysql-test/t/rpl_row_basic_2myisam.test
index 471f4d6dbc5..c2cef800ec8 100644
--- a/mysql-test/t/rpl_row_basic_2myisam.test
+++ b/mysql-test/t/rpl_row_basic_2myisam.test
@@ -1,3 +1,3 @@
let $type= 'MYISAM' ;
let $extra_index= ;
--- source include/rpl_row_basic.inc
+-- source extra/rpl_tests/rpl_row_basic.test
diff --git a/mysql-test/t/rpl_row_basic_3innodb.test b/mysql-test/t/rpl_row_basic_3innodb.test
index b97f1543cc3..89effc4b3bb 100644
--- a/mysql-test/t/rpl_row_basic_3innodb.test
+++ b/mysql-test/t/rpl_row_basic_3innodb.test
@@ -2,5 +2,5 @@
let $type= 'INNODB' ;
let $extra_index= ;
--- source include/rpl_row_basic.inc
+-- source extra/rpl_tests/rpl_row_basic.test
diff --git a/mysql-test/t/rpl_row_basic_7ndb.test b/mysql-test/t/rpl_row_basic_7ndb.test
index 464600c590a..1ec2fb333ae 100644
--- a/mysql-test/t/rpl_row_basic_7ndb.test
+++ b/mysql-test/t/rpl_row_basic_7ndb.test
@@ -1,5 +1,5 @@
-- source include/have_ndb.inc
let $type= 'NDB' ;
let $extra_index= ;
--- source include/rpl_row_basic.inc
+-- source extra/rpl_tests/rpl_row_basic.test
-- source include/master-slave-end.inc
diff --git a/mysql-test/t/sp.test b/mysql-test/t/sp.test
index 49d6186f389..b3563e21bdd 100644
--- a/mysql-test/t/sp.test
+++ b/mysql-test/t/sp.test
@@ -6258,6 +6258,32 @@ SELECT * FROM t11|
DROP TABLE t11, t12|
DROP FUNCTION bug19862|
+
+# Bug#21002 "Derived table not selecting from a "real" table fails in JOINs"
+#
+# A regression caused by the fix for Bug#18444: for derived tables we should
+# set an empty string as the current database. They do not belong to any
+# database and must be usable even if there is no database
+# selected.
+--disable_warnings
+drop table if exists t3|
+drop database if exists mysqltest1|
+--enable_warnings
+create table t3 (a int)|
+insert into t3 (a) values (1), (2)|
+
+create database mysqltest1|
+use mysqltest1|
+drop database mysqltest1|
+
+# No current database
+select database()|
+
+select * from (select 1 as a) as t1 natural join (select * from test.t3) as t2|
+use test|
+drop table t3|
+
+
# Test for BUG#16899: Possible buffer overflow in handling of DEFINER-clause.
#
# Prepare.
@@ -6291,6 +6317,7 @@ create procedure bug21416() show create procedure bug21416|
call bug21416()|
drop procedure bug21416|
+
#
# BUG#21414: SP: Procedure undroppable, to some extent
#
@@ -6310,6 +6337,21 @@ UNLOCK TABLES|
--echo The following should succeed.
DROP PROCEDURE bug21414|
+
+#
+# BUG#21311: Possible stack overrun if SP has non-latin1 name
+#
+set names utf8|
+--disable_warnings
+drop database if exists това_е_дълго_име_за_база_данни_нали|
+--enable_warnings
+create database това_е_дълго_име_за_база_данни_нали|
+INSERT INTO mysql.proc VALUES ('това_е_дълго_име_за_база_данни_нали','това_е_процедура_Ñ_доÑта_дълго_име_нали_и_още_по_дълго','PROCEDURE','това_е_процедура_Ñ_доÑта_дълго_име_нали_и_още_по_дълго','SQL','CONTAINS_SQL','NO','DEFINER','','','bad_body','root@localhost',now(), now(),'','')|
+--error ER_SP_PROC_TABLE_CORRUPT
+call това_е_дълго_име_за_база_данни_нали.това_е_процедура_Ñ_доÑта_дълго_име_нали_и_още_по_дълго()|
+drop database това_е_дълго_име_за_база_данни_нали|
+
+
#
# BUG#21493: Crash on the second call of a procedure containing
# a select statement that uses an IN aggregating subquery
@@ -6355,9 +6397,9 @@ INSERT INTO t4(Member_ID, Action, Action_Date, Track) VALUES
('666666', 'Enrolled', '2006-05-12', 'CHF' ),
('666666', 'Disenrolled', '2006-06-01', 'CAD' )|
-#--disable_warnings
+--disable_warnings
DROP FUNCTION IF EXISTS bug21493|
-#--enable_warnings
+--enable_warnings
CREATE FUNCTION bug21493(paramMember VARCHAR(15)) RETURNS varchar(45)
BEGIN
diff --git a/mysql-test/t/strict.test b/mysql-test/t/strict.test
index 4037e1231cd..ae5e4365af3 100644
--- a/mysql-test/t/strict.test
+++ b/mysql-test/t/strict.test
@@ -649,9 +649,9 @@ UPDATE t1 SET col2 =col2 + 50 WHERE col2 > 0;
UPDATE t1 SET col1 =col1 / 0 WHERE col1 > 0;
--error 1365
UPDATE t1 SET col1= MOD(col1,0) WHERE col1 > 0;
---error 1264
+--error 1366
INSERT INTO t1 (col1) VALUES ('');
---error 1264
+--error 1366
INSERT INTO t1 (col1) VALUES ('a59b');
--error 1265
INSERT INTO t1 (col1) VALUES ('1a');
@@ -710,9 +710,9 @@ INSERT INTO t1 (col2) VALUES(18446744073709551616.0);
UPDATE t1 SET col1 =col1 / 0 WHERE col1 > 0;
--error 1365
UPDATE t1 SET col1= MOD(col1,0) WHERE col1 > 0;
---error 1264
+--error 1366
INSERT INTO t1 (col1) VALUES ('');
---error 1264
+--error 1366
INSERT INTO t1 (col1) VALUES ('a59b');
--error 1265
INSERT INTO t1 (col1) VALUES ('1a');
diff --git a/mysql-test/t/subselect.test b/mysql-test/t/subselect.test
index a4e535ac418..7811301a9bc 100644
--- a/mysql-test/t/subselect.test
+++ b/mysql-test/t/subselect.test
@@ -665,7 +665,7 @@ CREATE TABLE t2 (
) ENGINE=MyISAM;
INSERT INTO t2 VALUES ('AUS','Australia','Oceania','Australia and New Zealand',7741220.00,1901,18886000,79.8,351182.00,392911.00,'Australia','Constitutional Monarchy, Federation','Elisabeth II',135,'AU');
-INSERT INTO t2 VALUES ('AZE','Azerbaijan','Asia','Middle East',86600.00,1991,7734000,62.9,4127.00,4100.00,'Azärbaycan','Federal Republic','Heydär Äliyev',144,'AZ');
+INSERT INTO t2 VALUES ('AZE','Azerbaijan','Asia','Middle East',86600.00,1991,7734000,62.9,4127.00,4100.00,'Azärbaycan','Federal Republic','Heydär Äliyev',144,'AZ');
select t2.Continent, t1.Name, t1.Population from t2 LEFT JOIN t1 ON t2.Code = t1.t2 where t1.Population IN (select max(t1.Population) AS Population from t1, t2 where t1.t2 = t2.Code group by Continent);
@@ -1526,7 +1526,7 @@ CREATE TABLE t1 (
) ENGINE=MyISAM;
INSERT INTO t1 VALUES ('XXX','Xxxxx','Oceania','Xxxxxx',26.00,0,0,0,0,0,'Xxxxx','Xxxxx','Xxxxx',NULL,'XX');
INSERT INTO t1 VALUES ('ASM','American Samoa','Oceania','Polynesia',199.00,0,68000,75.1,334.00,NULL,'Amerika Samoa','US Territory','George W. Bush',54,'AS');
-INSERT INTO t1 VALUES ('ATF','French Southern territories','Antarctica','Antarctica',7780.00,0,0,NULL,0.00,NULL,'Terres australes françaises','Nonmetropolitan Territory of France','Jacques Chirac',NULL,'TF');
+INSERT INTO t1 VALUES ('ATF','French Southern territories','Antarctica','Antarctica',7780.00,0,0,NULL,0.00,NULL,'Terres australes françaises','Nonmetropolitan Territory of France','Jacques Chirac',NULL,'TF');
INSERT INTO t1 VALUES ('UMI','United States Minor Outlying Islands','Oceania','Micronesia/Caribbean',16.00,0,0,NULL,0.00,NULL,'United States Minor Outlying Islands','Dependent Territory of the US','George W. Bush',NULL,'UM');
/*!40000 ALTER TABLE t1 ENABLE KEYS */;
SELECT DISTINCT Continent AS c FROM t1 WHERE Code <> SOME ( SELECT Code FROM t1 WHERE Continent = c AND Population < 200);
@@ -1918,6 +1918,43 @@ SELECT sql_no_cache t1.a, r.a, r.b FROM t1 LEFT JOIN t2 r
drop table t1,t2;
+#
+# Bug #21853: assert failure for a grouping query with
+# an ALL/ANY quantified subquery in HAVING
+#
+
+CREATE TABLE t1 (
+ field1 int NOT NULL,
+ field2 int NOT NULL,
+ field3 int NOT NULL,
+ PRIMARY KEY (field1,field2,field3)
+);
+CREATE TABLE t2 (
+ fieldA int NOT NULL,
+ fieldB int NOT NULL,
+ PRIMARY KEY (fieldA,fieldB)
+);
+
+INSERT INTO t1 VALUES
+ (1,1,1), (1,1,2), (1,2,1), (1,2,2), (1,2,3), (1,3,1);
+INSERT INTO t2 VALUES (1,1), (1,2), (1,3);
+
+SELECT field1, field2, COUNT(*)
+ FROM t1 GROUP BY field1, field2;
+
+SELECT field1, field2
+ FROM t1
+ GROUP BY field1, field2
+ HAVING COUNT(*) >= ALL (SELECT fieldB
+ FROM t2 WHERE fieldA = field1);
+SELECT field1, field2
+ FROM t1
+ GROUP BY field1, field2
+ HAVING COUNT(*) < ANY (SELECT fieldB
+ FROM t2 WHERE fieldA = field1);
+
+DROP TABLE t1, t2;
+
# End of 4.1 tests
#
@@ -2332,3 +2369,34 @@ explain select * from t1 where not exists
((select t11.i from t1 t11) union (select t12.i from t1 t12));
DROP TABLE t1;
+
+#
+# Bug #21540: Subqueries with no from and aggregate functions return
+# wrong results
+CREATE TABLE t1 (a INT, b INT);
+CREATE TABLE t2 (a INT);
+INSERT INTO t2 values (1);
+INSERT INTO t1 VALUES (1,1),(1,2),(2,3),(3,4);
+SELECT (SELECT COUNT(DISTINCT t1.b) from t2) FROM t1 GROUP BY t1.a;
+SELECT (SELECT COUNT(DISTINCT t1.b) from t2 union select 1 from t2 where 12 < 3)
+ FROM t1 GROUP BY t1.a;
+SELECT COUNT(DISTINCT t1.b), (SELECT COUNT(DISTINCT t1.b)) FROM t1 GROUP BY t1.a;
+SELECT COUNT(DISTINCT t1.b),
+ (SELECT COUNT(DISTINCT t1.b) union select 1 from DUAL where 12 < 3)
+ FROM t1 GROUP BY t1.a;
+SELECT (
+ SELECT (
+ SELECT COUNT(DISTINCT t1.b)
+ )
+)
+FROM t1 GROUP BY t1.a;
+SELECT (
+ SELECT (
+ SELECT (
+ SELECT COUNT(DISTINCT t1.b)
+ )
+ )
+ FROM t1 GROUP BY t1.a LIMIT 1)
+FROM t1 t2
+GROUP BY t2.a;
+DROP TABLE t1,t2;
diff --git a/mysql-test/t/temp_table.test b/mysql-test/t/temp_table.test
index 9121283fb32..123007b10c7 100644
--- a/mysql-test/t/temp_table.test
+++ b/mysql-test/t/temp_table.test
@@ -116,7 +116,54 @@ insert into t2 values (NULL, 'foo'), (NULL, 'bar');
select d, c from t1 left join t2 on b = c where a = 3 order by d;
drop table t1, t2;
-# End of 4.1 tests
+
+#
+# BUG#21096: locking issue ; temporary table conflicts.
+#
+# The problem was that on DROP TEMPORARY table name lock was acquired,
+# which should not be done.
+#
+--disable_warnings
+DROP TABLE IF EXISTS t1;
+--enable_warnings
+
+CREATE TABLE t1 (i INT);
+
+LOCK TABLE t1 WRITE;
+
+connect (conn1, localhost, root,,);
+
+CREATE TEMPORARY TABLE t1 (i INT);
+
+--echo The following command should not block
+DROP TEMPORARY TABLE t1;
+
+disconnect conn1;
+connection default;
+
+DROP TABLE t1;
+
+#
+# Check that it's not possible to drop a base table with
+# DROP TEMPORARY statement.
+#
+CREATE TABLE t1 (i INT);
+CREATE TEMPORARY TABLE t2 (i INT);
+
+--error 1051
+DROP TEMPORARY TABLE t2, t1;
+
+# Table t2 should have been dropped.
+--error 1146
+SELECT * FROM t2;
+# But table t1 should still be there.
+SELECT * FROM t1;
+
+DROP TABLE t1;
+
+
+--echo End of 4.1 tests.
+
#
# Test truncate with temporary tables
diff --git a/mysql-test/t/trigger.test b/mysql-test/t/trigger.test
index cd6de45a7ce..ccc17e55dc8 100644
--- a/mysql-test/t/trigger.test
+++ b/mysql-test/t/trigger.test
@@ -1421,4 +1421,23 @@ DROP TABLE t1;
DROP TABLE t2;
+#
+# Bug#20670 "UPDATE using key and invoking trigger that modifies
+# this key does not stop"
+#
+
+--disable_warnings
+drop table if exists t1;
+--enable_warnings
+create table t1 (i int, j int key);
+insert into t1 values (1,1), (2,2), (3,3);
+create trigger t1_bu before update on t1 for each row
+ set new.j = new.j + 10;
+# This should not work indefinitely and should cause
+# expected result
+update t1 set i= i+ 10 where j > 2;
+select * from t1;
+drop table t1;
+
+
--echo End of 5.0 tests
diff --git a/mysql-test/t/type_bit.test b/mysql-test/t/type_bit.test
index 998f8f18fbe..d46ba667665 100644
--- a/mysql-test/t/type_bit.test
+++ b/mysql-test/t/type_bit.test
@@ -252,5 +252,13 @@ select hex(b + 0), bin(b + 0), oct(b + 0), hex(n), bin(n), oct(n) from bug15583;
select conv(b, 10, 2), conv(b + 0, 10, 2) from bug15583;
drop table bug15583;
+#
+# Bug #22271: data casting may affect data stored in the next column(s?)
+#
+
+create table t1(a bit(1), b smallint unsigned);
+insert into t1 (b, a) values ('2', '1');
+select hex(a), b from t1;
+drop table t1;
--echo End of 5.0 tests
diff --git a/mysql-test/t/type_float.test b/mysql-test/t/type_float.test
index 5bfd744e4a8..965826629bd 100644
--- a/mysql-test/t/type_float.test
+++ b/mysql-test/t/type_float.test
@@ -178,7 +178,16 @@ show warnings;
desc t3;
drop table t1,t2,t3;
-# End of 4.1 tests
+#
+# Bug #22129: A small double precision number becomes zero
+#
+# check if underflows are detected correctly
+select 1e-308, 1.00000001e-300, 100000000e-300;
+
+# check if overflows are detected correctly
+select 10e307;
+
+--echo End of 4.1 tests
#
# bug #12694 (float(m,d) specifications)
diff --git a/mysql-test/t/view.test b/mysql-test/t/view.test
index 7d1ddccba83..0eadb33c3e1 100644
--- a/mysql-test/t/view.test
+++ b/mysql-test/t/view.test
@@ -347,13 +347,13 @@ create view v3 (x,y,z) as select b, a, b from t1;
create view v4 (x,y,z) as select c+1, b, a from t1;
create algorithm=temptable view v5 (x,y,z) as select c, b, a from t1;
# try insert to VIEW with fields duplicate
--- error 1288
+-- error ER_NON_INSERTABLE_TABLE
insert into v3 values (-60,4,30);
# try insert to VIEW with expression in SELECT list
--- error 1288
+-- error ER_NON_INSERTABLE_TABLE
insert into v4 values (-60,4,30);
# try insert to VIEW using temporary table algorithm
--- error 1288
+-- error ER_NON_INSERTABLE_TABLE
insert into v5 values (-60,4,30);
insert into v1 values (-60,4,30);
insert into v1 (z,y,x) values (50,6,-100);
@@ -375,13 +375,13 @@ create view v3 (x,y,z) as select b, a, b from t1;
create view v4 (x,y,z) as select c+1, b, a from t1;
create algorithm=temptable view v5 (x,y,z) as select c, b, a from t1;
# try insert to VIEW with fields duplicate
--- error 1288
+-- error ER_NON_INSERTABLE_TABLE
insert into v3 select c, b, a from t2;
# try insert to VIEW with expression in SELECT list
--- error 1288
+-- error ER_NON_INSERTABLE_TABLE
insert into v4 select c, b, a from t2;
# try insert to VIEW using temporary table algorithm
--- error 1288
+-- error ER_NON_INSERTABLE_TABLE
insert into v5 select c, b, a from t2;
insert into v1 select c, b, a from t2;
insert into v1 (z,y,x) select a+20,b+2,-100 from t2;
@@ -1249,14 +1249,14 @@ drop table t1;
#
create table t1 (s1 smallint);
create view v1 as select * from t1 where 20 < (select (s1) from t1);
--- error 1288
+-- error ER_NON_INSERTABLE_TABLE
insert into v1 values (30);
create view v2 as select * from t1;
create view v3 as select * from t1 where 20 < (select (s1) from v2);
--- error 1288
+-- error ER_NON_INSERTABLE_TABLE
insert into v3 values (30);
create view v4 as select * from v2 where 20 < (select (s1) from t1);
--- error 1288
+-- error ER_NON_INSERTABLE_TABLE
insert into v4 values (30);
drop view v4, v3, v2, v1;
drop table t1;
@@ -2443,7 +2443,7 @@ DROP TABLE t1, t2;
#
# Bug #16069: VIEW does return the same results as underlying SELECT
# with WHERE condition containing BETWEEN over dates
-
+# Dates as strings should be casted to date type
CREATE TABLE t1 (id int NOT NULL PRIMARY KEY,
td date DEFAULT NULL, KEY idx(td));
@@ -2830,7 +2830,7 @@ BEGIN
END |
delimiter ;|
---error ER_NON_UPDATABLE_TABLE
+--error ER_NON_INSERTABLE_TABLE
SELECT f2();
DROP FUNCTION f1;
@@ -2855,4 +2855,33 @@ EXPLAIN SELECT * FROM v1 t WHERE t.s1+1 < (SELECT MAX(t1.s1) FROM t1);
DROP VIEW v1;
DROP TABLE t1;
+
+#
+# Bug #5505: Wrong error message on INSERT into a view
+#
+create table t1 (s1 int);
+create view v1 as select s1 as a, s1 as b from t1;
+--error ER_NON_INSERTABLE_TABLE
+insert into v1 values (1,1);
+update v1 set a = 5;
+drop view v1;
+drop table t1;
+
+#
+# Bug #21646: view qith a subquery in ON expression
+#
+
+CREATE TABLE t1(pk int PRIMARY KEY);
+CREATE TABLE t2(pk int PRIMARY KEY, fk int, ver int, org int);
+
+CREATE ALGORITHM=MERGE VIEW v1 AS
+SELECT t1.*
+ FROM t1 JOIN t2
+ ON t2.fk = t1.pk AND
+ t2.ver = (SELECT MAX(t.ver) FROM t2 t WHERE t.org = t2.org);
+SHOW WARNINGS;
+SHOW CREATE VIEW v1;
+
+DROP VIEW v1;
+DROP TABLE t1, t2;
--echo End of 5.0 tests.
diff --git a/mysql-test/t/warnings.test b/mysql-test/t/warnings.test
index c20763f203f..a8b8e5f5103 100644
--- a/mysql-test/t/warnings.test
+++ b/mysql-test/t/warnings.test
@@ -147,4 +147,60 @@ select * from t1 limit 1, 0;
select * from t1 limit 0, 0;
drop table t1;
-# End of 4.1 tests
+--echo End of 4.1 tests
+
+#
+# Bug#20778: strange characters in warning message 1366 when called in SP
+#
+
+let $engine_type= innodb;
+
+CREATE TABLE t1( f1 CHAR(20) );
+CREATE TABLE t2( f1 CHAR(20), f2 CHAR(25) );
+CREATE TABLE t3( f1 CHAR(20), f2 CHAR(25), f3 DATE );
+
+INSERT INTO t1 VALUES ( 'a`' );
+INSERT INTO t2 VALUES ( 'a`', 'a`' );
+INSERT INTO t3 VALUES ( 'a`', 'a`', '1000-01-1' );
+
+DROP PROCEDURE IF EXISTS sp1;
+DROP PROCEDURE IF EXISTS sp2;
+DROP PROCEDURE IF EXISTS sp3;
+delimiter //;
+CREATE PROCEDURE sp1()
+BEGIN
+ DECLARE x NUMERIC ZEROFILL;
+ SELECT f1 INTO x FROM t1 LIMIT 1;
+END//
+CREATE PROCEDURE sp2()
+BEGIN
+ DECLARE x NUMERIC ZEROFILL;
+ SELECT f1 INTO x FROM t2 LIMIT 1;
+END//
+CREATE PROCEDURE sp3()
+BEGIN
+ DECLARE x NUMERIC ZEROFILL;
+ SELECT f1 INTO x FROM t3 LIMIT 1;
+END//
+delimiter ;//
+CALL sp1();
+CALL sp2();
+CALL sp3();
+
+DROP PROCEDURE IF EXISTS sp1;
+delimiter //;
+CREATE PROCEDURE sp1()
+BEGIN
+declare x numeric unsigned zerofill;
+SELECT f1 into x from t2 limit 1;
+END//
+delimiter ;//
+CALL sp1();
+DROP TABLE t1;
+DROP TABLE t2;
+DROP TABLE t3;
+DROP PROCEDURE sp1;
+DROP PROCEDURE sp2;
+DROP PROCEDURE sp3;
+
+--echo End of 5.0 tests
diff --git a/mysql-test/t/windows.test b/mysql-test/t/windows.test
index 79517df6517..d6bcfeb8cb3 100644
--- a/mysql-test/t/windows.test
+++ b/mysql-test/t/windows.test
@@ -18,42 +18,3 @@ create table nu (a int);
drop table nu;
# End of 4.1 tests
-
-#
-# Bug #20789: Merge Subtable Rename Causes Crash
-#
-CREATE TABLE `t1` (
- `TIM` datetime NOT NULL,
- `VAL` double default NULL
-) ENGINE=MyISAM DEFAULT CHARSET=latin1;
-CREATE TABLE `t2` (
- `TIM` datetime NOT NULL,
- `VAL` double default NULL
-) ENGINE=MyISAM DEFAULT CHARSET=latin1;
-CREATE TABLE `mt` (
- `TIM` datetime NOT NULL,
- `VAL` double default NULL
-) ENGINE=MRG_MyISAM DEFAULT CHARSET=latin1 INSERT_METHOD=LAST
-UNION=(`t1`,`t2`);
-
-# insert into the merge table and thus open it.
-INSERT INTO mt VALUES ('2006-01-01',0);
-
-# Alter one of the tables that are part of the merge table
-ALTER TABLE `t2` RENAME TO `t`;
-
-# Insert into the merge table that has just been altered
---error 1015
-INSERT INTO mt VALUES ('2006-01-01',0);
---error 1015
-select * from mt;
-
-FLUSH TABLES;
---error 1017
-select * from mt;
-
-# Alter one of the tables that are part of the merge table
-ALTER TABLE `t` RENAME TO `t2`;
-INSERT INTO mt VALUES ('2006-01-01',0);
-select * from mt;
-
diff --git a/mysql-test/t/xml.test b/mysql-test/t/xml.test
index d510a61f04d..3347573b4b7 100644
--- a/mysql-test/t/xml.test
+++ b/mysql-test/t/xml.test
@@ -360,3 +360,19 @@ select extractValue('<ns:element xmlns:ns="myns">a</ns:element>','/ns:element/@x
#
select extractValue('<foo><foo.bar>Data</foo.bar><something>Otherdata</something></foo>','/foo/foo.bar');
select extractValue('<foo><foo.bar>Data</foo.bar><something>Otherdata</something></foo>','/foo/something');
+
+#
+# Bug#20854 XML functions: wrong result in ExtractValue
+#
+--error 1105
+select extractValue('<zot><tim0><01>10:39:15</01><02>140</02></tim0></zot>','/zot/tim0/02');
+select extractValue('<zot><tim0><01>10:39:15</01><02>140</02></tim0></zot>','//*');
+# dot and dash are bad identtifier start character
+select extractValue('<.>test</.>','//*');
+select extractValue('<->test</->','//*');
+# semicolon is good identifier start character
+select extractValue('<:>test</:>','//*');
+# underscore is good identifier start character
+select extractValue('<_>test</_>','//*');
+# dot, dash, underscore and semicolon are good identifier middle characters
+select extractValue('<x.-_:>test</x.-_:>','//*');
diff --git a/mysql-test/valgrind.supp b/mysql-test/valgrind.supp
index 6dd11df5de6..e88df49a707 100644
--- a/mysql-test/valgrind.supp
+++ b/mysql-test/valgrind.supp
@@ -15,11 +15,12 @@
}
{
- pthread allocate_tls memory loss 2
+ pthread allocate_tls memory loss
Memcheck:Leak
fun:calloc
fun:_dl_allocate_tls
- fun:pthread_create@@GLIBC_2.1
+ fun:pthread_create*
+
}
{
@@ -183,6 +184,24 @@
}
{
+ libz longest_match 3
+ Memcheck:Cond
+ fun:longest_match
+ fun:deflate_slow
+ fun:deflate
+ fun:gzclose
+}
+
+{
+ libz longest_match 4
+ Memcheck:Cond
+ fun:longest_match
+ fun:deflate_slow
+ fun:deflate
+ fun:gzflush
+}
+
+{
libz longest_match3
Memcheck:Cond
fun:longest_match
diff --git a/mysys/base64.c b/mysys/base64.c
index fb51bdb3a60..363aa2cc739 100644
--- a/mysys/base64.c
+++ b/mysys/base64.c
@@ -125,44 +125,69 @@ pos(unsigned char c)
/*
Decode a base64 string
- Note: We require that dst is pre-allocated to correct size.
- See base64_needed_decoded_length().
-
- RETURN Number of bytes produced in dst or -1 in case of failure
+ SYNOPSIS
+ base64_decode()
+ src Pointer to base64-encoded string
+ len Length of string at 'src'
+ dst Pointer to location where decoded data will be stored
+ end_ptr Pointer to variable that will refer to the character
+ after the end of the encoded data that were decoded. Can
+ be NULL.
+
+ DESCRIPTION
+
+ The base64-encoded data in the range ['src','*end_ptr') will be
+ decoded and stored starting at 'dst'. The decoding will stop
+ after 'len' characters have been read from 'src', or when padding
+ occurs in the base64-encoded data. In either case: if 'end_ptr' is
+ non-null, '*end_ptr' will be set to point to the character after
+ the last read character, even in the presence of error.
+
+ NOTE
+ We require that 'dst' is pre-allocated to correct size.
+
+ SEE ALSO
+ base64_needed_decoded_length().
+
+ RETURN VALUE
+ Number of bytes written at 'dst' or -1 in case of failure
*/
int
-base64_decode(const char *src, size_t size, void *dst)
+base64_decode(const char *const src_base, size_t const len,
+ void *dst, const char **end_ptr)
{
char b[3];
size_t i= 0;
char *dst_base= (char *)dst;
+ char const *src= src_base;
char *d= dst_base;
size_t j;
- while (i < size)
+ while (i < len)
{
unsigned c= 0;
size_t mark= 0;
- SKIP_SPACE(src, i, size);
+ SKIP_SPACE(src, i, len);
c += pos(*src++);
c <<= 6;
i++;
- SKIP_SPACE(src, i, size);
+ SKIP_SPACE(src, i, len);
c += pos(*src++);
c <<= 6;
i++;
- SKIP_SPACE(src, i, size);
+ SKIP_SPACE(src, i, len);
- if (* src != '=')
+ if (*src != '=')
c += pos(*src++);
else
{
- i= size;
+ src += 2; /* There should be two bytes padding */
+ i= len;
mark= 2;
c <<= 6;
goto end;
@@ -170,13 +195,14 @@ base64_decode(const char *src, size_t size, void *dst)
c <<= 6;
i++;
- SKIP_SPACE(src, i, size);
+ SKIP_SPACE(src, i, len);
if (*src != '=')
c += pos(*src++);
else
{
- i= size;
+ src += 1; /* There should be one byte padding */
+ i= len;
mark= 1;
goto end;
}
@@ -191,11 +217,14 @@ base64_decode(const char *src, size_t size, void *dst)
*d++= b[j];
}
- if (i != size)
- {
- return -1;
- }
- return d - dst_base;
+ if (end_ptr != NULL)
+ *end_ptr= src;
+
+ /*
+ The variable 'i' is set to 'len' when padding has been read, so it
+ does not actually reflect the number of bytes read from 'src'.
+ */
+ return i != len ? -1 : d - dst_base;
}
diff --git a/mysys/mf_iocache2.c b/mysys/mf_iocache2.c
index f1ea21c2a47..895f03dc714 100644
--- a/mysys/mf_iocache2.c
+++ b/mysys/mf_iocache2.c
@@ -24,6 +24,54 @@
#include <stdarg.h>
#include <m_ctype.h>
+/*
+ Copy contents of an IO_CACHE to a file.
+
+ SYNOPSIS
+ my_b_copy_to_file()
+ cache IO_CACHE to copy from
+ file File to copy to
+
+ DESCRIPTION
+ Copy the contents of the cache to the file. The cache will be
+ re-inited to a read cache and will read from the beginning of the
+ cache.
+
+ If a failure to write fully occurs, the cache is only copied
+ partially.
+
+ TODO
+ Make this function solid by handling partial reads from the cache
+ in a correct manner: it should be atomic.
+
+ RETURN VALUE
+ 0 All OK
+ 1 An error occured
+*/
+int
+my_b_copy_to_file(IO_CACHE *cache, FILE *file)
+{
+ byte buf[IO_SIZE];
+ uint bytes_in_cache;
+ DBUG_ENTER("my_b_copy_to_file");
+
+ /* Reinit the cache to read from the beginning of the cache */
+ if (reinit_io_cache(cache, READ_CACHE, 0L, FALSE, FALSE))
+ DBUG_RETURN(1);
+ bytes_in_cache= my_b_bytes_in_cache(cache);
+ while (bytes_in_cache > 0) {
+ uint const read_bytes= min(bytes_in_cache, sizeof(buf));
+ DBUG_PRINT("debug", ("Remaining %u bytes - Reading %u bytes",
+ bytes_in_cache, read_bytes));
+ if (my_b_read(cache, buf, read_bytes))
+ DBUG_RETURN(1);
+ if (my_fwrite(file, buf, read_bytes, MYF(MY_WME | MY_NABP)) == (uint) -1)
+ DBUG_RETURN(1);
+ bytes_in_cache -= read_bytes;
+ }
+ DBUG_RETURN(0);
+}
+
my_off_t my_b_append_tell(IO_CACHE* info)
{
/*
diff --git a/mysys/my_chsize.c b/mysys/my_chsize.c
index 9760de29a08..fe0d0ffa607 100644
--- a/mysys/my_chsize.c
+++ b/mysys/my_chsize.c
@@ -46,7 +46,9 @@ int my_chsize(File fd, my_off_t newlength, int filler, myf MyFlags)
DBUG_PRINT("my",("fd: %d length: %lu MyFlags: %d",fd,(ulong) newlength,
MyFlags));
- oldsize = my_seek(fd, 0L, MY_SEEK_END, MYF(MY_WME+MY_FAE));
+ if ((oldsize = my_seek(fd, 0L, MY_SEEK_END, MYF(MY_WME+MY_FAE))) == newlength)
+ DBUG_RETURN(0);
+
DBUG_PRINT("info",("old_size: %ld", (ulong) oldsize));
if (oldsize > newlength)
diff --git a/mysys/my_libwrap.c b/mysys/my_libwrap.c
index be8adbab0a1..80fca127716 100644
--- a/mysys/my_libwrap.c
+++ b/mysys/my_libwrap.c
@@ -31,12 +31,12 @@ void my_fromhost(struct request_info *req)
int my_hosts_access(struct request_info *req)
{
- hosts_access(req);
+ return hosts_access(req);
}
char *my_eval_client(struct request_info *req)
{
- eval_client(req);
+ return eval_client(req);
}
#endif /* HAVE_LIBWRAP */
diff --git a/mysys/queues.c b/mysys/queues.c
index 8e572a0f195..3900ecad3f2 100644
--- a/mysys/queues.c
+++ b/mysys/queues.c
@@ -208,28 +208,22 @@ void delete_queue(QUEUE *queue)
void queue_insert(register QUEUE *queue, byte *element)
{
- reg2 uint idx,next;
+ reg2 uint idx, next;
int cmp;
-
-#ifndef DBUG_OFF
- if (queue->elements < queue->max_elements)
-#endif
+ DBUG_ASSERT(queue->elements < queue->max_elements);
+ queue->root[0]= element;
+ idx= ++queue->elements;
+ /* max_at_top swaps the comparison if we want to order by desc */
+ while ((cmp= queue->compare(queue->first_cmp_arg,
+ element + queue->offset_to_key,
+ queue->root[(next= idx >> 1)] +
+ queue->offset_to_key)) &&
+ (cmp ^ queue->max_at_top) < 0)
{
- queue->root[0]=element;
- idx= ++queue->elements;
-
- /* max_at_top swaps the comparison if we want to order by desc */
- while ((cmp=queue->compare(queue->first_cmp_arg,
- element+queue->offset_to_key,
- queue->root[(next=idx >> 1)] +
- queue->offset_to_key)) &&
- (cmp ^ queue->max_at_top) < 0)
- {
- queue->root[idx]=queue->root[next];
- idx=next;
- }
- queue->root[idx]=element;
+ queue->root[idx]= queue->root[next];
+ idx= next;
}
+ queue->root[idx]= element;
}
/*
@@ -262,16 +256,12 @@ int queue_insert_safe(register QUEUE *queue, byte *element)
byte *queue_remove(register QUEUE *queue, uint idx)
{
-#ifndef DBUG_OFF
- if (idx >= queue->max_elements)
- return 0;
-#endif
- {
- byte *element=queue->root[++idx]; /* Intern index starts from 1 */
- queue->root[idx]=queue->root[queue->elements--];
- _downheap(queue,idx);
- return element;
- }
+ byte *element;
+ DBUG_ASSERT(idx < queue->max_elements);
+ element= queue->root[++idx]; /* Intern index starts from 1 */
+ queue->root[idx]= queue->root[queue->elements--];
+ _downheap(queue, idx);
+ return element;
}
/* Fix when element on top has been replaced */
diff --git a/netware/BUILD/mwccnlm b/netware/BUILD/mwccnlm
index e6840e781f8..030d87288f2 100755
--- a/netware/BUILD/mwccnlm
+++ b/netware/BUILD/mwccnlm
@@ -3,9 +3,12 @@
# stop on errors
set -e
-# mwccnlm is having a hard time understanding "-I./../include"
-# convert it to "-I../include"
-args=" "`echo $* | sed -e 's/-I.\/../-I../g'`
+# mwccnlm is having a hard time understanding:
+# * "-I./../include", convert it to "-I../include"
+# * "-I.../..", convert it to "-I../../"
+args=" "`echo $* | sed \
+-e 's/-I.\/../-I../g' \
+-e 's/\(-I[.\/]*.\) /\1\/ /g'`
# NOTE: Option 'pipefail' is not standard sh
set -o pipefail
diff --git a/netware/BUILD/mwenv b/netware/BUILD/mwenv
index b88b6347668..d8d53293b2c 100755
--- a/netware/BUILD/mwenv
+++ b/netware/BUILD/mwenv
@@ -1,19 +1,39 @@
#! /bin/sh
-# F:/mydev, /home/kp/mydev, and 4.0.21 must be correct before compiling
-# This values are normally changed by the nwbootstrap script
+if test ! -r ./sql/mysqld.cc
+then
+ echo "you must start from the top source directory"
+ exit 1
+fi
-# the default is "F:/mydev"
-export MYDEV=WINE_BUILD_DIR
+# The base path(in wineformat) where compilers, includes and
+# libraries are installed
+if test -z $MYDEV
+then
+ # the default is "F:/mydev"
+ export MYDEV="F:/mydev"
+fi
+echo "MYDEV: $MYDEV"
-export MWCNWx86Includes="$MYDEV/libc/include;$MYDEV/fs64/headers;$MYDEV/zlib-1.2.3;$MYDEV/mysql-VERSION/include;$MYDEV"
-export MWNWx86Libraries="$MYDEV/libc/imports;$MYDEV/mw/lib;$MYDEV/fs64/imports;$MYDEV/zlib-1.2.3;$MYDEV/openssl;$MYDEV/mysql-VERSION/netware/BUILD"
+# Get current dir
+BUILD_DIR=`pwd`
+echo "BUILD_DIR: $BUILD_DIR"
+
+# Get current dir in wine format
+base=`echo $MYDEV |sed 's/\/.*//'`
+base_unix_part=`winepath -- -u $base/`
+WINE_BUILD_DIR=`echo "$BUILD_DIR" | sed 's_'$base_unix_part'/__'`
+WINE_BUILD_DIR="$base/$WINE_BUILD_DIR"
+echo "WINE_BUILD_DIR: $WINE_BUILD_DIR"
+
+export MWCNWx86Includes="$MYDEV/libc/include;$MYDEV/fs64/headers;$MYDEV/zlib-1.2.3;$WINE_BUILD_DIR/include;$MYDEV"
+export MWNWx86Libraries="$MYDEV/libc/imports;$MYDEV/mw/lib;$MYDEV/fs64/imports;$MYDEV/zlib-1.2.3;$MYDEV/openssl;$WINE_BUILD_DIR/netware/BUILD"
export MWNWx86LibraryFiles="libcpre.o;libc.imp;netware.imp;mwcrtl.lib;mwcpp.lib;libz.a;neb.imp;zPublics.imp;knetware.imp"
export WINEPATH="$MYDEV/mw/bin"
-# the default added path is "$HOME/mydev/mysql-x.x-x/netware/BUILD"
-export PATH="$PATH:BUILD_DIR/mysql-VERSION/netware/BUILD"
+# the default added path is "$BUILD_DIR/netware/BUILD"
+export PATH="$PATH:$BUILD_DIR/netware/BUILD"
export AR='mwldnlm'
export AR_FLAGS='-type library -o'
diff --git a/netware/Makefile.am b/netware/Makefile.am
index 5b40933994b..beb3fda35ee 100644
--- a/netware/Makefile.am
+++ b/netware/Makefile.am
@@ -23,7 +23,8 @@ mysqld_safe_SOURCES= mysqld_safe.c my_manage.c
mysql_install_db_SOURCES= mysql_install_db.c my_manage.c
mysql_test_run_SOURCES= mysql_test_run.c my_manage.c
libmysql_SOURCES= libmysqlmain.c
-libmysql_LDADD = ../libmysql/.libs/libmysqlclient.a @openssl_libs@
+libmysql_LDADD = ../libmysql/.libs/libmysqlclient.a \
+ @openssl_libs@ @yassl_libs@
netware_build_files = client/mysql.def client/mysqladmin.def \
client/mysqlbinlog.def client/mysqlcheck.def \
@@ -49,8 +50,20 @@ link_sources:
@LN_CP_F@ $(srcdir)/$$org ../$$f; \
done
else
-EXTRA_DIST= comp_err.def init_db.sql install_test_db.ncf \
- libmysql.def libmysql.imp \
+
+BUILT_SOURCES = libmysql.imp
+DISTCLEANFILES = $(BUILT_SOURCES)
+
+# Create the libmysql.imp from libmysql/libmysql.def
+libmysql.imp: $(top_srcdir)/libmysql/libmysql.def
+ awk 'BEGIN{x=0;} \
+ END{printf("\n");} \
+ x==1 {printf(" %s",$$1); x++; next} \
+ x>1 {printf(",\n %s", $$1); next} \
+ /EXPORTS/{x=1}' $(top_srcdir)/libmysql/libmysql.def > libmysql.imp
+
+EXTRA_DIST= $(BUILT_SOURCES) comp_err.def init_db.sql install_test_db.ncf \
+ libmysql.def \
libmysqlmain.c my_manage.c my_manage.h \
my_print_defaults.def myisam_ftdump.def myisamchk.def \
myisamlog.def myisampack.def mysql.def mysql.xdc \
diff --git a/netware/libmysql.imp b/netware/libmysql.imp
deleted file mode 100644
index 977fb1b0b1f..00000000000
--- a/netware/libmysql.imp
+++ /dev/null
@@ -1,85 +0,0 @@
-myodbc_remove_escape,
-mysql_add_slave,
-mysql_affected_rows,
-mysql_change_user,
-mysql_character_set_name,
-mysql_close,
-mysql_data_seek,
-mysql_debug,
-mysql_disable_reads_from_master,
-mysql_disable_rpl_parse,
-mysql_dump_debug_info,
-mysql_enable_reads_from_master,
-mysql_enable_rpl_parse,
-mysql_eof,
-mysql_errno,
-mysql_error,
-mysql_escape_string,
-mysql_fetch_field,
-mysql_fetch_field_direct,
-mysql_fetch_fields,
-mysql_fetch_lengths,
-mysql_fetch_row,
-mysql_field_count,
-mysql_field_seek,
-mysql_field_tell,
-mysql_free_result,
-mysql_get_client_info,
-mysql_get_host_info,
-mysql_get_proto_info,
-mysql_get_server_info,
-mysql_info,
-mysql_init,
-mysql_insert_id,
-mysql_kill,
-mysql_list_dbs,
-mysql_list_fields,
-mysql_list_processes,
-mysql_list_tables,
-mysql_manager_close,
-mysql_manager_command,
-mysql_manager_connect,
-mysql_manager_fetch_line,
-mysql_manager_init,
-mysql_master_query,
-mysql_master_send_query,
-mysql_num_fields,
-mysql_num_rows,
-mysql_odbc_escape_string,
-mysql_options,
-mysql_ping,
-mysql_query,
-mysql_read_query_result,
-mysql_reads_from_master_enabled,
-mysql_real_connect,
-mysql_real_escape_string,
-mysql_real_query,
-mysql_refresh,
-mysql_row_seek,
-mysql_row_tell,
-mysql_rpl_parse_enabled,
-mysql_rpl_probe,
-mysql_rpl_query_type,
-mysql_select_db,
-mysql_send_query,
-mysql_server_end,
-mysql_server_init,
-mysql_set_master,
-mysql_shutdown,
-mysql_slave_query,
-mysql_slave_send_query,
-mysql_ssl_set,
-mysql_stat,
-mysql_store_result,
-mysql_thread_end,
-mysql_thread_id,
-mysql_thread_init,
-mysql_thread_safe,
-mysql_use_result,
-net_safe_read,
-#simple_command,
-mysql_connect,
-mysql_create_db,
-mysql_drop_db,
-
-
diff --git a/plugin/fulltext/plugin_example.c b/plugin/fulltext/plugin_example.c
index 7da6672190c..f09462f2d1a 100644
--- a/plugin/fulltext/plugin_example.c
+++ b/plugin/fulltext/plugin_example.c
@@ -226,6 +226,7 @@ mysql_declare_plugin(ftexample)
"simple_parser", /* name */
"MySQL AB", /* author */
"Simple Full-Text Parser", /* description */
+ PLUGIN_LICENSE_GPL,
simple_parser_plugin_init, /* init function (when loaded) */
simple_parser_plugin_deinit,/* deinit function (when unloaded) */
0x0001, /* version */
diff --git a/scripts/mysqlhotcopy.sh b/scripts/mysqlhotcopy.sh
index bf53aa78e15..61cd59457d1 100644
--- a/scripts/mysqlhotcopy.sh
+++ b/scripts/mysqlhotcopy.sh
@@ -263,6 +263,7 @@ my $hc_locks = "";
my $hc_tables = "";
my $num_tables = 0;
my $num_files = 0;
+my $raid_dir_regex = '[A-Za-z0-9]{2}';
foreach my $rdb ( @db_desc ) {
my $db = $rdb->{src};
@@ -294,7 +295,7 @@ foreach my $rdb ( @db_desc ) {
my @raid_dir = ();
while ( defined( my $name = readdir DBDIR ) ) {
- if ( $name =~ /^\d\d$/ && -d "$db_dir/$name" ) {
+ if ( $name =~ /^$raid_dir_regex$/ && -d "$db_dir/$name" ) {
push @raid_dir, $name;
}
else {
@@ -602,7 +603,7 @@ sub copy_files {
# add recursive option for scp
$cp.= " -r" if $^O =~ /m^(solaris|linux|freebsd|darwin)$/ && $method =~ /^scp\b/;
- my @non_raid = map { "'$_'" } grep { ! m:/\d{2}/[^/]+$: } @$files;
+ my @non_raid = map { "'$_'" } grep { ! m:/$raid_dir_regex/[^/]+$: } @$files;
# add files to copy and the destination directory
safe_system( $cp, @non_raid, "'$target'" ) if (@non_raid);
@@ -810,7 +811,7 @@ sub get_raid_dirs {
my %dirs = ();
foreach my $f ( @$r_files ) {
- if ( $f =~ m:^(\d\d)/: ) {
+ if ( $f =~ m:^($raid_dir_regex)/: ) {
$dirs{$1} = 1;
}
}
diff --git a/server-tools/instance-manager/listener.cc b/server-tools/instance-manager/listener.cc
index da9338e28c5..197c315dee8 100644
--- a/server-tools/instance-manager/listener.cc
+++ b/server-tools/instance-manager/listener.cc
@@ -38,6 +38,27 @@
#include "thread_registry.h"
+static void set_non_blocking(int socket)
+{
+#ifndef __WIN__
+ int flags= fcntl(socket, F_GETFL, 0);
+ fcntl(socket, F_SETFL, flags | O_NONBLOCK);
+#else
+ u_long arg= 1;
+ ioctlsocket(socket, FIONBIO, &arg);
+#endif
+}
+
+
+static void set_no_inherit(int socket)
+{
+#ifndef __WIN__
+ int flags= fcntl(socket, F_GETFD, 0);
+ fcntl(socket, F_SETFD, flags | FD_CLOEXEC);
+#endif
+}
+
+
/*
Listener_thread - incapsulates listening functionality
*/
@@ -158,6 +179,8 @@ void Listener_thread::run()
/* accept may return -1 (failure or spurious wakeup) */
if (client_fd >= 0) // connection established
{
+ set_no_inherit(client_fd);
+
Vio *vio= vio_new(client_fd, socket_index == 0 ?
VIO_TYPE_SOCKET : VIO_TYPE_TCPIP,
socket_index == 0 ? 1 : 0);
@@ -199,25 +222,6 @@ err:
return;
}
-void set_non_blocking(int socket)
-{
-#ifndef __WIN__
- int flags= fcntl(socket, F_GETFL, 0);
- fcntl(socket, F_SETFL, flags | O_NONBLOCK);
-#else
- u_long arg= 1;
- ioctlsocket(socket, FIONBIO, &arg);
-#endif
-}
-
-void set_no_inherit(int socket)
-{
-#ifndef __WIN__
- int flags= fcntl(socket, F_GETFD, 0);
- fcntl(socket, F_SETFD, flags | FD_CLOEXEC);
-#endif
-}
-
int Listener_thread::create_tcp_socket()
{
/* value to be set by setsockopt */
diff --git a/sql-common/client.c b/sql-common/client.c
index 6722597531d..79a5be938b2 100644
--- a/sql-common/client.c
+++ b/sql-common/client.c
@@ -1753,7 +1753,7 @@ CLI_MYSQL_REAL_CONNECT(MYSQL *mysql,const char *host, const char *user,
const char *passwd, const char *db,
uint port, const char *unix_socket,ulong client_flag)
{
- char buff[NAME_BYTE_LEN+USERNAME_BYTE_LENGTH+100];
+ char buff[NAME_LEN+USERNAME_LENGTH+100];
char *end,*host_info;
my_socket sock;
in_addr_t ip_addr;
@@ -2212,7 +2212,7 @@ CLI_MYSQL_REAL_CONNECT(MYSQL *mysql,const char *host, const char *user,
mysql->server_status, client_flag));
/* This needs to be changed as it's not useful with big packets */
if (user && user[0])
- strmake(end,user,USERNAME_BYTE_LENGTH); /* Max user name */
+ strmake(end,user,USERNAME_LENGTH); /* Max user name */
else
read_user_name((char*) end);
@@ -2242,7 +2242,7 @@ CLI_MYSQL_REAL_CONNECT(MYSQL *mysql,const char *host, const char *user,
/* Add database if needed */
if (db && (mysql->server_capabilities & CLIENT_CONNECT_WITH_DB))
{
- end= strmake(end, db, NAME_BYTE_LEN) + 1;
+ end= strmake(end, db, NAME_LEN) + 1;
mysql->db= my_strdup(db,MYF(MY_WME));
db= 0;
}
diff --git a/sql/Makefile.am b/sql/Makefile.am
index 502d2881eb0..38a99aaef88 100644
--- a/sql/Makefile.am
+++ b/sql/Makefile.am
@@ -27,7 +27,7 @@ INCLUDES = @ZLIB_INCLUDES@ \
WRAPLIBS= @WRAPLIBS@
SUBDIRS = share
libexec_PROGRAMS = mysqld
-noinst_PROGRAMS = gen_lex_hash
+EXTRA_PROGRAMS = gen_lex_hash
bin_PROGRAMS = mysql_tzinfo_to_sql
gen_lex_hash_LDFLAGS = @NOINST_LDFLAGS@
LDADD = $(top_builddir)/vio/libvio.a \
@@ -157,7 +157,11 @@ sql_yacc.o: sql_yacc.cc sql_yacc.h $(HEADERS)
@echo "If it fails, re-run configure with --with-low-memory"
$(CXXCOMPILE) $(LM_CFLAGS) -c $<
-lex_hash.h: gen_lex_hash$(EXEEXT)
+# This generates lex_hash.h
+# NOTE Built sources should depend on their sources not the tool
+# this avoid the rebuild of the built files in a source dist
+lex_hash.h: gen_lex_hash.cc lex.h
+ $(MAKE) $(AM_MAKEFLAGS) gen_lex_hash$(EXEEXT)
./gen_lex_hash$(EXEEXT) > $@
# the following three should eventually be moved out of this directory
diff --git a/sql/field.cc b/sql/field.cc
index 2e478ead8b9..09e919d872a 100644
--- a/sql/field.cc
+++ b/sql/field.cc
@@ -2365,11 +2365,16 @@ int Field_new_decimal::store(const char *from, uint length,
from, length, charset, &decimal_value)) &&
table->in_use->abort_on_warning)
{
+ /* Because "from" is not NUL-terminated and we use %s in the ER() */
+ String from_as_str;
+ from_as_str.copy(from, length, &my_charset_bin);
+
push_warning_printf(table->in_use, MYSQL_ERROR::WARN_LEVEL_ERROR,
ER_TRUNCATED_WRONG_VALUE_FOR_FIELD,
ER(ER_TRUNCATED_WRONG_VALUE_FOR_FIELD),
- "decimal", from, field_name,
+ "decimal", from_as_str.c_ptr(), field_name,
(ulong) table->in_use->row_count);
+
DBUG_RETURN(err);
}
@@ -2382,13 +2387,20 @@ int Field_new_decimal::store(const char *from, uint length,
set_value_on_overflow(&decimal_value, decimal_value.sign());
break;
case E_DEC_BAD_NUM:
+ {
+ /* Because "from" is not NUL-terminated and we use %s in the ER() */
+ String from_as_str;
+ from_as_str.copy(from, length, &my_charset_bin);
+
push_warning_printf(table->in_use, MYSQL_ERROR::WARN_LEVEL_WARN,
ER_TRUNCATED_WRONG_VALUE_FOR_FIELD,
ER(ER_TRUNCATED_WRONG_VALUE_FOR_FIELD),
- "decimal", from, field_name,
+ "decimal", from_as_str.c_ptr(), field_name,
(ulong) table->in_use->row_count);
my_decimal_set_zero(&decimal_value);
+
break;
+ }
}
#ifndef DBUG_OFF
@@ -2553,28 +2565,26 @@ int Field_tiny::store(const char *from,uint len,CHARSET_INFO *cs)
ASSERT_COLUMN_MARKED_FOR_WRITE;
int not_used; // We can ignore result from str2int
char *end;
- long tmp= my_strntol(cs, from, len, 10, &end, &not_used);
- int error= 0;
+ int error;
if (unsigned_flag)
{
- if (tmp < 0)
- {
- tmp=0; /* purecov: inspected */
- set_warning(MYSQL_ERROR::WARN_LEVEL_WARN, ER_WARN_DATA_OUT_OF_RANGE, 1);
- error= 1;
- }
- else if (tmp > 255)
+ ulonglong tmp= cs->cset->strntoull10rnd(cs, from, len, 1, &end, &error);
+ if (error == MY_ERRNO_ERANGE || tmp > 255)
{
- tmp= 255;
+ set_if_smaller(tmp, 255);
set_warning(MYSQL_ERROR::WARN_LEVEL_WARN, ER_WARN_DATA_OUT_OF_RANGE, 1);
error= 1;
}
else if (table->in_use->count_cuted_fields && check_int(from,len,end,cs))
error= 1;
+ else
+ error= 0;
+ ptr[0]= (char) tmp;
}
else
{
+ longlong tmp= cs->cset->strntoull10rnd(cs, from, len, 0, &end, &error);
if (tmp < -128)
{
tmp= -128;
@@ -2589,8 +2599,10 @@ int Field_tiny::store(const char *from,uint len,CHARSET_INFO *cs)
}
else if (table->in_use->count_cuted_fields && check_int(from,len,end,cs))
error= 1;
+ else
+ error= 0;
+ ptr[0]= (char) tmp;
}
- ptr[0]= (char) tmp;
return error;
}
@@ -2763,28 +2775,33 @@ int Field_short::store(const char *from,uint len,CHARSET_INFO *cs)
ASSERT_COLUMN_MARKED_FOR_WRITE;
int not_used; // We can ignore result from str2int
char *end;
- long tmp= my_strntol(cs, from, len, 10, &end, &not_used);
- int error= 0;
+ int error;
if (unsigned_flag)
{
- if (tmp < 0)
- {
- tmp=0;
- set_warning(MYSQL_ERROR::WARN_LEVEL_WARN, ER_WARN_DATA_OUT_OF_RANGE, 1);
- error= 1;
- }
- else if (tmp > UINT_MAX16)
+ ulonglong tmp= cs->cset->strntoull10rnd(cs, from, len, 1, &end, &error);
+ if (error == MY_ERRNO_ERANGE || tmp > UINT_MAX16)
{
- tmp=UINT_MAX16;
+ set_if_smaller(tmp, UINT_MAX16);
set_warning(MYSQL_ERROR::WARN_LEVEL_WARN, ER_WARN_DATA_OUT_OF_RANGE, 1);
error= 1;
}
else if (table->in_use->count_cuted_fields && check_int(from,len,end,cs))
error= 1;
+ else
+ error= 0;
+#ifdef WORDS_BIGENDIAN
+ if (table->s->db_low_byte_first)
+ {
+ int2store(ptr,tmp);
+ }
+ else
+#endif
+ shortstore(ptr,(short) tmp);
}
else
{
+ longlong tmp= cs->cset->strntoull10rnd(cs, from, len, 0, &end, &error);
if (tmp < INT_MIN16)
{
tmp= INT_MIN16;
@@ -2799,15 +2816,17 @@ int Field_short::store(const char *from,uint len,CHARSET_INFO *cs)
}
else if (table->in_use->count_cuted_fields && check_int(from,len,end,cs))
error= 1;
- }
+ else
+ error= 0;
#ifdef WORDS_BIGENDIAN
- if (table->s->db_low_byte_first)
- {
- int2store(ptr,tmp);
- }
- else
+ if (table->s->db_low_byte_first)
+ {
+ int2store(ptr,tmp);
+ }
+ else
#endif
- shortstore(ptr,(short) tmp);
+ shortstore(ptr,(short) tmp);
+ }
return error;
}
@@ -3043,28 +3062,26 @@ int Field_medium::store(const char *from,uint len,CHARSET_INFO *cs)
ASSERT_COLUMN_MARKED_FOR_WRITE;
int not_used; // We can ignore result from str2int
char *end;
- long tmp= my_strntol(cs, from, len, 10, &end, &not_used);
- int error= 0;
+ int error;
if (unsigned_flag)
{
- if (tmp < 0)
- {
- tmp=0;
- set_warning(MYSQL_ERROR::WARN_LEVEL_WARN, ER_WARN_DATA_OUT_OF_RANGE, 1);
- error= 1;
- }
- else if (tmp >= (long) (1L << 24))
+ ulonglong tmp= cs->cset->strntoull10rnd(cs, from, len, 1, &end, &error);
+ if (error == MY_ERRNO_ERANGE || tmp > UINT_MAX24)
{
- tmp=(long) (1L << 24)-1L;
+ set_if_smaller(tmp, UINT_MAX24);
set_warning(MYSQL_ERROR::WARN_LEVEL_WARN, ER_WARN_DATA_OUT_OF_RANGE, 1);
error= 1;
}
else if (table->in_use->count_cuted_fields && check_int(from,len,end,cs))
error= 1;
+ else
+ error= 0;
+ int3store(ptr,tmp);
}
else
{
+ longlong tmp= cs->cset->strntoull10rnd(cs, from, len, 0, &end, &error);
if (tmp < INT_MIN24)
{
tmp= INT_MIN24;
@@ -3079,9 +3096,10 @@ int Field_medium::store(const char *from,uint len,CHARSET_INFO *cs)
}
else if (table->in_use->count_cuted_fields && check_int(from,len,end,cs))
error= 1;
+ else
+ error= 0;
+ int3store(ptr,tmp);
}
-
- int3store(ptr,tmp);
return error;
}
@@ -3290,58 +3308,43 @@ int Field_long::store(const char *from,uint len,CHARSET_INFO *cs)
int error;
char *end;
- tmp_scan= cs->cset->scan(cs, from, from+len, MY_SEQ_SPACES);
- len-= tmp_scan;
- from+= tmp_scan;
-
- end= (char*) from+len;
- tmp= cs->cset->strtoll10(cs, from, &end, &error);
-
- if (error != MY_ERRNO_EDOM)
+ if (unsigned_flag)
{
- if (unsigned_flag)
+ ulonglong tmp= cs->cset->strntoull10rnd(cs, from, len, 1, &end, &error);
+ if (error == MY_ERRNO_ERANGE || tmp > (ulonglong) UINT_MAX32)
{
- if (error < 0)
- {
- error= 1;
- tmp= 0;
- }
- else if ((ulonglong) tmp > (ulonglong) UINT_MAX32)
- {
- tmp= UINT_MAX32;
- error= 1;
- }
- else
- error= 0;
+ set_if_smaller(tmp, (ulonglong) UINT_MAX32);
+ set_warning(MYSQL_ERROR::WARN_LEVEL_WARN, ER_WARN_DATA_OUT_OF_RANGE, 1);
+ error= 1;
}
+ else if (table->in_use->count_cuted_fields && check_int(from,len,end,cs))
+ error= 1;
else
- {
- if (error < 0)
- {
- error= 0;
- if (tmp < INT_MIN32)
- {
- tmp= INT_MIN32;
- error= 1;
- }
- }
- else if (tmp > INT_MAX32)
- {
- tmp= INT_MAX32;
- error= 1;
- }
- }
+ error= 0;
+ store_tmp= (long) tmp;
}
- if (error)
+ else
{
- error= error != MY_ERRNO_EDOM ? 1 : 2;
- set_warning(MYSQL_ERROR::WARN_LEVEL_WARN, ER_WARN_DATA_OUT_OF_RANGE, 1);
+ longlong tmp= cs->cset->strntoull10rnd(cs, from, len, 0, &end, &error);
+ if (tmp < INT_MIN32)
+ {
+ tmp= INT_MIN32;
+ set_warning(MYSQL_ERROR::WARN_LEVEL_WARN, ER_WARN_DATA_OUT_OF_RANGE, 1);
+ error= 1;
+ }
+ else if (tmp > INT_MAX32)
+ {
+ tmp=INT_MAX32;
+ set_warning(MYSQL_ERROR::WARN_LEVEL_WARN, ER_WARN_DATA_OUT_OF_RANGE, 1);
+ error= 1;
+ }
+ else if (table->in_use->count_cuted_fields && check_int(from,len,end,cs))
+ error= 1;
+ else
+ error= 0;
+ store_tmp= (long) tmp;
}
- else if (from+len != end && table->in_use->count_cuted_fields &&
- check_int(from,len,end,cs))
- error= 2;
- store_tmp= (long) tmp;
#ifdef WORDS_BIGENDIAN
if (table->s->db_low_byte_first)
{
@@ -3583,33 +3586,20 @@ void Field_long::sql_type(String &res) const
int Field_longlong::store(const char *from,uint len,CHARSET_INFO *cs)
{
ASSERT_COLUMN_MARKED_FOR_WRITE;
- longlong tmp;
int error= 0;
char *end;
+ ulonglong tmp;
- tmp= cs->cset->scan(cs, from, from+len, MY_SEQ_SPACES);
- len-= (uint)tmp;
- from+= tmp;
- if (unsigned_flag)
- {
- if (!len || test_if_minus(cs, from, from + len))
- {
- tmp=0; // Set negative to 0
- error= 1;
- }
- else
- tmp=(longlong) my_strntoull(cs,from,len,10,&end,&error);
- }
- else
- tmp=my_strntoll(cs,from,len,10,&end,&error);
- if (error)
+ tmp= cs->cset->strntoull10rnd(cs,from,len,unsigned_flag,&end,&error);
+ if (error == MY_ERRNO_ERANGE)
{
set_warning(MYSQL_ERROR::WARN_LEVEL_WARN, ER_WARN_DATA_OUT_OF_RANGE, 1);
error= 1;
}
- else if (from+len != end && table->in_use->count_cuted_fields &&
- check_int(from,len,end,cs))
- error= 2;
+ else if (table->in_use->count_cuted_fields && check_int(from,len,end,cs))
+ error= 1;
+ else
+ error= 0;
#ifdef WORDS_BIGENDIAN
if (table->s->db_low_byte_first)
{
@@ -8163,7 +8153,7 @@ int Field_bit::store(const char *from, uint length, CHARSET_INFO *cs)
(delta == -1 && (uchar) *from > ((1 << bit_len) - 1)) ||
(!bit_len && delta < 0))
{
- set_rec_bits(0xff, bit_ptr, bit_ofs, bit_len);
+ set_rec_bits((1 << bit_len) - 1, bit_ptr, bit_ofs, bit_len);
memset(ptr, 0xff, bytes_in_rec);
if (table->in_use->really_abort_on_warning())
set_warning(MYSQL_ERROR::WARN_LEVEL_ERROR, ER_DATA_TOO_LONG, 1);
@@ -9160,7 +9150,7 @@ create_field::create_field(Field *old_field,Field *orig_field)
case 3: sql_type= FIELD_TYPE_MEDIUM_BLOB; break;
default: sql_type= FIELD_TYPE_LONG_BLOB; break;
}
- length=(length+charset->mbmaxlen-1) / charset->mbmaxlen;
+ length/= charset->mbmaxlen;
key_length/= charset->mbmaxlen;
break;
case MYSQL_TYPE_STRING:
diff --git a/sql/field.h b/sql/field.h
index 8a6bda500d3..9b81931d416 100644
--- a/sql/field.h
+++ b/sql/field.h
@@ -1522,6 +1522,8 @@ public:
uint decimals, flags, pack_length, key_length;
Field::utype unireg_check;
TYPELIB *interval; // Which interval to use
+ TYPELIB *save_interval; // Temporary copy for the above
+ // Used only for UCS2 intervals
List<String> interval_list;
CHARSET_INFO *charset;
Field::geometry_type geom_type;
diff --git a/sql/field_conv.cc b/sql/field_conv.cc
index 20d1e372a2c..7bc6c432d1c 100644
--- a/sql/field_conv.cc
+++ b/sql/field_conv.cc
@@ -427,6 +427,21 @@ static void do_varstring2(Copy_field *copy)
length);
}
+
+static void do_varstring2_mb(Copy_field *copy)
+{
+ int well_formed_error;
+ CHARSET_INFO *cs= copy->from_field->charset();
+ uint char_length= (copy->to_length - HA_KEY_BLOB_LENGTH) / cs->mbmaxlen;
+ uint from_length= uint2korr(copy->from_ptr);
+ const char *from_beg= copy->from_ptr + HA_KEY_BLOB_LENGTH;
+ uint length= cs->cset->well_formed_len(cs, from_beg, from_beg + from_length,
+ char_length, &well_formed_error);
+ int2store(copy->to_ptr, length);
+ memcpy(copy->to_ptr+HA_KEY_BLOB_LENGTH, from_beg, length);
+}
+
+
/***************************************************************************
** The different functions that fills in a Copy_field class
***************************************************************************/
@@ -586,7 +601,8 @@ void (*Copy_field::get_copy_func(Field *to,Field *from))(Copy_field*)
return do_field_string;
if (to_length != from_length)
return (((Field_varstring*) to)->length_bytes == 1 ?
- do_varstring1 : do_varstring2);
+ do_varstring1 : (from->charset()->mbmaxlen == 1 ?
+ do_varstring2 : do_varstring2_mb));
}
else if (to_length < from_length)
return (from->charset()->mbmaxlen == 1 ?
diff --git a/sql/filesort.cc b/sql/filesort.cc
index eb2960a0458..01f3bb97557 100644
--- a/sql/filesort.cc
+++ b/sql/filesort.cc
@@ -1345,6 +1345,7 @@ sortlength(THD *thd, SORT_FIELD *sortorder, uint s_length,
switch ((sortorder->result_type=sortorder->item->result_type())) {
case STRING_RESULT:
sortorder->length=sortorder->item->max_length;
+ set_if_smaller(sortorder->length, thd->variables.max_sort_length);
if (use_strnxfrm((cs=sortorder->item->collation.collation)))
{
sortorder->length= cs->coll->strnxfrmlen(cs, sortorder->length);
diff --git a/sql/ha_ndbcluster.cc b/sql/ha_ndbcluster.cc
index ccfe8e717fb..13ea471511c 100644
--- a/sql/ha_ndbcluster.cc
+++ b/sql/ha_ndbcluster.cc
@@ -75,17 +75,25 @@ static const int max_transactions= 3; // should really be 2 but there is a trans
static uint ndbcluster_partition_flags();
static uint ndbcluster_alter_table_flags(uint flags);
static int ndbcluster_init(void *);
-static int ndbcluster_end(ha_panic_function flag);
-static bool ndbcluster_show_status(THD*,stat_print_fn *,enum ha_stat_type);
-static int ndbcluster_alter_tablespace(THD* thd, st_alter_tablespace *info);
-static int ndbcluster_fill_files_table(THD *thd, TABLE_LIST *tables, COND *cond);
+static int ndbcluster_end(handlerton *hton, ha_panic_function flag);
+static bool ndbcluster_show_status(handlerton *hton, THD*,
+ stat_print_fn *,
+ enum ha_stat_type);
+static int ndbcluster_alter_tablespace(handlerton *hton,
+ THD* thd,
+ st_alter_tablespace *info);
+static int ndbcluster_fill_files_table(handlerton *hton,
+ THD *thd,
+ TABLE_LIST *tables,
+ COND *cond);
handlerton *ndbcluster_hton;
-static handler *ndbcluster_create_handler(TABLE_SHARE *table,
+static handler *ndbcluster_create_handler(handlerton *hton,
+ TABLE_SHARE *table,
MEM_ROOT *mem_root)
{
- return new (mem_root) ha_ndbcluster(table);
+ return new (mem_root) ha_ndbcluster(hton, table);
}
static uint ndbcluster_partition_flags()
@@ -179,8 +187,8 @@ static long ndb_cluster_node_id= 0;
static const char * ndb_connected_host= 0;
static long ndb_connected_port= 0;
static long ndb_number_of_replicas= 0;
-long ndb_number_of_storage_nodes= 0;
-long ndb_number_of_ready_storage_nodes= 0;
+long ndb_number_of_data_nodes= 0;
+long ndb_number_of_ready_data_nodes= 0;
long ndb_connect_count= 0;
static int update_status_variables(Ndb_cluster_connection *c)
@@ -189,8 +197,8 @@ static int update_status_variables(Ndb_cluster_connection *c)
ndb_connected_port= c->get_connected_port();
ndb_connected_host= c->get_connected_host();
ndb_number_of_replicas= 0;
- ndb_number_of_storage_nodes= c->no_db_nodes();
- ndb_number_of_ready_storage_nodes= c->get_no_ready();
+ ndb_number_of_ready_data_nodes= c->get_no_ready();
+ ndb_number_of_data_nodes= c->no_db_nodes();
ndb_connect_count= c->get_connect_count();
return 0;
}
@@ -200,7 +208,7 @@ SHOW_VAR ndb_status_variables[]= {
{"config_from_host", (char*) &ndb_connected_host, SHOW_CHAR_PTR},
{"config_from_port", (char*) &ndb_connected_port, SHOW_LONG},
// {"number_of_replicas", (char*) &ndb_number_of_replicas, SHOW_LONG},
- {"number_of_storage_nodes",(char*) &ndb_number_of_storage_nodes, SHOW_LONG},
+ {"number_of_data_nodes",(char*) &ndb_number_of_data_nodes, SHOW_LONG},
{NullS, NullS, SHOW_LONG}
};
@@ -2395,6 +2403,30 @@ int ha_ndbcluster::ordered_index_scan(const key_range *start_key,
DBUG_RETURN(next_result(buf));
}
+static
+int
+guess_scan_flags(NdbOperation::LockMode lm,
+ const NDBTAB* tab, const MY_BITMAP* readset)
+{
+ int flags= 0;
+ flags|= (lm == NdbOperation::LM_Read) ? NdbScanOperation::SF_KeyInfo : 0;
+ if (tab->checkColumns(0, 0) & 2)
+ {
+ int ret = tab->checkColumns(readset->bitmap, no_bytes_in_map(readset));
+
+ if (ret & 2)
+ { // If disk columns...use disk scan
+ flags |= NdbScanOperation::SF_DiskScan;
+ }
+ else if ((ret & 4) == 0 && (lm == NdbOperation::LM_Exclusive))
+ {
+ // If no mem column is set and exclusive...guess disk scan
+ flags |= NdbScanOperation::SF_DiskScan;
+ }
+ }
+ return flags;
+}
+
/*
Start full table scan in NDB
*/
@@ -2412,11 +2444,9 @@ int ha_ndbcluster::full_table_scan(byte *buf)
NdbOperation::LockMode lm=
(NdbOperation::LockMode)get_ndb_lock_type(m_lock.type);
- bool need_pk = (lm == NdbOperation::LM_Read);
+ int flags= guess_scan_flags(lm, m_table, table->read_set);
if (!(op=trans->getNdbScanOperation(m_table)) ||
- op->readTuples(lm,
- (need_pk)?NdbScanOperation::SF_KeyInfo:0,
- parallelism))
+ op->readTuples(lm, flags, parallelism))
ERR_RETURN(trans->getNdbError());
m_active_cursor= op;
@@ -4208,7 +4238,7 @@ int ha_ndbcluster::start_stmt(THD *thd, thr_lock_type lock_type)
Commit a transaction started in NDB
*/
-static int ndbcluster_commit(THD *thd, bool all)
+static int ndbcluster_commit(handlerton *hton, THD *thd, bool all)
{
int res= 0;
Thd_ndb *thd_ndb= get_thd_ndb(thd);
@@ -4259,7 +4289,7 @@ static int ndbcluster_commit(THD *thd, bool all)
Rollback a transaction started in NDB
*/
-static int ndbcluster_rollback(THD *thd, bool all)
+static int ndbcluster_rollback(handlerton *hton, THD *thd, bool all)
{
int res= 0;
Thd_ndb *thd_ndb= get_thd_ndb(thd);
@@ -5559,8 +5589,8 @@ void ha_ndbcluster::get_auto_increment(ulonglong offset, ulonglong increment,
HA_HAS_OWN_BINLOGGING | \
HA_HAS_RECORDS
-ha_ndbcluster::ha_ndbcluster(TABLE_SHARE *table_arg):
- handler(ndbcluster_hton, table_arg),
+ha_ndbcluster::ha_ndbcluster(handlerton *hton, TABLE_SHARE *table_arg):
+ handler(hton, table_arg),
m_active_trans(NULL),
m_active_cursor(NULL),
m_table(NULL),
@@ -5823,7 +5853,7 @@ int ha_ndbcluster::check_ndb_connection(THD* thd)
}
-static int ndbcluster_close_connection(THD *thd)
+static int ndbcluster_close_connection(handlerton *hton, THD *thd)
{
Thd_ndb *thd_ndb= get_thd_ndb(thd);
DBUG_ENTER("ndbcluster_close_connection");
@@ -5840,8 +5870,10 @@ static int ndbcluster_close_connection(THD *thd)
Try to discover one table from NDB
*/
-int ndbcluster_discover(THD* thd, const char *db, const char *name,
- const void** frmblob, uint* frmlen)
+int ndbcluster_discover(handlerton *hton, THD* thd, const char *db,
+ const char *name,
+ const void** frmblob,
+ uint* frmlen)
{
int error= 0;
NdbError ndb_error;
@@ -5921,7 +5953,8 @@ err:
*/
-int ndbcluster_table_exists_in_engine(THD* thd, const char *db,
+int ndbcluster_table_exists_in_engine(handlerton *hton, THD* thd,
+ const char *db,
const char *name)
{
Ndb* ndb;
@@ -6021,7 +6054,7 @@ int ndbcluster_drop_database_impl(const char *path)
DBUG_RETURN(ret);
}
-static void ndbcluster_drop_database(char *path)
+static void ndbcluster_drop_database(handlerton *hton, char *path)
{
THD *thd= current_thd;
DBUG_ENTER("ndbcluster_drop_database");
@@ -6182,7 +6215,9 @@ int ndbcluster_find_all_files(THD *thd)
DBUG_RETURN(-(skipped + unhandled));
}
-int ndbcluster_find_files(THD *thd,const char *db,const char *path,
+int ndbcluster_find_files(handlerton *hton, THD *thd,
+ const char *db,
+ const char *path,
const char *wild, bool dir, List<char> *files)
{
DBUG_ENTER("ndbcluster_find_files");
@@ -6292,7 +6327,7 @@ int ndbcluster_find_files(THD *thd,const char *db,const char *path,
DBUG_PRINT("info", ("%s existed on disk", name));
// The .ndb file exists on disk, but it's not in list of tables in ndb
// Verify that handler agrees table is gone.
- if (ndbcluster_table_exists_in_engine(thd, db, file_name) == 0)
+ if (ndbcluster_table_exists_in_engine(hton, thd, db, file_name) == 0)
{
DBUG_PRINT("info", ("NDB says %s does not exists", file_name));
it.remove();
@@ -6546,7 +6581,7 @@ ndbcluster_init_error:
DBUG_RETURN(TRUE);
}
-static int ndbcluster_end(ha_panic_function type)
+static int ndbcluster_end(handlerton *hton, ha_panic_function type)
{
DBUG_ENTER("ndbcluster_end");
@@ -6630,7 +6665,7 @@ void ndbcluster_print_error(int error, const NdbOperation *error_op)
share.db.length= 0;
share.table_name.str= (char *) tab_name;
share.table_name.length= strlen(tab_name);
- ha_ndbcluster error_handler(&share);
+ ha_ndbcluster error_handler(ndbcluster_hton, &share);
error_handler.print_error(error, MYF(0));
DBUG_VOID_RETURN;
}
@@ -9710,7 +9745,7 @@ err:
Implements the SHOW NDB STATUS command.
*/
bool
-ndbcluster_show_status(THD* thd, stat_print_fn *stat_print,
+ndbcluster_show_status(handlerton *hton, THD* thd, stat_print_fn *stat_print,
enum ha_stat_type stat_type)
{
char buf[IO_SIZE];
@@ -9732,14 +9767,14 @@ ndbcluster_show_status(THD* thd, stat_print_fn *stat_print,
"cluster_node_id=%u, "
"connected_host=%s, "
"connected_port=%u, "
- "number_of_storage_nodes=%u, "
- "number_of_ready_storage_nodes=%u, "
+ "number_of_data_nodes=%u, "
+ "number_of_ready_data_nodes=%u, "
"connect_count=%u",
ndb_cluster_node_id,
ndb_connected_host,
ndb_connected_port,
- ndb_number_of_storage_nodes,
- ndb_number_of_ready_storage_nodes,
+ ndb_number_of_data_nodes,
+ ndb_number_of_ready_data_nodes,
ndb_connect_count);
if (stat_print(thd, ndbcluster_hton_name, ndbcluster_hton_name_length,
STRING_WITH_LEN("connection"), buf, buflen))
@@ -10174,7 +10209,7 @@ bool set_up_undofile(st_alter_tablespace *info,
return false;
}
-int ndbcluster_alter_tablespace(THD* thd, st_alter_tablespace *info)
+int ndbcluster_alter_tablespace(handlerton *hton, THD* thd, st_alter_tablespace *info)
{
DBUG_ENTER("ha_ndbcluster::alter_tablespace");
@@ -10435,7 +10470,9 @@ bool ha_ndbcluster::get_no_parts(const char *name, uint *no_parts)
DBUG_RETURN(TRUE);
}
-static int ndbcluster_fill_files_table(THD *thd, TABLE_LIST *tables,
+static int ndbcluster_fill_files_table(handlerton *hton,
+ THD *thd,
+ TABLE_LIST *tables,
COND *cond)
{
TABLE* table= tables->table;
@@ -10756,7 +10793,7 @@ SHOW_VAR ndb_status_variables_export[]= {
};
struct st_mysql_storage_engine ndbcluster_storage_engine=
-{ MYSQL_HANDLERTON_INTERFACE_VERSION, ndbcluster_hton };
+{ MYSQL_HANDLERTON_INTERFACE_VERSION };
mysql_declare_plugin(ndbcluster)
{
@@ -10765,6 +10802,7 @@ mysql_declare_plugin(ndbcluster)
ndbcluster_hton_name,
"MySQL AB",
"Clustered, fault-tolerant tables",
+ PLUGIN_LICENSE_GPL,
ndbcluster_init, /* Plugin Init */
NULL, /* Plugin Deinit */
0x0100 /* 1.0 */,
diff --git a/sql/ha_ndbcluster.h b/sql/ha_ndbcluster.h
index 5cd5bb2c716..19ff513f9b1 100644
--- a/sql/ha_ndbcluster.h
+++ b/sql/ha_ndbcluster.h
@@ -627,7 +627,7 @@ class Thd_ndb
class ha_ndbcluster: public handler
{
public:
- ha_ndbcluster(TABLE_SHARE *table);
+ ha_ndbcluster(handlerton *hton, TABLE_SHARE *table);
~ha_ndbcluster();
int ha_initialise();
diff --git a/sql/ha_ndbcluster_binlog.cc b/sql/ha_ndbcluster_binlog.cc
index 3fc84ad1b66..5f5c8bcb221 100644
--- a/sql/ha_ndbcluster_binlog.cc
+++ b/sql/ha_ndbcluster_binlog.cc
@@ -506,7 +506,7 @@ ndbcluster_binlog_index_purge_file(THD *thd, const char *file)
}
static void
-ndbcluster_binlog_log_query(THD *thd, enum_binlog_command binlog_command,
+ndbcluster_binlog_log_query(handlerton *hton, THD *thd, enum_binlog_command binlog_command,
const char *query, uint query_length,
const char *db, const char *table_name)
{
@@ -637,7 +637,9 @@ static void ndbcluster_reset_slave(THD *thd)
/*
Initialize the binlog part of the ndb handlerton
*/
-static int ndbcluster_binlog_func(THD *thd, enum_binlog_func fn, void *arg)
+static int ndbcluster_binlog_func(handlerton *hton, THD *thd,
+ enum_binlog_func fn,
+ void *arg)
{
switch(fn)
{
diff --git a/sql/ha_ndbcluster_binlog.h b/sql/ha_ndbcluster_binlog.h
index 822ebf3e358..233d1a58aaa 100644
--- a/sql/ha_ndbcluster_binlog.h
+++ b/sql/ha_ndbcluster_binlog.h
@@ -31,6 +31,8 @@ extern ulong ndb_extra_logging;
#define NDB_INVALID_SCHEMA_OBJECT 241
+extern handlerton *ndbcluster_hton;
+
/*
The numbers below must not change as they
are passed between mysql servers, and if changed
@@ -103,7 +105,6 @@ extern pthread_mutex_t injector_mutex;
extern pthread_cond_t injector_cond;
extern unsigned char g_node_id_map[max_ndb_nodes];
-extern handlerton *ndbcluster_hton;
extern pthread_t ndb_util_thread;
extern pthread_mutex_t LOCK_ndb_util_thread;
extern pthread_cond_t COND_ndb_util_thread;
diff --git a/sql/ha_partition.cc b/sql/ha_partition.cc
index 1e75dd08f38..713be1b7b5d 100644
--- a/sql/ha_partition.cc
+++ b/sql/ha_partition.cc
@@ -69,16 +69,17 @@ static PARTITION_SHARE *get_share(const char *table_name, TABLE * table);
MODULE create/delete handler object
****************************************************************************/
-static handler *partition_create_handler(TABLE_SHARE *share,
+static handler *partition_create_handler(handlerton *hton,
+ TABLE_SHARE *share,
MEM_ROOT *mem_root);
static uint partition_flags();
static uint alter_table_flags(uint flags);
-handlerton *partition_hton;
static int partition_initialize(void *p)
{
+ handlerton *partition_hton;
partition_hton= (handlerton *)p;
partition_hton->state= SHOW_OPTION_YES;
@@ -102,10 +103,11 @@ static int partition_initialize(void *p)
New partition object
*/
-static handler *partition_create_handler(TABLE_SHARE *share,
+static handler *partition_create_handler(handlerton *hton,
+ TABLE_SHARE *share,
MEM_ROOT *mem_root)
{
- ha_partition *file= new (mem_root) ha_partition(share);
+ ha_partition *file= new (mem_root) ha_partition(hton, share);
if (file && file->initialise_partition(mem_root))
{
delete file;
@@ -155,8 +157,8 @@ static uint alter_table_flags(uint flags __attribute__((unused)))
NONE
*/
-ha_partition::ha_partition(TABLE_SHARE *share)
- :handler(partition_hton, share), m_part_info(NULL), m_create_handler(FALSE),
+ha_partition::ha_partition(handlerton *hton, TABLE_SHARE *share)
+ :handler(hton, share), m_part_info(NULL), m_create_handler(FALSE),
m_is_sub_partitioned(0)
{
DBUG_ENTER("ha_partition::ha_partition(table)");
@@ -176,8 +178,8 @@ ha_partition::ha_partition(TABLE_SHARE *share)
NONE
*/
-ha_partition::ha_partition(partition_info *part_info)
- :handler(partition_hton, NULL), m_part_info(part_info),
+ha_partition::ha_partition(handlerton *hton, partition_info *part_info)
+ :handler(hton, NULL), m_part_info(part_info),
m_create_handler(TRUE),
m_is_sub_partitioned(m_part_info->is_sub_partitioned())
@@ -5659,7 +5661,7 @@ static int free_share(PARTITION_SHARE *share)
#endif /* NOT_USED */
struct st_mysql_storage_engine partition_storage_engine=
-{ MYSQL_HANDLERTON_INTERFACE_VERSION, partition_hton };
+{ MYSQL_HANDLERTON_INTERFACE_VERSION };
mysql_declare_plugin(partition)
{
@@ -5668,6 +5670,7 @@ mysql_declare_plugin(partition)
"partition",
"Mikael Ronstrom, MySQL AB",
"Partition Storage Engine Helper",
+ PLUGIN_LICENSE_GPL,
partition_initialize, /* Plugin Init */
NULL, /* Plugin Deinit */
0x0100, /* 1.0 */
diff --git a/sql/ha_partition.h b/sql/ha_partition.h
index d76591b7514..008bda01bc9 100644
--- a/sql/ha_partition.h
+++ b/sql/ha_partition.h
@@ -150,8 +150,8 @@ public:
partition handler.
-------------------------------------------------------------------------
*/
- ha_partition(TABLE_SHARE * table);
- ha_partition(partition_info * part_info);
+ ha_partition(handlerton *hton, TABLE_SHARE * table);
+ ha_partition(handlerton *hton, partition_info * part_info);
~ha_partition();
/*
A partition handler has no characteristics in itself. It only inherits
diff --git a/sql/handler.cc b/sql/handler.cc
index 7848552f3de..ccf1a1ef8d9 100644
--- a/sql/handler.cc
+++ b/sql/handler.cc
@@ -170,7 +170,7 @@ const char *ha_get_storage_engine(enum legacy_db_type db_type)
static handler *create_default(TABLE_SHARE *table, MEM_ROOT *mem_root)
{
handlerton *hton= ha_default_handlerton(current_thd);
- return (hton && hton->create) ? hton->create(table, mem_root) : NULL;
+ return (hton && hton->create) ? hton->create(hton, table, mem_root) : NULL;
}
@@ -232,7 +232,7 @@ handler *get_new_handler(TABLE_SHARE *share, MEM_ROOT *alloc,
if (db_type && db_type->state == SHOW_OPTION_YES && db_type->create)
{
- if ((file= db_type->create(share, alloc)))
+ if ((file= db_type->create(db_type, share, alloc)))
file->init();
DBUG_RETURN(file);
}
@@ -251,7 +251,7 @@ handler *get_ha_partition(partition_info *part_info)
{
ha_partition *partition;
DBUG_ENTER("get_ha_partition");
- if ((partition= new ha_partition(part_info)))
+ if ((partition= new ha_partition(partition_hton, part_info)))
{
if (partition->initialise_partition(current_thd->mem_root))
{
@@ -376,7 +376,7 @@ int ha_finalize_handlerton(st_plugin_int *plugin)
case SHOW_OPTION_YES:
if (installed_htons[hton->db_type] == hton)
installed_htons[hton->db_type]= NULL;
- if (hton->panic && hton->panic(HA_PANIC_CLOSE))
+ if (hton->panic && hton->panic(hton, HA_PANIC_CLOSE))
DBUG_RETURN(1);
break;
};
@@ -465,6 +465,26 @@ int ha_initialize_handlerton(st_plugin_int *plugin)
hton->state= SHOW_OPTION_DISABLED;
break;
}
+
+ /*
+ This is entirely for legacy. We will create a new "disk based" hton and a
+ "memory" hton which will be configurable longterm. We should be able to
+ remove partition and myisammrg.
+ */
+ switch (hton->db_type) {
+ case DB_TYPE_HEAP:
+ heap_hton= hton;
+ break;
+ case DB_TYPE_MYISAM:
+ myisam_hton= hton;
+ break;
+ case DB_TYPE_PARTITION_DB:
+ partition_hton= hton;
+ break;
+ default:
+ break;
+ };
+
DBUG_RETURN(0);
err:
DBUG_RETURN(1);
@@ -498,7 +518,7 @@ static my_bool panic_handlerton(THD *unused1, st_plugin_int *plugin, void *arg)
{
handlerton *hton= (handlerton *)plugin->data;
if (hton->state == SHOW_OPTION_YES && hton->panic)
- ((int*)arg)[0]|= hton->panic((enum ha_panic_function)((int*)arg)[1]);
+ ((int*)arg)[0]|= hton->panic(hton, (enum ha_panic_function)((int*)arg)[1]);
return FALSE;
}
@@ -520,7 +540,7 @@ static my_bool dropdb_handlerton(THD *unused1, st_plugin_int *plugin,
{
handlerton *hton= (handlerton *)plugin->data;
if (hton->state == SHOW_OPTION_YES && hton->drop_database)
- hton->drop_database((char *)path);
+ hton->drop_database(hton, (char *)path);
return FALSE;
}
@@ -541,7 +561,7 @@ static my_bool closecon_handlerton(THD *thd, st_plugin_int *plugin,
*/
if (hton->state == SHOW_OPTION_YES && hton->close_connection &&
thd->ha_data[hton->slot])
- hton->close_connection(thd);
+ hton->close_connection(hton, thd);
return FALSE;
}
@@ -617,7 +637,7 @@ int ha_prepare(THD *thd)
statistic_increment(thd->status_var.ha_prepare_count,&LOCK_status);
if ((*ht)->prepare)
{
- if ((err= (*(*ht)->prepare)(thd, all)))
+ if ((err= (*(*ht)->prepare)(*ht, thd, all)))
{
my_error(ER_ERROR_DURING_COMMIT, MYF(0), err);
ha_rollback_trans(thd, all);
@@ -691,7 +711,7 @@ int ha_commit_trans(THD *thd, bool all)
for (; *ht && !error; ht++)
{
int err;
- if ((err= (*(*ht)->prepare)(thd, all)))
+ if ((err= (*(*ht)->prepare)(*ht, thd, all)))
{
my_error(ER_ERROR_DURING_COMMIT, MYF(0), err);
error= 1;
@@ -738,7 +758,7 @@ int ha_commit_one_phase(THD *thd, bool all)
for (ht=trans->ht; *ht; ht++)
{
int err;
- if ((err= (*(*ht)->commit)(thd, all)))
+ if ((err= (*(*ht)->commit)(*ht, thd, all)))
{
my_error(ER_ERROR_DURING_COMMIT, MYF(0), err);
error=1;
@@ -794,7 +814,7 @@ int ha_rollback_trans(THD *thd, bool all)
for (handlerton **ht=trans->ht; *ht; ht++)
{
int err;
- if ((err= (*(*ht)->rollback)(thd, all)))
+ if ((err= (*(*ht)->rollback)(*ht, thd, all)))
{ // cannot happen
my_error(ER_ERROR_DURING_ROLLBACK, MYF(0), err);
error=1;
@@ -871,7 +891,7 @@ static my_bool xacommit_handlerton(THD *unused1, st_plugin_int *plugin,
handlerton *hton= (handlerton *)plugin->data;
if (hton->state == SHOW_OPTION_YES && hton->recover)
{
- hton->commit_by_xid(((struct xahton_st *)arg)->xid);
+ hton->commit_by_xid(hton, ((struct xahton_st *)arg)->xid);
((struct xahton_st *)arg)->result= 0;
}
return FALSE;
@@ -883,7 +903,7 @@ static my_bool xarollback_handlerton(THD *unused1, st_plugin_int *plugin,
handlerton *hton= (handlerton *)plugin->data;
if (hton->state == SHOW_OPTION_YES && hton->recover)
{
- hton->rollback_by_xid(((struct xahton_st *)arg)->xid);
+ hton->rollback_by_xid(hton, ((struct xahton_st *)arg)->xid);
((struct xahton_st *)arg)->result= 0;
}
return FALSE;
@@ -993,7 +1013,7 @@ static my_bool xarecover_handlerton(THD *unused, st_plugin_int *plugin,
if (hton->state == SHOW_OPTION_YES && hton->recover)
{
- while ((got= hton->recover(info->list, info->len)) > 0 )
+ while ((got= hton->recover(hton, info->list, info->len)) > 0 )
{
sql_print_information("Found %d prepared transaction(s) in %s",
got, hton2plugin[hton->slot]->name.str);
@@ -1024,7 +1044,7 @@ static my_bool xarecover_handlerton(THD *unused, st_plugin_int *plugin,
char buf[XIDDATASIZE*4+6]; // see xid_to_str
sql_print_information("commit xid %s", xid_to_str(buf, info->list+i));
#endif
- hton->commit_by_xid(info->list+i);
+ hton->commit_by_xid(hton, info->list+i);
}
else
{
@@ -1033,7 +1053,7 @@ static my_bool xarecover_handlerton(THD *unused, st_plugin_int *plugin,
sql_print_information("rollback xid %s",
xid_to_str(buf, info->list+i));
#endif
- hton->rollback_by_xid(info->list+i);
+ hton->rollback_by_xid(hton, info->list+i);
}
}
if (got < info->len)
@@ -1179,7 +1199,7 @@ static my_bool release_temporary_latches(THD *thd, st_plugin_int *plugin,
handlerton *hton= (handlerton *)plugin->data;
if (hton->state == SHOW_OPTION_YES && hton->release_temporary_latches)
- hton->release_temporary_latches(thd);
+ hton->release_temporary_latches(hton, thd);
return FALSE;
}
@@ -1212,7 +1232,7 @@ int ha_rollback_to_savepoint(THD *thd, SAVEPOINT *sv)
{
int err;
DBUG_ASSERT((*ht)->savepoint_set != 0);
- if ((err= (*(*ht)->savepoint_rollback)(thd, (byte *)(sv+1)+(*ht)->savepoint_offset)))
+ if ((err= (*(*ht)->savepoint_rollback)(*ht, thd, (byte *)(sv+1)+(*ht)->savepoint_offset)))
{ // cannot happen
my_error(ER_ERROR_DURING_ROLLBACK, MYF(0), err);
error=1;
@@ -1228,7 +1248,7 @@ int ha_rollback_to_savepoint(THD *thd, SAVEPOINT *sv)
for (; *ht ; ht++)
{
int err;
- if ((err= (*(*ht)->rollback)(thd, !thd->in_sub_stmt)))
+ if ((err= (*(*ht)->rollback)(*ht, thd, !thd->in_sub_stmt)))
{ // cannot happen
my_error(ER_ERROR_DURING_ROLLBACK, MYF(0), err);
error=1;
@@ -1262,7 +1282,7 @@ int ha_savepoint(THD *thd, SAVEPOINT *sv)
error=1;
break;
}
- if ((err= (*(*ht)->savepoint_set)(thd, (byte *)(sv+1)+(*ht)->savepoint_offset)))
+ if ((err= (*(*ht)->savepoint_set)(*ht, thd, (byte *)(sv+1)+(*ht)->savepoint_offset)))
{ // cannot happen
my_error(ER_GET_ERRNO, MYF(0), err);
error=1;
@@ -1288,7 +1308,9 @@ int ha_release_savepoint(THD *thd, SAVEPOINT *sv)
int err;
if (!(*ht)->savepoint_release)
continue;
- if ((err= (*(*ht)->savepoint_release)(thd, (byte *)(sv+1)+(*ht)->savepoint_offset)))
+ if ((err= (*(*ht)->savepoint_release)(*ht, thd,
+ (byte *)(sv+1)+
+ (*ht)->savepoint_offset)))
{ // cannot happen
my_error(ER_GET_ERRNO, MYF(0), err);
error=1;
@@ -1305,7 +1327,7 @@ static my_bool snapshot_handlerton(THD *thd, st_plugin_int *plugin,
if (hton->state == SHOW_OPTION_YES &&
hton->start_consistent_snapshot)
{
- hton->start_consistent_snapshot(thd);
+ hton->start_consistent_snapshot(hton, thd);
*((bool *)arg)= false;
}
return FALSE;
@@ -1333,7 +1355,8 @@ static my_bool flush_handlerton(THD *thd, st_plugin_int *plugin,
void *arg)
{
handlerton *hton= (handlerton *)plugin->data;
- if (hton->state == SHOW_OPTION_YES && hton->flush_logs && hton->flush_logs())
+ if (hton->state == SHOW_OPTION_YES && hton->flush_logs &&
+ hton->flush_logs(hton))
return TRUE;
return FALSE;
}
@@ -1350,7 +1373,7 @@ bool ha_flush_logs(handlerton *db_type)
else
{
if (db_type->state != SHOW_OPTION_YES ||
- (db_type->flush_logs && db_type->flush_logs()))
+ (db_type->flush_logs && db_type->flush_logs(db_type)))
return TRUE;
}
return FALSE;
@@ -2765,7 +2788,9 @@ static my_bool discover_handlerton(THD *thd, st_plugin_int *plugin,
st_discover_args *vargs= (st_discover_args *)arg;
handlerton *hton= (handlerton *)plugin->data;
if (hton->state == SHOW_OPTION_YES && hton->discover &&
- (!(hton->discover(thd, vargs->db, vargs->name, vargs->frmblob, vargs->frmlen))))
+ (!(hton->discover(hton, thd, vargs->db, vargs->name,
+ vargs->frmblob,
+ vargs->frmlen))))
return TRUE;
return FALSE;
@@ -2814,7 +2839,7 @@ static my_bool find_files_handlerton(THD *thd, st_plugin_int *plugin,
if (hton->state == SHOW_OPTION_YES && hton->find_files)
- if (hton->find_files(thd, vargs->db, vargs->path, vargs->wild,
+ if (hton->find_files(hton, thd, vargs->db, vargs->path, vargs->wild,
vargs->dir, vargs->files))
return TRUE;
@@ -2861,7 +2886,7 @@ static my_bool table_exists_in_engine_handlerton(THD *thd, st_plugin_int *plugin
handlerton *hton= (handlerton *)plugin->data;
if (hton->state == SHOW_OPTION_YES && hton->table_exists_in_engine)
- if ((hton->table_exists_in_engine(thd, vargs->db, vargs->name)) == 1)
+ if ((hton->table_exists_in_engine(hton, thd, vargs->db, vargs->name)) == 1)
return TRUE;
return FALSE;
@@ -2930,7 +2955,7 @@ static my_bool binlog_func_foreach(THD *thd, binlog_func_st *bfn)
uint i= 0, sz= hton_list.sz;
while(i < sz)
- hton_list.hton[i++]->binlog_func(thd, bfn->fn, bfn->arg);
+ hton_list.hton[i++]->binlog_func(hton, thd, bfn->fn, bfn->arg);
return FALSE;
}
@@ -2977,12 +3002,12 @@ struct binlog_log_query_st
};
static my_bool binlog_log_query_handlerton2(THD *thd,
- const handlerton *hton,
+ handlerton *hton,
void *args)
{
struct binlog_log_query_st *b= (struct binlog_log_query_st*)args;
if (hton->state == SHOW_OPTION_YES && hton->binlog_log_query)
- hton->binlog_log_query(thd,
+ hton->binlog_log_query(hton, thd,
b->binlog_command,
b->query,
b->query_length,
@@ -2995,10 +3020,10 @@ static my_bool binlog_log_query_handlerton(THD *thd,
st_plugin_int *plugin,
void *args)
{
- return binlog_log_query_handlerton2(thd, (const handlerton *)plugin->data, args);
+ return binlog_log_query_handlerton2(thd, (handlerton *)plugin->data, args);
}
-void ha_binlog_log_query(THD *thd, const handlerton *hton,
+void ha_binlog_log_query(THD *thd, handlerton *hton,
enum_binlog_command binlog_command,
const char *query, uint query_length,
const char *db, const char *table_name)
@@ -3296,7 +3321,7 @@ static my_bool exts_handlerton(THD *unused, st_plugin_int *plugin,
handlerton *hton= (handlerton *)plugin->data;
handler *file;
if (hton->state == SHOW_OPTION_YES && hton->create &&
- (file= hton->create((TABLE_SHARE*) 0, current_thd->mem_root)))
+ (file= hton->create(hton, (TABLE_SHARE*) 0, current_thd->mem_root)))
{
List_iterator_fast<char> it(*found_exts);
const char **ext, *old_ext;
@@ -3371,7 +3396,7 @@ static my_bool showstat_handlerton(THD *thd, st_plugin_int *plugin,
enum ha_stat_type stat= *(enum ha_stat_type *) arg;
handlerton *hton= (handlerton *)plugin->data;
if (hton->state == SHOW_OPTION_YES && hton->show_status &&
- hton->show_status(thd, stat_print, stat))
+ hton->show_status(hton, thd, stat_print, stat))
return TRUE;
return FALSE;
}
@@ -3405,7 +3430,7 @@ bool ha_show_status(THD *thd, handlerton *db_type, enum ha_stat_type stat)
}
else
result= db_type->show_status &&
- db_type->show_status(thd, stat_print, stat) ? 1 : 0;
+ db_type->show_status(db_type, thd, stat_print, stat) ? 1 : 0;
}
if (!result)
@@ -3726,7 +3751,7 @@ int example_of_iterator_using_for_logs_cleanup(handlerton *hton)
if (!hton->create_iterator)
return 1; /* iterator creator is not supported */
- if ((*hton->create_iterator)(HA_TRANSACTLOG_ITERATOR, &iterator) !=
+ if ((*hton->create_iterator)(hton, HA_TRANSACTLOG_ITERATOR, &iterator) !=
HA_ITERATOR_OK)
{
/* error during creation of log iterator or iterator is not supported */
diff --git a/sql/handler.h b/sql/handler.h
index 2efe9f3ce6a..5e26d9c7b63 100644
--- a/sql/handler.h
+++ b/sql/handler.h
@@ -449,7 +449,7 @@ class st_alter_tablespace : public Sql_alloc
ulonglong autoextend_size;
ulonglong max_size;
uint nodegroup_id;
- const handlerton *storage_engine;
+ handlerton *storage_engine;
bool wait_until_completed;
const char *ts_comment;
enum tablespace_access_mode ts_access_mode;
@@ -605,18 +605,18 @@ struct handlerton
this storage area - set it to something, so that MySQL would know
this storage engine was accessed in this connection
*/
- int (*close_connection)(THD *thd);
+ int (*close_connection)(handlerton *hton, THD *thd);
/*
sv points to an uninitialized storage area of requested size
(see savepoint_offset description)
*/
- int (*savepoint_set)(THD *thd, void *sv);
+ int (*savepoint_set)(handlerton *hton, THD *thd, void *sv);
/*
sv points to a storage area, that was earlier passed
to the savepoint_set call
*/
- int (*savepoint_rollback)(THD *thd, void *sv);
- int (*savepoint_release)(THD *thd, void *sv);
+ int (*savepoint_rollback)(handlerton *hton, THD *thd, void *sv);
+ int (*savepoint_release)(handlerton *hton, THD *thd, void *sv);
/*
'all' is true if it's a real commit, that makes persistent changes
'all' is false if it's not in fact a commit but an end of the
@@ -624,25 +624,25 @@ struct handlerton
NOTE 'all' is also false in auto-commit mode where 'end of statement'
and 'real commit' mean the same event.
*/
- int (*commit)(THD *thd, bool all);
- int (*rollback)(THD *thd, bool all);
- int (*prepare)(THD *thd, bool all);
- int (*recover)(XID *xid_list, uint len);
- int (*commit_by_xid)(XID *xid);
- int (*rollback_by_xid)(XID *xid);
- void *(*create_cursor_read_view)();
- void (*set_cursor_read_view)(void *);
- void (*close_cursor_read_view)(void *);
- handler *(*create)(TABLE_SHARE *table, MEM_ROOT *mem_root);
- void (*drop_database)(char* path);
- int (*panic)(enum ha_panic_function flag);
- int (*start_consistent_snapshot)(THD *thd);
- bool (*flush_logs)();
- bool (*show_status)(THD *thd, stat_print_fn *print, enum ha_stat_type stat);
+ int (*commit)(handlerton *hton, THD *thd, bool all);
+ int (*rollback)(handlerton *hton, THD *thd, bool all);
+ int (*prepare)(handlerton *hton, THD *thd, bool all);
+ int (*recover)(handlerton *hton, XID *xid_list, uint len);
+ int (*commit_by_xid)(handlerton *hton, XID *xid);
+ int (*rollback_by_xid)(handlerton *hton, XID *xid);
+ void *(*create_cursor_read_view)(handlerton *hton, THD *thd);
+ void (*set_cursor_read_view)(handlerton *hton, THD *thd, void *read_view);
+ void (*close_cursor_read_view)(handlerton *hton, THD *thd, void *read_view);
+ handler *(*create)(handlerton *hton, TABLE_SHARE *table, MEM_ROOT *mem_root);
+ void (*drop_database)(handlerton *hton, char* path);
+ int (*panic)(handlerton *hton, enum ha_panic_function flag);
+ int (*start_consistent_snapshot)(handlerton *hton, THD *thd);
+ bool (*flush_logs)(handlerton *hton);
+ bool (*show_status)(handlerton *hton, THD *thd, stat_print_fn *print, enum ha_stat_type stat);
uint (*partition_flags)();
uint (*alter_table_flags)(uint flags);
- int (*alter_tablespace)(THD *thd, st_alter_tablespace *ts_info);
- int (*fill_files_table)(THD *thd,
+ int (*alter_tablespace)(handlerton *hton, THD *thd, st_alter_tablespace *ts_info);
+ int (*fill_files_table)(handlerton *hton, THD *thd,
struct st_table_list *tables,
class Item *cond);
uint32 flags; /* global handler flags */
@@ -650,11 +650,12 @@ struct handlerton
Those handlerton functions below are properly initialized at handler
init.
*/
- int (*binlog_func)(THD *thd, enum_binlog_func fn, void *arg);
- void (*binlog_log_query)(THD *thd, enum_binlog_command binlog_command,
+ int (*binlog_func)(handlerton *hton, THD *thd, enum_binlog_func fn, void *arg);
+ void (*binlog_log_query)(handlerton *hton, THD *thd,
+ enum_binlog_command binlog_command,
const char *query, uint query_length,
const char *db, const char *table_name);
- int (*release_temporary_latches)(THD *thd);
+ int (*release_temporary_latches)(handlerton *hton, THD *thd);
/*
Get log status.
@@ -663,21 +664,26 @@ struct handlerton
(see example of implementation in handler.cc, TRANS_LOG_MGM_EXAMPLE_CODE)
*/
- enum log_status (*get_log_status)(char *log);
+ enum log_status (*get_log_status)(handlerton *hton, char *log);
/*
Iterators creator.
Presence of the pointer should be checked before using
*/
enum handler_create_iterator_result
- (*create_iterator)(enum handler_iterator_type type,
+ (*create_iterator)(handlerton *hton, enum handler_iterator_type type,
struct handler_iterator *fill_this_in);
- int (*discover)(THD* thd, const char *db, const char *name,
- const void** frmblob, uint* frmlen);
- int (*find_files)(THD *thd,const char *db,const char *path,
+ int (*discover)(handlerton *hton, THD* thd, const char *db,
+ const char *name,
+ const void** frmblob,
+ uint* frmlen);
+ int (*find_files)(handlerton *hton, THD *thd,
+ const char *db,
+ const char *path,
const char *wild, bool dir, List<char> *files);
- int (*table_exists_in_engine)(THD* thd, const char *db,
+ int (*table_exists_in_engine)(handlerton *hton, THD* thd, const char *db,
const char *name);
+ uint32 license; /* Flag for Engine License */
};
@@ -691,6 +697,7 @@ struct handlerton
#define HTON_NOT_USER_SELECTABLE (1 << 5)
#define HTON_TEMPORARY_NOT_SUPPORTED (1 << 6) //Having temporary tables not supported
#define HTON_SUPPORT_LOG_TABLES (1 << 7) //Engine supports log tables
+#define HTON_NO_PARTITION (1 << 8) //You can not partition these tables
typedef struct st_thd_trans
{
@@ -893,7 +900,7 @@ class handler :public Sql_alloc
virtual void start_bulk_insert(ha_rows rows) {}
virtual int end_bulk_insert() {return 0; }
public:
- const handlerton *ht; /* storage engine of this handler */
+ handlerton *ht; /* storage engine of this handler */
byte *ref; /* Pointer to current row */
byte *dup_ref; /* Pointer to duplicate row */
@@ -943,7 +950,7 @@ public:
*/
Discrete_interval auto_inc_interval_for_cur_row;
- handler(const handlerton *ht_arg, TABLE_SHARE *share_arg)
+ handler(handlerton *ht_arg, TABLE_SHARE *share_arg)
:table_share(share_arg), estimation_rows_to_insert(0), ht(ht_arg),
ref(0), key_used_on_scan(MAX_KEY), active_index(MAX_KEY),
ref_length(sizeof(my_off_t)),
@@ -1716,7 +1723,7 @@ void trans_register_ha(THD *thd, bool all, handlerton *ht);
int ha_reset_logs(THD *thd);
int ha_binlog_index_purge_file(THD *thd, const char *file);
void ha_reset_slave(THD *thd);
-void ha_binlog_log_query(THD *thd, const handlerton *db_type,
+void ha_binlog_log_query(THD *thd, handlerton *db_type,
enum_binlog_command binlog_command,
const char *query, uint query_length,
const char *db, const char *table_name);
diff --git a/sql/item.cc b/sql/item.cc
index 39f1ac3feea..f8a8b4a6272 100644
--- a/sql/item.cc
+++ b/sql/item.cc
@@ -1210,6 +1210,7 @@ void Item::split_sum_func2(THD *thd, Item **ref_pointer_array,
split_sum_func(thd, ref_pointer_array, fields);
}
else if ((type() == SUM_FUNC_ITEM || (used_tables() & ~PARAM_TABLE_BIT)) &&
+ type() != SUBSELECT_ITEM &&
(type() != REF_ITEM ||
((Item_ref*)this)->ref_type() == Item_ref::VIEW_REF))
{
@@ -3795,6 +3796,7 @@ void Item_field::cleanup()
I.e. we can drop 'field'.
*/
field= result_field= 0;
+ null_value= FALSE;
DBUG_VOID_RETURN;
}
@@ -5710,11 +5712,6 @@ void Item_trigger_field::cleanup()
}
-/*
- If item is a const function, calculate it and return a const item
- The original item is freed if not returned
-*/
-
Item_result item_cmp_type(Item_result a,Item_result b)
{
if (a == STRING_RESULT && b == STRING_RESULT)
diff --git a/sql/item_cmpfunc.cc b/sql/item_cmpfunc.cc
index 0aa6d432966..135e4596996 100644
--- a/sql/item_cmpfunc.cc
+++ b/sql/item_cmpfunc.cc
@@ -66,12 +66,10 @@ static void agg_result_type(Item_result *type, Item **items, uint nitems)
/*
Aggregates result types from the array of items.
- SYNOPSIS:
+ SYNOPSIS
agg_cmp_type()
- thd thread handle
- type [out] the aggregated type
- items array of items to aggregate the type from
- nitems number of items in the array
+ items array of items to aggregate the type from
+ nitems number of items in the array
DESCRIPTION
This function aggregates result types from the array of items. Found type
@@ -79,12 +77,43 @@ static void agg_result_type(Item_result *type, Item **items, uint nitems)
Aggregation itself is performed by the item_cmp_type() function.
*/
-static void agg_cmp_type(THD *thd, Item_result *type, Item **items, uint nitems)
+static Item_result agg_cmp_type(Item **items, uint nitems)
{
uint i;
- type[0]= items[0]->result_type();
+ Item_result type= items[0]->result_type();
for (i= 1 ; i < nitems ; i++)
- type[0]= item_cmp_type(type[0], items[i]->result_type());
+ type= item_cmp_type(type, items[i]->result_type());
+ return type;
+}
+
+
+/*
+ Collects different types for comparison of first item with each other items
+
+ SYNOPSIS
+ collect_cmp_types()
+ items Array of items to collect types from
+ nitems Number of items in the array
+
+ DESCRIPTION
+ This function collects different result types for comparison of the first
+ item in the list with each of the remaining items in the 'items' array.
+
+ RETURN
+ Bitmap of collected types
+*/
+
+static uint collect_cmp_types(Item **items, uint nitems)
+{
+ uint i;
+ uint found_types;
+ Item_result left_result= items[0]->result_type();
+ DBUG_ASSERT(nitems > 1);
+ found_types= 0;
+ for (i= 1; i < nitems ; i++)
+ found_types|= 1<< (uint)item_cmp_type(left_result,
+ items[i]->result_type());
+ return found_types;
}
@@ -1117,7 +1146,7 @@ void Item_func_between::fix_length_and_dec()
*/
if (!args[0] || !args[1] || !args[2])
return;
- agg_cmp_type(thd, &cmp_type, args, 3);
+ cmp_type= agg_cmp_type(args, 3);
if (cmp_type == STRING_RESULT &&
agg_arg_charsets(cmp_collation, args, 3, MY_COLL_CMP_CONV, 1))
return;
@@ -1597,94 +1626,65 @@ Item_func_nullif::is_null()
return (null_value= (!cmp.compare() ? 1 : args[0]->null_value));
}
+
/*
- CASE expression
Return the matching ITEM or NULL if all compares (including else) failed
+
+ SYNOPSIS
+ find_item()
+ str Buffer string
+
+ DESCRIPTION
+ Find and return matching items for CASE or ELSE item if all compares
+ are failed or NULL if ELSE item isn't defined.
+
+ IMPLEMENTATION
+ In order to do correct comparisons of the CASE expression (the expression
+ between CASE and the first WHEN) with each WHEN expression several
+ comparators are used. One for each result type. CASE expression can be
+ evaluated up to # of different result types are used. To check whether
+ the CASE expression already was evaluated for a particular result type
+ a bit mapped variable value_added_map is used. Result types are mapped
+ to it according to their int values i.e. STRING_RESULT is mapped to bit
+ 0, REAL_RESULT to bit 1, so on.
+
+ RETURN
+ NULL - Nothing found and there is no ELSE expression defined
+ item - Found item or ELSE item if defined and all comparisons are
+ failed
*/
Item *Item_func_case::find_item(String *str)
{
- String *first_expr_str, *tmp;
- my_decimal *first_expr_dec, first_expr_dec_val;
- longlong first_expr_int;
- double first_expr_real;
- char buff[MAX_FIELD_WIDTH];
- String buff_str(buff,sizeof(buff),default_charset());
-
- /* These will be initialized later */
- LINT_INIT(first_expr_str);
- LINT_INIT(first_expr_int);
- LINT_INIT(first_expr_real);
- LINT_INIT(first_expr_dec);
-
- if (first_expr_num != -1)
- {
- switch (cmp_type)
- {
- case STRING_RESULT:
- // We can't use 'str' here as this may be overwritten
- if (!(first_expr_str= args[first_expr_num]->val_str(&buff_str)))
- return else_expr_num != -1 ? args[else_expr_num] : 0; // Impossible
- break;
- case INT_RESULT:
- first_expr_int= args[first_expr_num]->val_int();
- if (args[first_expr_num]->null_value)
- return else_expr_num != -1 ? args[else_expr_num] : 0;
- break;
- case REAL_RESULT:
- first_expr_real= args[first_expr_num]->val_real();
- if (args[first_expr_num]->null_value)
- return else_expr_num != -1 ? args[else_expr_num] : 0;
- break;
- case DECIMAL_RESULT:
- first_expr_dec= args[first_expr_num]->val_decimal(&first_expr_dec_val);
- if (args[first_expr_num]->null_value)
- return else_expr_num != -1 ? args[else_expr_num] : 0;
- break;
- case ROW_RESULT:
- default:
- // This case should never be chosen
- DBUG_ASSERT(0);
- break;
- }
- }
+ uint value_added_map= 0;
- // Compare every WHEN argument with it and return the first match
- for (uint i=0 ; i < ncases ; i+=2)
+ if (first_expr_num == -1)
{
- if (first_expr_num == -1)
+ for (uint i=0 ; i < ncases ; i+=2)
{
// No expression between CASE and the first WHEN
if (args[i]->val_bool())
return args[i+1];
continue;
}
- switch (cmp_type) {
- case STRING_RESULT:
- if ((tmp=args[i]->val_str(str))) // If not null
- if (sortcmp(tmp,first_expr_str,cmp_collation.collation)==0)
- return args[i+1];
- break;
- case INT_RESULT:
- if (args[i]->val_int()==first_expr_int && !args[i]->null_value)
- return args[i+1];
- break;
- case REAL_RESULT:
- if (args[i]->val_real() == first_expr_real && !args[i]->null_value)
- return args[i+1];
- break;
- case DECIMAL_RESULT:
+ }
+ else
+ {
+ /* Compare every WHEN argument with it and return the first match */
+ for (uint i=0 ; i < ncases ; i+=2)
{
- my_decimal value;
- if (my_decimal_cmp(args[i]->val_decimal(&value), first_expr_dec) == 0)
- return args[i+1];
- break;
- }
- case ROW_RESULT:
- default:
- // This case should never be chosen
- DBUG_ASSERT(0);
- break;
+ cmp_type= item_cmp_type(left_result_type, args[i]->result_type());
+ DBUG_ASSERT(cmp_type != ROW_RESULT);
+ DBUG_ASSERT(cmp_items[(uint)cmp_type]);
+ if (!(value_added_map & (1<<(uint)cmp_type)))
+ {
+ cmp_items[(uint)cmp_type]->store_value(args[first_expr_num]);
+ if ((null_value=args[first_expr_num]->null_value))
+ return else_expr_num != -1 ? args[else_expr_num] : 0;
+ value_added_map|= 1<<(uint)cmp_type;
+ }
+ if (!cmp_items[(uint)cmp_type]->cmp(args[i]) && !args[i]->null_value)
+ return args[i + 1];
}
}
// No, WHEN clauses all missed, return ELSE expression
@@ -1791,7 +1791,7 @@ void Item_func_case::fix_length_and_dec()
Item **agg;
uint nagg;
THD *thd= current_thd;
-
+ uint found_types= 0;
if (!(agg= (Item**) sql_alloc(sizeof(Item*)*(ncases+1))))
return;
@@ -1818,16 +1818,31 @@ void Item_func_case::fix_length_and_dec()
*/
if (first_expr_num != -1)
{
+ uint i;
agg[0]= args[first_expr_num];
+ left_result_type= agg[0]->result_type();
+
for (nagg= 0; nagg < ncases/2 ; nagg++)
agg[nagg+1]= args[nagg*2];
nagg++;
- agg_cmp_type(thd, &cmp_type, agg, nagg);
- if ((cmp_type == STRING_RESULT) &&
- agg_arg_charsets(cmp_collation, agg, nagg, MY_COLL_CMP_CONV, 1))
- return;
+ found_types= collect_cmp_types(agg, nagg);
+
+ for (i= 0; i <= (uint)DECIMAL_RESULT; i++)
+ {
+ if (found_types & (1 << i) && !cmp_items[i])
+ {
+ DBUG_ASSERT((Item_result)i != ROW_RESULT);
+ if ((Item_result)i == STRING_RESULT &&
+ agg_arg_charsets(cmp_collation, agg, nagg, MY_COLL_CMP_CONV, 1))
+ return;
+ if (!(cmp_items[i]=
+ cmp_item::get_comparator((Item_result)i,
+ cmp_collation.collation)))
+ return;
+ }
+ }
}
-
+
if (else_expr_num == -1 || args[else_expr_num]->maybe_null)
maybe_null=1;
@@ -2412,16 +2427,14 @@ static int srtcmp_in(CHARSET_INFO *cs, const String *x,const String *y)
void Item_func_in::fix_length_and_dec()
{
Item **arg, **arg_end;
- uint const_itm= 1;
+ bool const_itm= 1;
THD *thd= current_thd;
+ uint found_types= 0;
+ uint type_cnt= 0, i;
+ left_result_type= args[0]->result_type();
+ found_types= collect_cmp_types(args, arg_count);
- agg_cmp_type(thd, &cmp_type, args, arg_count);
-
- if (cmp_type == STRING_RESULT &&
- agg_arg_charsets(cmp_collation, args, arg_count, MY_COLL_CMP_CONV, 1))
- return;
-
- for (arg=args+1, arg_end=args+arg_count; arg != arg_end ; arg++)
+ for (arg= args + 1, arg_end= args + arg_count; arg != arg_end ; arg++)
{
if (!arg[0]->const_item())
{
@@ -2429,26 +2442,39 @@ void Item_func_in::fix_length_and_dec()
break;
}
}
-
+ for (i= 0; i <= (uint)DECIMAL_RESULT; i++)
+ {
+ if (found_types & 1 << i)
+ (type_cnt)++;
+ }
/*
- Row item with NULLs inside can return NULL or FALSE =>
+ Row item with NULLs inside can return NULL or FALSE =>
they can't be processed as static
*/
- if (const_itm && !nulls_in_row())
+ if (type_cnt == 1 && const_itm && !nulls_in_row())
{
+ uint tmp_type;
+ Item_result cmp_type;
+ /* Only one cmp type was found. Extract it here */
+ for (tmp_type= 0; found_types - 1; found_types>>= 1)
+ tmp_type++;
+ cmp_type= (Item_result)tmp_type;
+
switch (cmp_type) {
case STRING_RESULT:
- array=new in_string(arg_count-1,(qsort2_cmp) srtcmp_in,
+ if (agg_arg_charsets(cmp_collation, args, arg_count, MY_COLL_CMP_CONV, 1))
+ return;
+ array=new in_string(arg_count - 1,(qsort2_cmp) srtcmp_in,
cmp_collation.collation);
break;
case INT_RESULT:
- array= new in_longlong(arg_count-1);
+ array= new in_longlong(arg_count - 1);
break;
case REAL_RESULT:
- array= new in_double(arg_count-1);
+ array= new in_double(arg_count - 1);
break;
case ROW_RESULT:
- array= new in_row(arg_count-1, args[0]);
+ array= new in_row(arg_count - 1, args[0]);
break;
case DECIMAL_RESULT:
array= new in_decimal(arg_count - 1);
@@ -2468,15 +2494,25 @@ void Item_func_in::fix_length_and_dec()
else
have_null= 1;
}
- if ((array->used_count=j))
+ if ((array->used_count= j))
array->sort();
}
}
else
{
- in_item= cmp_item::get_comparator(cmp_type, cmp_collation.collation);
- if (cmp_type == STRING_RESULT)
- in_item->cmp_charset= cmp_collation.collation;
+ for (i= 0; i <= (uint) DECIMAL_RESULT; i++)
+ {
+ if (found_types & (1 << i) && !cmp_items[i])
+ {
+ if ((Item_result)i == STRING_RESULT &&
+ agg_arg_charsets(cmp_collation, args, arg_count, MY_COLL_CMP_CONV, 1))
+ return;
+ if (!(cmp_items[i]=
+ cmp_item::get_comparator((Item_result)i,
+ cmp_collation.collation)))
+ return;
+ }
+ }
}
maybe_null= args[0]->maybe_null;
max_length= 1;
@@ -2495,25 +2531,61 @@ void Item_func_in::print(String *str)
}
+/*
+ Evaluate the function and return its value.
+
+ SYNOPSIS
+ val_int()
+
+ DESCRIPTION
+ Evaluate the function and return its value.
+
+ IMPLEMENTATION
+ If the array object is defined then the value of the function is
+ calculated by means of this array.
+ Otherwise several cmp_item objects are used in order to do correct
+ comparison of left expression and an expression from the values list.
+ One cmp_item object correspond to one used comparison type. Left
+ expression can be evaluated up to number of different used comparison
+ types. A bit mapped variable value_added_map is used to check whether
+ the left expression already was evaluated for a particular result type.
+ Result types are mapped to it according to their integer values i.e.
+ STRING_RESULT is mapped to bit 0, REAL_RESULT to bit 1, so on.
+
+ RETURN
+ Value of the function
+*/
+
longlong Item_func_in::val_int()
{
+ cmp_item *in_item;
DBUG_ASSERT(fixed == 1);
+ uint value_added_map= 0;
if (array)
{
int tmp=array->find(args[0]);
null_value=args[0]->null_value || (!tmp && have_null);
return (longlong) (!null_value && tmp != negated);
}
- in_item->store_value(args[0]);
- if ((null_value=args[0]->null_value))
- return 0;
- have_null= 0;
- for (uint i=1 ; i < arg_count ; i++)
+
+ for (uint i= 1 ; i < arg_count ; i++)
{
+ Item_result cmp_type= item_cmp_type(left_result_type, args[i]->result_type());
+ in_item= cmp_items[(uint)cmp_type];
+ DBUG_ASSERT(in_item);
+ if (!(value_added_map & (1 << (uint)cmp_type)))
+ {
+ in_item->store_value(args[0]);
+ if ((null_value=args[0]->null_value))
+ return 0;
+ have_null= 0;
+ value_added_map|= 1 << (uint)cmp_type;
+ }
if (!in_item->cmp(args[i]) && !args[i]->null_value)
return (longlong) (!negated);
have_null|= args[i]->null_value;
}
+
null_value= have_null;
return (longlong) (!null_value && negated);
}
diff --git a/sql/item_cmpfunc.h b/sql/item_cmpfunc.h
index 18badc71c1d..1b88153b049 100644
--- a/sql/item_cmpfunc.h
+++ b/sql/item_cmpfunc.h
@@ -588,50 +588,6 @@ public:
bool check_partition_func_processor(byte *int_arg) {return FALSE;}
};
-
-class Item_func_case :public Item_func
-{
- int first_expr_num, else_expr_num;
- enum Item_result cached_result_type;
- String tmp_value;
- uint ncases;
- Item_result cmp_type;
- DTCollation cmp_collation;
-public:
- Item_func_case(List<Item> &list, Item *first_expr_arg, Item *else_expr_arg)
- :Item_func(), first_expr_num(-1), else_expr_num(-1),
- cached_result_type(INT_RESULT)
- {
- ncases= list.elements;
- if (first_expr_arg)
- {
- first_expr_num= list.elements;
- list.push_back(first_expr_arg);
- }
- if (else_expr_arg)
- {
- else_expr_num= list.elements;
- list.push_back(else_expr_arg);
- }
- set_arguments(list);
- }
- double val_real();
- longlong val_int();
- String *val_str(String *);
- my_decimal *val_decimal(my_decimal *);
- bool fix_fields(THD *thd, Item **ref);
- void fix_length_and_dec();
- uint decimal_precision() const;
- table_map not_null_tables() const { return 0; }
- enum Item_result result_type () const { return cached_result_type; }
- const char *func_name() const { return "case"; }
- void print(String *str);
- Item *find_item(String *str);
- CHARSET_INFO *compare_collation() { return cmp_collation.collation; }
- bool check_partition_func_processor(byte *int_arg) {return FALSE;}
-};
-
-
/* Functions to handle the optimized IN */
@@ -686,6 +642,7 @@ public:
{
return test(compare(collation, base + pos1*size, base + pos2*size));
}
+ virtual Item_result result_type()= 0;
};
class in_string :public in_vector
@@ -707,6 +664,7 @@ public:
Item_string *to= (Item_string*)item;
to->str_value= *str;
}
+ Item_result result_type() { return STRING_RESULT; }
};
class in_longlong :public in_vector
@@ -729,6 +687,7 @@ public:
{
((Item_int*)item)->value= ((longlong*)base)[pos];
}
+ Item_result result_type() { return INT_RESULT; }
};
class in_double :public in_vector
@@ -746,6 +705,7 @@ public:
{
((Item_float*)item)->value= ((double*) base)[pos];
}
+ Item_result result_type() { return REAL_RESULT; }
};
@@ -766,6 +726,8 @@ public:
Item_decimal *item_dec= (Item_decimal*)item;
item_dec->set_decimal_value(dec);
}
+ Item_result result_type() { return DECIMAL_RESULT; }
+
};
@@ -796,7 +758,9 @@ class cmp_item_string :public cmp_item
protected:
String *value_res;
public:
+ cmp_item_string () {}
cmp_item_string (CHARSET_INFO *cs) { cmp_charset= cs; }
+ void set_charset(CHARSET_INFO *cs) { cmp_charset= cs; }
friend class cmp_item_sort_string;
friend class cmp_item_sort_string_in_static;
};
@@ -807,6 +771,8 @@ protected:
char value_buff[STRING_BUFFER_USUAL_SIZE];
String value;
public:
+ cmp_item_sort_string():
+ cmp_item_string() {}
cmp_item_sort_string(CHARSET_INFO *cs):
cmp_item_string(cs),
value(value_buff, sizeof(value_buff), cs) {}
@@ -828,6 +794,11 @@ public:
return sortcmp(value_res, cmp->value_res, cmp_charset);
}
cmp_item *make_same();
+ void set_charset(CHARSET_INFO *cs)
+ {
+ cmp_charset= cs;
+ value.set_quick(value_buff, sizeof(value_buff), cs);
+ }
};
class cmp_item_int :public cmp_item
@@ -908,6 +879,7 @@ public:
~in_row();
void set(uint pos,Item *item);
byte *get_value(Item *item);
+ Item_result result_type() { return ROW_RESULT; }
};
/*
@@ -943,18 +915,109 @@ public:
}
};
+
+/*
+ The class Item_func_case is the CASE ... WHEN ... THEN ... END function
+ implementation.
+
+ When there is no expression between CASE and the first WHEN
+ (the CASE expression) then this function simple checks all WHEN expressions
+ one after another. When some WHEN expression evaluated to TRUE then the
+ value of the corresponding THEN expression is returned.
+
+ When the CASE expression is specified then it is compared to each WHEN
+ expression individually. When an equal WHEN expression is found
+ corresponding THEN expression is returned.
+ In order to do correct comparisons several comparators are used. One for
+ each result type. Different result types that are used in particular
+ CASE ... END expression are collected in the fix_length_and_dec() member
+ function and only comparators for there result types are used.
+*/
+
+class Item_func_case :public Item_func
+{
+ int first_expr_num, else_expr_num;
+ enum Item_result cached_result_type, left_result_type;
+ String tmp_value;
+ uint ncases;
+ Item_result cmp_type;
+ DTCollation cmp_collation;
+ cmp_item *cmp_items[5]; /* For all result types */
+ cmp_item *case_item;
+public:
+ Item_func_case(List<Item> &list, Item *first_expr_arg, Item *else_expr_arg)
+ :Item_func(), first_expr_num(-1), else_expr_num(-1),
+ cached_result_type(INT_RESULT), left_result_type(INT_RESULT), case_item(0)
+ {
+ ncases= list.elements;
+ if (first_expr_arg)
+ {
+ first_expr_num= list.elements;
+ list.push_back(first_expr_arg);
+ }
+ if (else_expr_arg)
+ {
+ else_expr_num= list.elements;
+ list.push_back(else_expr_arg);
+ }
+ set_arguments(list);
+ bzero(&cmp_items, sizeof(cmp_items));
+ }
+ double val_real();
+ longlong val_int();
+ String *val_str(String *);
+ my_decimal *val_decimal(my_decimal *);
+ bool fix_fields(THD *thd, Item **ref);
+ void fix_length_and_dec();
+ uint decimal_precision() const;
+ table_map not_null_tables() const { return 0; }
+ enum Item_result result_type () const { return cached_result_type; }
+ const char *func_name() const { return "case"; }
+ void print(String *str);
+ Item *find_item(String *str);
+ CHARSET_INFO *compare_collation() { return cmp_collation.collation; }
+ bool check_partition_func_processor(byte *bool_arg) { return FALSE;}
+ void cleanup()
+ {
+ uint i;
+ DBUG_ENTER("Item_func_case::cleanup");
+ Item_func::cleanup();
+ for (i= 0; i <= (uint)DECIMAL_RESULT; i++)
+ {
+ delete cmp_items[i];
+ cmp_items[i]= 0;
+ }
+ DBUG_VOID_RETURN;
+ }
+};
+
+/*
+ The Item_func_in class implements the in_expr IN(values_list) function.
+
+ The current implementation distinguishes 2 cases:
+ 1) all items in the value_list are constants and have the same
+ result type. This case is handled by in_vector class.
+ 2) items in the value_list have different result types or there is some
+ non-constant items.
+ In this case Item_func_in employs several cmp_item objects to performs
+ comparisons of in_expr and an item from the values_list. One cmp_item
+ object for each result type. Different result types are collected in the
+ fix_length_and_dec() member function by means of collect_cmp_types()
+ function.
+*/
class Item_func_in :public Item_func_opt_neg
{
public:
- Item_result cmp_type;
in_vector *array;
- cmp_item *in_item;
bool have_null;
+ Item_result left_result_type;
+ cmp_item *cmp_items[5]; /* One cmp_item for each result type */
DTCollation cmp_collation;
Item_func_in(List<Item> &list)
- :Item_func_opt_neg(list), array(0), in_item(0), have_null(0)
+ :Item_func_opt_neg(list), array(0), have_null(0)
{
+ bzero(&cmp_items, sizeof(cmp_items));
allowed_arg_cols= 0; // Fetch this value from first argument
}
longlong val_int();
@@ -963,12 +1026,16 @@ public:
uint decimal_precision() const { return 1; }
void cleanup()
{
+ uint i;
DBUG_ENTER("Item_func_in::cleanup");
Item_int_func::cleanup();
delete array;
- delete in_item;
array= 0;
- in_item= 0;
+ for (i= 0; i <= (uint)DECIMAL_RESULT; i++)
+ {
+ delete cmp_items[i];
+ cmp_items[i]= 0;
+ }
DBUG_VOID_RETURN;
}
optimize_type select_optimize() const
diff --git a/sql/item_strfunc.cc b/sql/item_strfunc.cc
index 851551a86d9..7a82dd753b3 100644
--- a/sql/item_strfunc.cc
+++ b/sql/item_strfunc.cc
@@ -1149,12 +1149,13 @@ void Item_func_substr::fix_length_and_dec()
}
if (arg_count == 3 && args[2]->const_item())
{
- int32 length= (int32) args[2]->val_int() * collation.collation->mbmaxlen;
+ int32 length= (int32) args[2]->val_int();
if (length <= 0)
max_length=0; /* purecov: inspected */
else
set_if_smaller(max_length,(uint) length);
}
+ max_length*= collation.collation->mbmaxlen;
}
diff --git a/sql/item_sum.cc b/sql/item_sum.cc
index cf122f565ff..73e2c5e6935 100644
--- a/sql/item_sum.cc
+++ b/sql/item_sum.cc
@@ -246,7 +246,27 @@ bool Item_sum::register_sum_func(THD *thd, Item **ref)
aggr_sl->inner_sum_func_list->next= this;
}
aggr_sl->inner_sum_func_list= this;
-
+ aggr_sl->with_sum_func= 1;
+
+ /*
+ Mark Item_subselect(s) as containing aggregate function all the way up
+ to aggregate function's calculation context.
+ Note that we must not mark the Item of calculation context itself
+ because with_sum_func on the calculation context st_select_lex is
+ already set above.
+
+ with_sum_func being set for an Item means that this Item refers
+ (somewhere in it, e.g. one of its arguments if it's a function) directly
+ or through intermediate items to an aggregate function that is calculated
+ in a context "outside" of the Item (e.g. in the current or outer select).
+
+ with_sum_func being set for an st_select_lex means that this st_select_lex
+ has aggregate functions directly referenced (i.e. not through a sub-select).
+ */
+ for (sl= thd->lex->current_select;
+ sl && sl != aggr_sl && sl->master_unit()->item;
+ sl= sl->master_unit()->outer_select() )
+ sl->master_unit()->item->with_sum_func= 1;
}
return FALSE;
}
diff --git a/sql/item_timefunc.cc b/sql/item_timefunc.cc
index a259fd90485..d32adde5e64 100644
--- a/sql/item_timefunc.cc
+++ b/sql/item_timefunc.cc
@@ -65,7 +65,7 @@ static bool make_datetime(date_time_format_types format, TIME *ltime,
ltime->hour, ltime->minute, ltime->second);
break;
case TIME_MICROSECOND:
- length= cs->cset->snprintf(cs, buff, length, "%s%02d:%02d:%02d.%06d",
+ length= cs->cset->snprintf(cs, buff, length, "%s%02d:%02d:%02d.%06ld",
ltime->neg ? "-" : "",
ltime->hour, ltime->minute, ltime->second,
ltime->second_part);
@@ -82,7 +82,7 @@ static bool make_datetime(date_time_format_types format, TIME *ltime,
break;
case DATE_TIME_MICROSECOND:
length= cs->cset->snprintf(cs, buff, length,
- "%04d-%02d-%02d %02d:%02d:%02d.%06d",
+ "%04d-%02d-%02d %02d:%02d:%02d.%06ld",
ltime->year, ltime->month, ltime->day,
ltime->hour, ltime->minute, ltime->second,
ltime->second_part);
diff --git a/sql/item_xmlfunc.cc b/sql/item_xmlfunc.cc
index dfa2d2a7325..44a2b690bac 100644
--- a/sql/item_xmlfunc.cc
+++ b/sql/item_xmlfunc.cc
@@ -105,6 +105,7 @@ typedef struct my_xpath_st
String *context_cache; /* last context provider */
String *pxml; /* Parsed XML, an array of MY_XML_NODE */
CHARSET_INFO *cs; /* character set/collation string comparison */
+ int error;
} MY_XPATH;
@@ -913,7 +914,9 @@ static Item *eq_func_reverse(int oper, Item *a, Item *b)
RETURN
The newly created item.
*/
-static Item *create_comparator(MY_XPATH *xpath, int oper, Item *a, Item *b)
+static Item *create_comparator(MY_XPATH *xpath,
+ int oper, MY_XPATH_LEX *context,
+ Item *a, Item *b)
{
if (a->type() != Item::XPATH_NODESET &&
b->type() != Item::XPATH_NODESET)
@@ -923,6 +926,13 @@ static Item *create_comparator(MY_XPATH *xpath, int oper, Item *a, Item *b)
else if (a->type() == Item::XPATH_NODESET &&
b->type() == Item::XPATH_NODESET)
{
+ uint len= context->end - context->beg;
+ set_if_bigger(len, 32);
+ my_printf_error(ER_UNKNOWN_ERROR,
+ "XPATH error: "
+ "comparison of two nodesets is not supported: '%.*s'",
+ MYF(0), len, context->beg);
+
return 0; // TODO: Comparison of two nodesets
}
else
@@ -1430,7 +1440,7 @@ my_xpath_lex_scan(MY_XPATH *xpath,
static int
my_xpath_parse_term(MY_XPATH *xpath, int term)
{
- if (xpath->lasttok.term == term)
+ if (xpath->lasttok.term == term && !xpath->error)
{
xpath->prevtok= xpath->lasttok;
my_xpath_lex_scan(xpath, &xpath->lasttok,
@@ -1558,8 +1568,9 @@ static int my_xpath_parse_AbsoluteLocationPath(MY_XPATH *xpath)
return my_xpath_parse_RelativeLocationPath(xpath);
}
- return my_xpath_parse_term(xpath, MY_XPATH_LEX_EOF) ||
- my_xpath_parse_RelativeLocationPath(xpath);
+ my_xpath_parse_RelativeLocationPath(xpath);
+
+ return (xpath->error == 0);
}
@@ -1596,7 +1607,10 @@ static int my_xpath_parse_RelativeLocationPath(MY_XPATH *xpath)
"*", 1,
xpath->pxml, 1);
if (!my_xpath_parse_Step(xpath))
+ {
+ xpath->error= 1;
return 0;
+ }
}
return 1;
}
@@ -1633,10 +1647,16 @@ my_xpath_parse_AxisSpecifier_NodeTest_opt_Predicate_list(MY_XPATH *xpath)
xpath->context_cache= context_cache;
if(!my_xpath_parse_PredicateExpr(xpath))
+ {
+ xpath->error= 1;
return 0;
+ }
if (!my_xpath_parse_term(xpath, MY_XPATH_LEX_RB))
+ {
+ xpath->error= 1;
return 0;
+ }
xpath->item= nodeset2bool(xpath, xpath->item);
@@ -1893,7 +1913,10 @@ static int my_xpath_parse_UnionExpr(MY_XPATH *xpath)
if (!my_xpath_parse_PathExpr(xpath)
|| xpath->item->type() != Item::XPATH_NODESET)
+ {
+ xpath->error= 1;
return 0;
+ }
xpath->item= new Item_nodeset_func_union(prev, xpath->item, xpath->pxml);
}
return 1;
@@ -1929,6 +1952,7 @@ static int my_xpath_parse_PathExpr(MY_XPATH *xpath)
{
return my_xpath_parse_LocationPath(xpath) ||
my_xpath_parse_FilterExpr_opt_slashes_RelativeLocationPath(xpath);
+
}
@@ -1975,7 +1999,10 @@ static int my_xpath_parse_OrExpr(MY_XPATH *xpath)
{
Item *prev= xpath->item;
if (!my_xpath_parse_AndExpr(xpath))
+ {
return 0;
+ xpath->error= 1;
+ }
xpath->item= new Item_cond_or(nodeset2bool(xpath, prev),
nodeset2bool(xpath, xpath->item));
}
@@ -2003,7 +2030,10 @@ static int my_xpath_parse_AndExpr(MY_XPATH *xpath)
{
Item *prev= xpath->item;
if (!my_xpath_parse_EqualityExpr(xpath))
+ {
+ xpath->error= 1;
return 0;
+ }
xpath->item= new Item_cond_and(nodeset2bool(xpath,prev),
nodeset2bool(xpath,xpath->item));
@@ -2057,17 +2087,26 @@ static int my_xpath_parse_EqualityOperator(MY_XPATH *xpath)
}
static int my_xpath_parse_EqualityExpr(MY_XPATH *xpath)
{
+ MY_XPATH_LEX operator_context;
if (!my_xpath_parse_RelationalExpr(xpath))
return 0;
+
+ operator_context= xpath->lasttok;
while (my_xpath_parse_EqualityOperator(xpath))
{
Item *prev= xpath->item;
int oper= xpath->extra;
if (!my_xpath_parse_RelationalExpr(xpath))
+ {
+ xpath->error= 1;
return 0;
+ }
- if (!(xpath->item= create_comparator(xpath, oper, prev, xpath->item)))
+ if (!(xpath->item= create_comparator(xpath, oper, &operator_context,
+ prev, xpath->item)))
return 0;
+
+ operator_context= xpath->lasttok;
}
return 1;
}
@@ -2109,18 +2148,25 @@ static int my_xpath_parse_RelationalOperator(MY_XPATH *xpath)
}
static int my_xpath_parse_RelationalExpr(MY_XPATH *xpath)
{
+ MY_XPATH_LEX operator_context;
if (!my_xpath_parse_AdditiveExpr(xpath))
return 0;
+ operator_context= xpath->lasttok;
while (my_xpath_parse_RelationalOperator(xpath))
{
Item *prev= xpath->item;
int oper= xpath->extra;
if (!my_xpath_parse_AdditiveExpr(xpath))
+ {
+ xpath->error= 1;
return 0;
+ }
- if (!(xpath->item= create_comparator(xpath, oper, prev, xpath->item)))
+ if (!(xpath->item= create_comparator(xpath, oper, &operator_context,
+ prev, xpath->item)))
return 0;
+ operator_context= xpath->lasttok;
}
return 1;
}
@@ -2153,7 +2199,10 @@ static int my_xpath_parse_AdditiveExpr(MY_XPATH *xpath)
int oper= xpath->prevtok.term;
Item *prev= xpath->item;
if (!my_xpath_parse_MultiplicativeExpr(xpath))
+ {
+ xpath->error= 1;
return 0;
+ }
if (oper == MY_XPATH_LEX_PLUS)
xpath->item= new Item_func_plus(prev, xpath->item);
@@ -2198,7 +2247,10 @@ static int my_xpath_parse_MultiplicativeExpr(MY_XPATH *xpath)
int oper= xpath->prevtok.term;
Item *prev= xpath->item;
if (!my_xpath_parse_UnaryExpr(xpath))
+ {
+ xpath->error= 1;
return 0;
+ }
switch (oper)
{
case MY_XPATH_LEX_ASTERISK:
diff --git a/sql/key.cc b/sql/key.cc
index 69557d971e8..be21bf11c3c 100644
--- a/sql/key.cc
+++ b/sql/key.cc
@@ -359,31 +359,29 @@ void key_unpack(String *to,TABLE *table,uint idx)
/*
- Return 1 if any field in a list is part of key or the key uses a field
- that is automaticly updated (like a timestamp)
+ Check if key uses field that is marked in passed field bitmap.
+
+ SYNOPSIS
+ is_key_used()
+ table TABLE object with which keys and fields are associated.
+ idx Key to be checked.
+ fields Bitmap of fields to be checked.
+
+ NOTE
+ This function uses TABLE::tmp_set bitmap so the caller should care
+ about saving/restoring its state if it also uses this bitmap.
+
+ RETURN VALUE
+ TRUE Key uses field from bitmap
+ FALSE Otherwise
*/
-bool check_if_key_used(TABLE *table, uint idx, List<Item> &fields)
+bool is_key_used(TABLE *table, uint idx, const MY_BITMAP *fields)
{
- List_iterator_fast<Item> f(fields);
- KEY_PART_INFO *key_part,*key_part_end;
- for (key_part=table->key_info[idx].key_part,key_part_end=key_part+
- table->key_info[idx].key_parts ;
- key_part < key_part_end;
- key_part++)
- {
- Item_field *field;
-
- if (key_part->field == table->timestamp_field)
- return 1; // Can't be used for update
-
- f.rewind();
- while ((field=(Item_field*) f++))
- {
- if (key_part->field->eq(field->field))
- return 1;
- }
- }
+ bitmap_clear_all(&table->tmp_set);
+ table->mark_columns_used_by_index_no_reset(idx, &table->tmp_set);
+ if (bitmap_is_overlapping(&table->tmp_set, fields))
+ return 1;
/*
If table handler has primary key as part of the index, check that primary
@@ -391,7 +389,7 @@ bool check_if_key_used(TABLE *table, uint idx, List<Item> &fields)
*/
if (idx != table->s->primary_key && table->s->primary_key < MAX_KEY &&
(table->file->ha_table_flags() & HA_PRIMARY_KEY_IN_READ_INDEX))
- return check_if_key_used(table, table->s->primary_key, fields);
+ return is_key_used(table, table->s->primary_key, fields);
return 0;
}
diff --git a/sql/log.cc b/sql/log.cc
index 9875b16f8e5..a1ed9bd6df3 100644
--- a/sql/log.cc
+++ b/sql/log.cc
@@ -32,10 +32,22 @@
#include <mysql/plugin.h>
+/*
+ Define placement versions of operator new and operator delete since
+ we cannot be sure that the <new> include exists.
+ */
+inline void *operator new(size_t, void *ptr) { return ptr; }
+inline void *operator new[](size_t, void *ptr) { return ptr; }
+inline void operator delete(void*, void*) { /* Do nothing */ }
+inline void operator delete[](void*, void*) { /* Do nothing */ }
+
/* max size of the log message */
#define MAX_LOG_BUFFER_SIZE 1024
#define MAX_USER_HOST_SIZE 512
#define MAX_TIME_SIZE 32
+#define MY_OFF_T_UNDEF (~(my_off_t)0UL)
+
+#define FLAGSTR(V,F) ((V)&(F)?#F" ":"")
LOGGER logger;
@@ -46,13 +58,13 @@ static Muted_query_log_event invisible_commit;
static bool test_if_number(const char *str,
long *res, bool allow_wildcards);
-static int binlog_init();
-static int binlog_close_connection(THD *thd);
-static int binlog_savepoint_set(THD *thd, void *sv);
-static int binlog_savepoint_rollback(THD *thd, void *sv);
-static int binlog_commit(THD *thd, bool all);
-static int binlog_rollback(THD *thd, bool all);
-static int binlog_prepare(THD *thd, bool all);
+static int binlog_init(void *p);
+static int binlog_close_connection(handlerton *hton, THD *thd);
+static int binlog_savepoint_set(handlerton *hton, THD *thd, void *sv);
+static int binlog_savepoint_rollback(handlerton *hton, THD *thd, void *sv);
+static int binlog_commit(handlerton *hton, THD *thd, bool all);
+static int binlog_rollback(handlerton *hton, THD *thd, bool all);
+static int binlog_prepare(handlerton *hton, THD *thd, bool all);
sql_print_message_func sql_print_message_handlers[3] =
{
@@ -70,23 +82,92 @@ char *make_default_log_name(char *buff,const char* log_ext)
}
/*
- This is a POD. Please keep it that way!
-
- Don't add constructors, destructors, or virtual functions.
+ Helper class to store binary log transaction data.
*/
-struct binlog_trx_data {
+class binlog_trx_data {
+public:
+ binlog_trx_data()
+#ifdef HAVE_ROW_BASED_REPLICATION
+ : m_pending(0), before_stmt_pos(MY_OFF_T_UNDEF)
+#endif
+ {
+ trans_log.end_of_file= max_binlog_cache_size;
+ }
+
+ ~binlog_trx_data()
+ {
+#ifdef HAVE_ROW_BASED_REPLICATION
+ DBUG_ASSERT(pending() == NULL);
+#endif
+ close_cached_file(&trans_log);
+ }
+
+ my_off_t position() const {
+ return my_b_tell(&trans_log);
+ }
+
bool empty() const
{
#ifdef HAVE_ROW_BASED_REPLICATION
- return pending == NULL && my_b_tell(&trans_log) == 0;
+ return pending() == NULL && my_b_tell(&trans_log) == 0;
#else
return my_b_tell(&trans_log) == 0;
#endif
}
- binlog_trx_data() {}
+
+ /*
+ Truncate the transaction cache to a certain position. This
+ includes deleting the pending event.
+ */
+ void truncate(my_off_t pos)
+ {
+#ifdef HAVE_ROW_BASED_REPLICATION
+ delete pending();
+ set_pending(0);
+#endif
+ reinit_io_cache(&trans_log, WRITE_CACHE, pos, 0, 0);
+ }
+
+ /*
+ Reset the entire contents of the transaction cache, emptying it
+ completely.
+ */
+ void reset() {
+ if (!empty())
+ truncate(0);
+#ifdef HAVE_ROW_BASED_REPLICATION
+ before_stmt_pos= MY_OFF_T_UNDEF;
+#endif
+ trans_log.end_of_file= max_binlog_cache_size;
+ }
+
+#ifdef HAVE_ROW_BASED_REPLICATION
+ Rows_log_event *pending() const
+ {
+ return m_pending;
+ }
+
+ void set_pending(Rows_log_event *const pending)
+ {
+ m_pending= pending;
+ }
+#endif
+
IO_CACHE trans_log; // The transaction cache
+
+private:
#ifdef HAVE_ROW_BASED_REPLICATION
- Rows_log_event *pending; // The pending binrows event
+ /*
+ Pending binrows event. This event is the event where the rows are
+ currently written.
+ */
+ Rows_log_event *m_pending;
+
+public:
+ /*
+ Binlog position before the start of the current statement.
+ */
+ my_off_t before_stmt_pos;
#endif
};
@@ -1149,6 +1230,69 @@ void Log_to_csv_event_handler::
}
+ /*
+ Save position of binary log transaction cache.
+
+ SYNPOSIS
+ binlog_trans_log_savepos()
+
+ thd The thread to take the binlog data from
+ pos Pointer to variable where the position will be stored
+
+ DESCRIPTION
+
+ Save the current position in the binary log transaction cache into
+ the variable pointed to by 'pos'
+ */
+
+static void
+binlog_trans_log_savepos(THD *thd, my_off_t *pos)
+{
+ DBUG_ENTER("binlog_trans_log_savepos");
+ DBUG_ASSERT(pos != NULL);
+ if (thd->ha_data[binlog_hton->slot] == NULL)
+ thd->binlog_setup_trx_data();
+ binlog_trx_data *const trx_data=
+ (binlog_trx_data*) thd->ha_data[binlog_hton->slot];
+ DBUG_ASSERT(mysql_bin_log.is_open());
+ *pos= trx_data->position();
+ DBUG_PRINT("return", ("*pos=%u", *pos));
+ DBUG_VOID_RETURN;
+}
+
+
+/*
+ Truncate the binary log transaction cache.
+
+ SYNPOSIS
+ binlog_trans_log_truncate()
+
+ thd The thread to take the binlog data from
+ pos Position to truncate to
+
+ DESCRIPTION
+
+ Truncate the binary log to the given position. Will not change
+ anything else.
+
+ */
+static void
+binlog_trans_log_truncate(THD *thd, my_off_t pos)
+{
+ DBUG_ENTER("binlog_trans_log_truncate");
+ DBUG_PRINT("enter", ("pos=%u", pos));
+
+ DBUG_ASSERT(thd->ha_data[binlog_hton->slot] != NULL);
+ /* Only true if binlog_trans_log_savepos() wasn't called before */
+ DBUG_ASSERT(pos != ~(my_off_t) 0);
+
+ binlog_trx_data *const trx_data=
+ (binlog_trx_data*) thd->ha_data[binlog_hton->slot];
+ trx_data->truncate(pos);
+ DBUG_VOID_RETURN;
+}
+
+
/*
this function is mostly a placeholder.
conceptually, binlog initialization (now mostly done in MYSQL_BIN_LOG::open)
@@ -1171,30 +1315,66 @@ int binlog_init(void *p)
return 0;
}
-static int binlog_close_connection(THD *thd)
+static int binlog_close_connection(handlerton *hton, THD *thd)
{
binlog_trx_data *const trx_data=
(binlog_trx_data*) thd->ha_data[binlog_hton->slot];
- IO_CACHE *trans_log= &trx_data->trans_log;
DBUG_ASSERT(mysql_bin_log.is_open() && trx_data->empty());
- close_cached_file(trans_log);
thd->ha_data[binlog_hton->slot]= 0;
+ trx_data->~binlog_trx_data();
my_free((gptr)trx_data, MYF(0));
return 0;
}
+/*
+ End a transaction.
+
+ SYNOPSIS
+ binlog_end_trans()
+
+ thd The thread whose transaction should be ended
+ trx_data Pointer to the transaction data to use
+ end_ev The end event to use, or NULL
+ all True if the entire transaction should be ended, false if
+ only the statement transaction should be ended.
+
+ DESCRIPTION
+
+ End the currently open transaction. The transaction can be either
+ a real transaction (if 'all' is true) or a statement transaction
+ (if 'all' is false).
+
+ If 'end_ev' is NULL, the transaction is a rollback of only
+ transactional tables, so the transaction cache will be truncated
+ to either just before the last opened statement transaction (if
+ 'all' is false), or reset completely (if 'all' is true).
+ */
static int
-binlog_end_trans(THD *thd, binlog_trx_data *trx_data, Log_event *end_ev)
+binlog_end_trans(THD *thd, binlog_trx_data *trx_data,
+ Log_event *end_ev, bool all)
{
DBUG_ENTER("binlog_end_trans");
int error=0;
IO_CACHE *trans_log= &trx_data->trans_log;
+ DBUG_PRINT("enter", ("transaction: %s, end_ev=%p",
+ all ? "all" : "stmt", end_ev));
+ DBUG_PRINT("info", ("thd->options={ %s%s}",
+ FLAGSTR(thd->options, OPTION_NOT_AUTOCOMMIT),
+ FLAGSTR(thd->options, OPTION_BEGIN)));
-
- /* NULL denotes ROLLBACK with nothing to replicate */
+ /*
+ NULL denotes ROLLBACK with nothing to replicate: i.e., rollback of
+ only transactional tables. If the transaction contain changes to
+ any non-transactiona tables, we need write the transaction and log
+ a ROLLBACK last.
+ */
if (end_ev != NULL)
{
/*
+ Doing a commit or a rollback including non-transactional tables,
+ i.e., ending a transaction where we might write the transaction
+ cache to the binary log.
+
We can always end the statement when ending a transaction since
transactions are not allowed inside stored functions. If they
were, we would have to ensure that we're not ending a statement
@@ -1203,42 +1383,59 @@ binlog_end_trans(THD *thd, binlog_trx_data *trx_data, Log_event *end_ev)
#ifdef HAVE_ROW_BASED_REPLICATION
thd->binlog_flush_pending_rows_event(TRUE);
#endif
- error= mysql_bin_log.write(thd, trans_log, end_ev);
+ /*
+ We write the transaction cache to the binary log if either we're
+ committing the entire transaction, or if we are doing an
+ autocommit outside a transaction.
+ */
+ if (all || !(thd->options & (OPTION_BEGIN | OPTION_NOT_AUTOCOMMIT)))
+ {
+ error= mysql_bin_log.write(thd, &trx_data->trans_log, end_ev);
+ trx_data->reset();
+#ifdef HAVE_ROW_BASED_REPLICATION
+ /*
+ We need to step the table map version after writing the
+ transaction cache to disk.
+ */
+ mysql_bin_log.update_table_map_version();
+#endif
+ statistic_increment(binlog_cache_use, &LOCK_status);
+ if (trans_log->disk_writes != 0)
+ {
+ statistic_increment(binlog_cache_disk_use, &LOCK_status);
+ trans_log->disk_writes= 0;
+ }
+ }
}
#ifdef HAVE_ROW_BASED_REPLICATION
else
{
-#ifdef HAVE_ROW_BASED_REPLICATION
- thd->binlog_delete_pending_rows_event();
-#endif
- }
+ /*
+ If rolling back an entire transaction or a single statement not
+ inside a transaction, we reset the transaction cache.
- /*
- We need to step the table map version both after writing the
- entire transaction to the log file and after rolling back the
- transaction.
-
- We need to step the table map version after writing the
- transaction cache to disk. In addition, we need to step the table
- map version on a rollback to ensure that a new table map event is
- generated instead of the one that was written to the thrown-away
- transaction cache.
- */
- mysql_bin_log.update_table_map_version();
-#endif
+ If rolling back a statement in a transaction, we truncate the
+ transaction cache to remove the statement.
- statistic_increment(binlog_cache_use, &LOCK_status);
- if (trans_log->disk_writes != 0)
- {
- statistic_increment(binlog_cache_disk_use, &LOCK_status);
- trans_log->disk_writes= 0;
+ */
+ if (all || !(thd->options & (OPTION_BEGIN | OPTION_NOT_AUTOCOMMIT)))
+ trx_data->reset();
+ else
+ trx_data->truncate(trx_data->before_stmt_pos); // ...statement
+
+ /*
+ We need to step the table map version on a rollback to ensure
+ that a new table map event is generated instead of the one that
+ was written to the thrown-away transaction cache.
+ */
+ mysql_bin_log.update_table_map_version();
}
- reinit_io_cache(trans_log, WRITE_CACHE, (my_off_t) 0, 0, 1); // cannot fail
- trans_log->end_of_file= max_binlog_cache_size;
+#endif
+
DBUG_RETURN(error);
}
-static int binlog_prepare(THD *thd, bool all)
+static int binlog_prepare(handlerton *hton, THD *thd, bool all)
{
/*
do nothing.
@@ -1249,44 +1446,49 @@ static int binlog_prepare(THD *thd, bool all)
return 0;
}
-static int binlog_commit(THD *thd, bool all)
+static int binlog_commit(handlerton *hton, THD *thd, bool all)
{
+ int error= 0;
DBUG_ENTER("binlog_commit");
binlog_trx_data *const trx_data=
(binlog_trx_data*) thd->ha_data[binlog_hton->slot];
IO_CACHE *trans_log= &trx_data->trans_log;
- DBUG_ASSERT(mysql_bin_log.is_open() &&
- (all || !(thd->options & (OPTION_NOT_AUTOCOMMIT | OPTION_BEGIN))));
+ DBUG_ASSERT(mysql_bin_log.is_open());
- if (trx_data->empty())
+ if (all && trx_data->empty())
{
// we're here because trans_log was flushed in MYSQL_BIN_LOG::log()
+ trx_data->reset();
DBUG_RETURN(0);
}
- if (all)
+ if (all)
{
Query_log_event qev(thd, STRING_WITH_LEN("COMMIT"), TRUE, FALSE);
qev.error_code= 0; // see comment in MYSQL_LOG::write(THD, IO_CACHE)
- DBUG_RETURN(binlog_end_trans(thd, trx_data, &qev));
+ int error= binlog_end_trans(thd, trx_data, &qev, all);
+ DBUG_RETURN(error);
}
else
- DBUG_RETURN(binlog_end_trans(thd, trx_data, &invisible_commit));
+ {
+ int error= binlog_end_trans(thd, trx_data, &invisible_commit, all);
+ DBUG_RETURN(error);
+ }
}
-static int binlog_rollback(THD *thd, bool all)
+static int binlog_rollback(handlerton *hton, THD *thd, bool all)
{
DBUG_ENTER("binlog_rollback");
int error=0;
binlog_trx_data *const trx_data=
(binlog_trx_data*) thd->ha_data[binlog_hton->slot];
IO_CACHE *trans_log= &trx_data->trans_log;
- /*
- First assert is guaranteed - see trans_register_ha() call below.
- The second must be true. If it is not, we're registering
- unnecessary, doing extra work. The cause should be found and eliminated
- */
- DBUG_ASSERT(all || !(thd->options & (OPTION_NOT_AUTOCOMMIT | OPTION_BEGIN)));
- DBUG_ASSERT(mysql_bin_log.is_open() && !trx_data->empty());
+ DBUG_ASSERT(mysql_bin_log.is_open());
+
+ if (trx_data->empty()) {
+ trx_data->reset();
+ DBUG_RETURN(0);
+ }
+
/*
Update the binary log with a BEGIN/ROLLBACK block if we have
cached some queries and we updated some non-transactional
@@ -1298,10 +1500,10 @@ static int binlog_rollback(THD *thd, bool all)
{
Query_log_event qev(thd, STRING_WITH_LEN("ROLLBACK"), TRUE, FALSE);
qev.error_code= 0; // see comment in MYSQL_LOG::write(THD, IO_CACHE)
- error= binlog_end_trans(thd, trx_data, &qev);
+ error= binlog_end_trans(thd, trx_data, &qev, all);
}
else
- error= binlog_end_trans(thd, trx_data, 0);
+ error= binlog_end_trans(thd, trx_data, 0, all);
DBUG_RETURN(error);
}
@@ -1326,14 +1528,11 @@ static int binlog_rollback(THD *thd, bool all)
that case there is no need to have it in the binlog).
*/
-static int binlog_savepoint_set(THD *thd, void *sv)
+static int binlog_savepoint_set(handlerton *hton, THD *thd, void *sv)
{
DBUG_ENTER("binlog_savepoint_set");
- binlog_trx_data *const trx_data=
- (binlog_trx_data*) thd->ha_data[binlog_hton->slot];
- DBUG_ASSERT(mysql_bin_log.is_open() && my_b_tell(&trx_data->trans_log));
- *(my_off_t *)sv= my_b_tell(&trx_data->trans_log);
+ binlog_trans_log_savepos(thd, (my_off_t*) sv);
/* Write it to the binary log */
int const error=
@@ -1342,13 +1541,13 @@ static int binlog_savepoint_set(THD *thd, void *sv)
DBUG_RETURN(error);
}
-static int binlog_savepoint_rollback(THD *thd, void *sv)
+static int binlog_savepoint_rollback(handlerton *hton, THD *thd, void *sv)
{
DBUG_ENTER("binlog_savepoint_rollback");
binlog_trx_data *const trx_data=
(binlog_trx_data*) thd->ha_data[binlog_hton->slot];
IO_CACHE *trans_log= &trx_data->trans_log;
- DBUG_ASSERT(mysql_bin_log.is_open() && my_b_tell(trans_log));
+ DBUG_ASSERT(mysql_bin_log.is_open());
/*
Write ROLLBACK TO SAVEPOINT to the binlog cache if we have updated some
@@ -1363,7 +1562,7 @@ static int binlog_savepoint_rollback(THD *thd, void *sv)
thd->query, thd->query_length, TRUE, FALSE);
DBUG_RETURN(error);
}
- reinit_io_cache(trans_log, WRITE_CACHE, *(my_off_t *)sv, 0, 0);
+ binlog_trans_log_truncate(thd, *(my_off_t*)sv);
DBUG_RETURN(0);
}
@@ -1579,17 +1778,18 @@ bool MYSQL_LOG::open(const char *log_name, enum_log_type log_type_arg,
if (log_type == LOG_NORMAL)
{
char *end;
- int len=my_snprintf(buff, sizeof(buff), "%s, Version: %s. "
+ int len=my_snprintf(buff, sizeof(buff), "%s, Version: %s (%s). "
#ifdef EMBEDDED_LIBRARY
- "embedded library\n", my_progname, server_version
+ "embedded library\n",
+ my_progname, server_version, MYSQL_COMPILATION_COMMENT
#elif __NT__
"started with:\nTCP Port: %d, Named Pipe: %s\n",
- my_progname, server_version, mysqld_port,
- mysqld_unix_port
+ my_progname, server_version, MYSQL_COMPILATION_COMMENT,
+ mysqld_port, mysqld_unix_port
#else
"started with:\nTcp port: %d Unix socket: %s\n",
- my_progname, server_version, mysqld_port,
- mysqld_unix_port
+ my_progname, server_version, MYSQL_COMPILATION_COMMENT,
+ mysqld_port, mysqld_unix_port
#endif
);
end= strnmov(buff + len, "Time Id Command Argument\n",
@@ -2493,7 +2693,7 @@ bool MYSQL_BIN_LOG::reset_logs(THD* thd)
thread. If the transaction involved MyISAM tables, it should go
into binlog even on rollback.
*/
- (void) pthread_mutex_lock(&LOCK_thread_count);
+ VOID(pthread_mutex_lock(&LOCK_thread_count));
/* Save variables so that we can reopen the log */
save_name=name;
@@ -2525,7 +2725,7 @@ bool MYSQL_BIN_LOG::reset_logs(THD* thd)
my_free((gptr) save_name, MYF(0));
err:
- (void) pthread_mutex_unlock(&LOCK_thread_count);
+ VOID(pthread_mutex_unlock(&LOCK_thread_count));
pthread_mutex_unlock(&LOCK_index);
pthread_mutex_unlock(&LOCK_log);
DBUG_RETURN(error);
@@ -3091,18 +3291,76 @@ int THD::binlog_setup_trx_data()
ha_data[binlog_hton->slot]= 0;
DBUG_RETURN(1); // Didn't manage to set it up
}
- trx_data->trans_log.end_of_file= max_binlog_cache_size;
+
+ trx_data= new (ha_data[binlog_hton->slot]) binlog_trx_data;
+
DBUG_RETURN(0);
}
+#ifdef HAVE_ROW_BASED_REPLICATION
/*
- Write a table map to the binary log.
+ Function to start a statement and optionally a transaction for the
+ binary log.
+
+ SYNOPSIS
+ binlog_start_trans_and_stmt()
- This function is called from ha_external_lock() after the storage
- engine has registered for the transaction.
+ DESCRIPTION
+
+ This function does three things:
+ - Start a transaction if not in autocommit mode or if a BEGIN
+ statement has been seen.
+
+ - Start a statement transaction to allow us to truncate the binary
+ log.
+
+ - Save the currrent binlog position so that we can roll back the
+ statement by truncating the transaction log.
+
+ We only update the saved position if the old one was undefined,
+ the reason is that there are some cases (e.g., for CREATE-SELECT)
+ where the position is saved twice (e.g., both in
+ select_create::prepare() and THD::binlog_write_table_map()) , but
+ we should use the first. This means that calls to this function
+ can be used to start the statement before the first table map
+ event, to include some extra events.
+ */
+
+void
+THD::binlog_start_trans_and_stmt()
+{
+ DBUG_ENTER("binlog_start_trans_and_stmt");
+ binlog_trx_data *trx_data= (binlog_trx_data*) ha_data[binlog_hton->slot];
+ DBUG_PRINT("enter", ("trx_data=0x%lu", trx_data));
+ if (trx_data)
+ DBUG_PRINT("enter", ("trx_data->before_stmt_pos=%u",
+ trx_data->before_stmt_pos));
+ if (trx_data == NULL ||
+ trx_data->before_stmt_pos == MY_OFF_T_UNDEF)
+ {
+ /*
+ The call to binlog_trans_log_savepos() might create the trx_data
+ structure, if it didn't exist before, so we save the position
+ into an auto variable and then write it into the transaction
+ data for the binary log (i.e., trx_data).
+ */
+ my_off_t pos= 0;
+ binlog_trans_log_savepos(this, &pos);
+ trx_data= (binlog_trx_data*) ha_data[binlog_hton->slot];
+
+ trx_data->before_stmt_pos= pos;
+
+ if (options & (OPTION_NOT_AUTOCOMMIT | OPTION_BEGIN))
+ trans_register_ha(this, TRUE, binlog_hton);
+ trans_register_ha(this, FALSE, binlog_hton);
+ }
+ DBUG_VOID_RETURN;
+}
+
+/*
+ Write a table map to the binary log.
*/
-#ifdef HAVE_ROW_BASED_REPLICATION
int THD::binlog_write_table_map(TABLE *table, bool is_trans)
{
int error;
@@ -3121,10 +3379,8 @@ int THD::binlog_write_table_map(TABLE *table, bool is_trans)
Table_map_log_event
the_event(this, table, table->s->table_map_id, is_trans, flags);
- if (is_trans)
- trans_register_ha(this,
- (options & (OPTION_NOT_AUTOCOMMIT | OPTION_BEGIN)) != 0,
- binlog_hton);
+ if (is_trans && binlog_table_maps == 0)
+ binlog_start_trans_and_stmt();
if ((error= mysql_bin_log.write(&the_event)))
DBUG_RETURN(error);
@@ -3145,7 +3401,7 @@ THD::binlog_get_pending_rows_event() const
(since the trx_data is set up there). In that case, we just return
NULL.
*/
- return trx_data ? trx_data->pending : NULL;
+ return trx_data ? trx_data->pending() : NULL;
}
void
@@ -3158,7 +3414,7 @@ THD::binlog_set_pending_rows_event(Rows_log_event* ev)
(binlog_trx_data*) ha_data[binlog_hton->slot];
DBUG_ASSERT(trx_data);
- trx_data->pending= ev;
+ trx_data->set_pending(ev);
}
@@ -3167,8 +3423,9 @@ THD::binlog_set_pending_rows_event(Rows_log_event* ev)
(either cached binlog if transaction, or disk binlog). Sets a new pending
event.
*/
-int MYSQL_BIN_LOG::
- flush_and_set_pending_rows_event(THD *thd, Rows_log_event* event)
+int
+MYSQL_BIN_LOG::flush_and_set_pending_rows_event(THD *thd,
+ Rows_log_event* event)
{
DBUG_ENTER("MYSQL_BIN_LOG::flush_and_set_pending_rows_event(event)");
DBUG_ASSERT(mysql_bin_log.is_open());
@@ -3181,9 +3438,9 @@ int MYSQL_BIN_LOG::
DBUG_ASSERT(trx_data);
- DBUG_PRINT("info", ("trx_data->pending=%p", trx_data->pending));
+ DBUG_PRINT("info", ("trx_data->pending()=%p", trx_data->pending()));
- if (Rows_log_event* pending= trx_data->pending)
+ if (Rows_log_event* pending= trx_data->pending())
{
IO_CACHE *file= &log_file;
@@ -3333,15 +3590,14 @@ bool MYSQL_BIN_LOG::write(Log_event *event_info)
binlog_trx_data *const trx_data=
(binlog_trx_data*) thd->ha_data[binlog_hton->slot];
IO_CACHE *trans_log= &trx_data->trans_log;
- bool trans_log_in_use= my_b_tell(trans_log) != 0;
- if (event_info->get_cache_stmt() && !trans_log_in_use)
- trans_register_ha(thd,
- (thd->options &
- (OPTION_NOT_AUTOCOMMIT | OPTION_BEGIN)) != 0,
- binlog_hton);
- if (event_info->get_cache_stmt() || trans_log_in_use)
+ my_off_t trans_log_pos= my_b_tell(trans_log);
+ if (event_info->get_cache_stmt() || trans_log_pos != 0)
{
- DBUG_PRINT("info", ("Using trans_log"));
+ DBUG_PRINT("info", ("Using trans_log: cache=%d, trans_log_pos=%u",
+ event_info->get_cache_stmt(),
+ trans_log_pos));
+ if (trans_log_pos == 0)
+ thd->binlog_start_trans_and_stmt();
file= trans_log;
}
/*
@@ -3545,61 +3801,69 @@ bool MYSQL_BIN_LOG::write(THD *thd, IO_CACHE *cache, Log_event *commit_event)
uint length;
/*
- Log "BEGIN" at the beginning of the transaction.
- which may contain more than 1 SQL statement.
- */
- if (thd->options & (OPTION_NOT_AUTOCOMMIT | OPTION_BEGIN))
+ We only bother to write to the binary log if there is anything
+ to write.
+ */
+ if (my_b_tell(cache) > 0)
{
- Query_log_event qinfo(thd, STRING_WITH_LEN("BEGIN"), TRUE, FALSE);
/*
- Imagine this is rollback due to net timeout, after all statements of
- the transaction succeeded. Then we want a zero-error code in BEGIN.
- In other words, if there was a really serious error code it's already
- in the statement's events, there is no need to put it also in this
- internally generated event, and as this event is generated late it
- would lead to false alarms.
- This is safer than thd->clear_error() against kills at shutdown.
+ Log "BEGIN" at the beginning of the transaction.
+ which may contain more than 1 SQL statement.
*/
- qinfo.error_code= 0;
- /*
- Now this Query_log_event has artificial log_pos 0. It must be adjusted
- to reflect the real position in the log. Not doing it would confuse the
- slave: it would prevent this one from knowing where he is in the
- master's binlog, which would result in wrong positions being shown to
- the user, MASTER_POS_WAIT undue waiting etc.
- */
- if (qinfo.write(&log_file))
- goto err;
- }
- /* Read from the file used to cache the queries .*/
- if (reinit_io_cache(cache, READ_CACHE, 0, 0, 0))
- goto err;
- length=my_b_bytes_in_cache(cache);
- DBUG_EXECUTE_IF("half_binlogged_transaction", length-=100;);
- do
- {
- /* Write data to the binary log file */
- if (my_b_write(&log_file, cache->read_pos, length))
- goto err;
- cache->read_pos=cache->read_end; // Mark buffer used up
- DBUG_EXECUTE_IF("half_binlogged_transaction", goto DBUG_skip_commit;);
- } while ((length=my_b_fill(cache)));
+ if (thd->options & (OPTION_NOT_AUTOCOMMIT | OPTION_BEGIN))
+ {
+ Query_log_event qinfo(thd, STRING_WITH_LEN("BEGIN"), TRUE, FALSE);
+ /*
+ Imagine this is rollback due to net timeout, after all statements of
+ the transaction succeeded. Then we want a zero-error code in BEGIN.
+ In other words, if there was a really serious error code it's already
+ in the statement's events, there is no need to put it also in this
+ internally generated event, and as this event is generated late it
+ would lead to false alarms.
+ This is safer than thd->clear_error() against kills at shutdown.
+ */
+ qinfo.error_code= 0;
+ /*
+ Now this Query_log_event has artificial log_pos 0. It must be adjusted
+ to reflect the real position in the log. Not doing it would confuse the
+ slave: it would prevent this one from knowing where he is in the
+ master's binlog, which would result in wrong positions being shown to
+ the user, MASTER_POS_WAIT undue waiting etc.
+ */
+ if (qinfo.write(&log_file))
+ goto err;
+ }
+ /* Read from the file used to cache the queries .*/
+ if (reinit_io_cache(cache, READ_CACHE, 0, 0, 0))
+ goto err;
+ length=my_b_bytes_in_cache(cache);
+ DBUG_EXECUTE_IF("half_binlogged_transaction", length-=100;);
+ do
+ {
+ /* Write data to the binary log file */
+ if (my_b_write(&log_file, cache->read_pos, length))
+ goto err;
+ cache->read_pos=cache->read_end; // Mark buffer used up
+ DBUG_EXECUTE_IF("half_binlogged_transaction", goto DBUG_skip_commit;);
+ } while ((length=my_b_fill(cache)));
- if (commit_event->write(&log_file))
- goto err;
+ if (commit_event && commit_event->write(&log_file))
+ goto err;
#ifndef DBUG_OFF
-DBUG_skip_commit:
+ DBUG_skip_commit:
#endif
- if (flush_and_sync())
- goto err;
- DBUG_EXECUTE_IF("half_binlogged_transaction", abort(););
- if (cache->error) // Error on read
- {
- sql_print_error(ER(ER_ERROR_ON_READ), cache->file_name, errno);
- write_error=1; // Don't give more errors
- goto err;
+ if (flush_and_sync())
+ goto err;
+ DBUG_EXECUTE_IF("half_binlogged_transaction", abort(););
+ if (cache->error) // Error on read
+ {
+ sql_print_error(ER(ER_ERROR_ON_READ), cache->file_name, errno);
+ write_error=1; // Don't give more errors
+ goto err;
+ }
+ signal_update();
}
- signal_update();
+
/*
if commit_event is Xid_log_event, increase the number of
prepared_xids (it's decreasd in ::unlog()). Binlog cannot be rotated
@@ -3608,7 +3872,7 @@ DBUG_skip_commit:
If the commit_event is not Xid_log_event (then it's a Query_log_event)
rotate binlog, if necessary.
*/
- if (commit_event->get_type_code() == XID_EVENT)
+ if (commit_event && commit_event->get_type_code() == XID_EVENT)
{
pthread_mutex_lock(&LOCK_prep_xids);
prepared_xids++;
@@ -4618,12 +4882,17 @@ int TC_LOG_BINLOG::log(THD *thd, my_xid xid)
Xid_log_event xle(thd, xid);
binlog_trx_data *trx_data=
(binlog_trx_data*) thd->ha_data[binlog_hton->slot];
- DBUG_RETURN(!binlog_end_trans(thd, trx_data, &xle)); // invert return value
+ /*
+ We always commit the entire transaction when writing an XID. Also
+ note that the return value is inverted.
+ */
+ DBUG_RETURN(!binlog_end_trans(thd, trx_data, &xle, TRUE));
}
void TC_LOG_BINLOG::unlog(ulong cookie, my_xid xid)
{
pthread_mutex_lock(&LOCK_prep_xids);
+ DBUG_ASSERT(prepared_xids > 0);
if (--prepared_xids == 0)
pthread_cond_signal(&COND_prep_xids);
pthread_mutex_unlock(&LOCK_prep_xids);
@@ -4678,7 +4947,7 @@ err1:
}
struct st_mysql_storage_engine binlog_storage_engine=
-{ MYSQL_HANDLERTON_INTERFACE_VERSION, binlog_hton };
+{ MYSQL_HANDLERTON_INTERFACE_VERSION };
mysql_declare_plugin(binlog)
{
@@ -4687,6 +4956,7 @@ mysql_declare_plugin(binlog)
"binlog",
"MySQL AB",
"This is a pseudo storage engine to represent the binlog in a transaction",
+ PLUGIN_LICENSE_GPL,
binlog_init, /* Plugin Init */
NULL, /* Plugin Deinit */
0x0100 /* 1.0 */,
diff --git a/sql/log.h b/sql/log.h
index 2b33f70392a..8f75601f02b 100644
--- a/sql/log.h
+++ b/sql/log.h
@@ -177,7 +177,7 @@ public:
pthread_mutex_t LOCK_log;
char *name;
char log_file_name[FN_REFLEN];
- char time_buff[20], db[NAME_BYTE_LEN + 1];
+ char time_buff[20], db[NAME_LEN + 1];
bool write_error, inited;
IO_CACHE log_file;
enum_log_type log_type;
diff --git a/sql/log_event.cc b/sql/log_event.cc
index faff2cae48e..4a6346bf57c 100644
--- a/sql/log_event.cc
+++ b/sql/log_event.cc
@@ -33,31 +33,110 @@
#define log_cs &my_charset_latin1
/*
+ Cache that will automatically be written to a dedicated file on
+ destruction.
+
+ DESCRIPTION
+
+ */
+class Write_on_release_cache
+{
+public:
+ enum flag
+ {
+ FLUSH_F
+ };
+
+ typedef unsigned short flag_set;
+
+ /*
+ Constructor.
+
+ SYNOPSIS
+ Write_on_release_cache
+ cache Pointer to cache to use
+ file File to write cache to upon destruction
+ flags Flags for the cache
+
+ DESCRIPTION
+
+ Class used to guarantee copy of cache to file before exiting the
+ current block. On successful copy of the cache, the cache will
+ be reinited as a WRITE_CACHE.
+
+ Currently, a pointer to the cache is provided in the
+ constructor, but it would be possible to create a subclass
+ holding the IO_CACHE itself.
+ */
+ Write_on_release_cache(IO_CACHE *cache, FILE *file, flag_set flags = 0)
+ : m_cache(cache), m_file(file), m_flags(flags)
+ {
+ reinit_io_cache(m_cache, WRITE_CACHE, 0L, FALSE, TRUE);
+ }
+
+ ~Write_on_release_cache()
+ {
+ if (!my_b_copy_to_file(m_cache, m_file))
+ reinit_io_cache(m_cache, WRITE_CACHE, 0L, FALSE, TRUE);
+ if (m_flags | FLUSH_F)
+ fflush(m_file);
+ }
+
+ /*
+ Return a pointer to the internal IO_CACHE.
+
+ SYNOPSIS
+ operator&()
+
+ DESCRIPTION
+ Function to return a pointer to the internal, so that the object
+ can be treated as a IO_CACHE and used with the my_b_* IO_CACHE
+ functions
+
+ RETURN VALUE
+ A pointer to the internal IO_CACHE.
+ */
+ IO_CACHE *operator&()
+ {
+ return m_cache;
+ }
+
+private:
+ // Hidden, to prevent usage.
+ Write_on_release_cache(Write_on_release_cache const&);
+
+ IO_CACHE *m_cache;
+ FILE *m_file;
+ flag_set m_flags;
+};
+
+
+/*
pretty_print_str()
*/
#ifdef MYSQL_CLIENT
-static void pretty_print_str(FILE* file, char* str, int len)
+static void pretty_print_str(IO_CACHE* cache, char* str, int len)
{
char* end = str + len;
- fputc('\'', file);
+ my_b_printf(cache, "\'");
while (str < end)
{
char c;
switch ((c=*str++)) {
- case '\n': fprintf(file, "\\n"); break;
- case '\r': fprintf(file, "\\r"); break;
- case '\\': fprintf(file, "\\\\"); break;
- case '\b': fprintf(file, "\\b"); break;
- case '\t': fprintf(file, "\\t"); break;
- case '\'': fprintf(file, "\\'"); break;
- case 0 : fprintf(file, "\\0"); break;
+ case '\n': my_b_printf(cache, "\\n"); break;
+ case '\r': my_b_printf(cache, "\\r"); break;
+ case '\\': my_b_printf(cache, "\\\\"); break;
+ case '\b': my_b_printf(cache, "\\b"); break;
+ case '\t': my_b_printf(cache, "\\t"); break;
+ case '\'': my_b_printf(cache, "\\'"); break;
+ case 0 : my_b_printf(cache, "\\0"); break;
default:
- fputc(c, file);
+ my_b_printf(cache, "%c", c);
break;
}
}
- fputc('\'', file);
+ my_b_printf(cache, "\'");
}
#endif /* MYSQL_CLIENT */
@@ -294,14 +373,15 @@ append_query_string(CHARSET_INFO *csinfo,
*/
#ifdef MYSQL_CLIENT
-static void print_set_option(FILE* file, uint32 bits_changed, uint32 option,
- uint32 flags, const char* name, bool* need_comma)
+static void print_set_option(IO_CACHE* file, uint32 bits_changed,
+ uint32 option, uint32 flags, const char* name,
+ bool* need_comma)
{
if (bits_changed & option)
{
if (*need_comma)
- fprintf(file,", ");
- fprintf(file,"%s=%d", name, test(flags & option));
+ my_b_printf(file,", ");
+ my_b_printf(file,"%s=%d", name, test(flags & option));
*need_comma= 1;
}
}
@@ -960,20 +1040,23 @@ Log_event* Log_event::read_log_event(const char* buf, uint event_len,
Log_event::print_header()
*/
-void Log_event::print_header(FILE* file, PRINT_EVENT_INFO* print_event_info)
+void Log_event::print_header(IO_CACHE* file,
+ PRINT_EVENT_INFO* print_event_info,
+ bool is_more __attribute__((unused)))
{
char llbuff[22];
my_off_t hexdump_from= print_event_info->hexdump_from;
+ DBUG_ENTER("Log_event::print_header");
- fputc('#', file);
+ my_b_printf(file, "#");
print_timestamp(file);
- fprintf(file, " server id %d end_log_pos %s ", server_id,
- llstr(log_pos,llbuff));
+ my_b_printf(file, " server id %d end_log_pos %s ", server_id,
+ llstr(log_pos,llbuff));
/* mysqlbinlog --hexdump */
if (print_event_info->hexdump_from)
{
- fprintf(file, "\n");
+ my_b_printf(file, "\n");
uchar *ptr= (uchar*)temp_buf;
my_off_t size=
uint4korr(ptr + EVENT_LEN_OFFSET) - LOG_EVENT_MINIMAL_HEADER_LEN;
@@ -986,15 +1069,21 @@ void Log_event::print_header(FILE* file, PRINT_EVENT_INFO* print_event_info)
/* Pretty-print event common header if header is exactly 19 bytes */
if (print_event_info->common_header_len == LOG_EVENT_MINIMAL_HEADER_LEN)
{
- fprintf(file, "# Position Timestamp Type Master ID "
- "Size Master Pos Flags \n");
- fprintf(file, "# %8.8lx %02x %02x %02x %02x %02x "
- "%02x %02x %02x %02x %02x %02x %02x %02x "
- "%02x %02x %02x %02x %02x %02x\n",
- (unsigned long) hexdump_from,
- ptr[0], ptr[1], ptr[2], ptr[3], ptr[4], ptr[5], ptr[6],
- ptr[7], ptr[8], ptr[9], ptr[10], ptr[11], ptr[12], ptr[13],
- ptr[14], ptr[15], ptr[16], ptr[17], ptr[18]);
+ char emit_buf[256]; // Enough for storing one line
+ my_b_printf(file, "# Position Timestamp Type Master ID "
+ "Size Master Pos Flags \n");
+ int const bytes_written=
+ my_snprintf(emit_buf, sizeof(emit_buf),
+ "# %8.8lx %02x %02x %02x %02x %02x "
+ "%02x %02x %02x %02x %02x %02x %02x %02x "
+ "%02x %02x %02x %02x %02x %02x\n",
+ (unsigned long) hexdump_from,
+ ptr[0], ptr[1], ptr[2], ptr[3], ptr[4], ptr[5], ptr[6],
+ ptr[7], ptr[8], ptr[9], ptr[10], ptr[11], ptr[12], ptr[13],
+ ptr[14], ptr[15], ptr[16], ptr[17], ptr[18]);
+ DBUG_ASSERT(bytes_written >= 0);
+ DBUG_ASSERT(static_cast<my_size_t>(bytes_written) < sizeof(emit_buf));
+ my_b_write(file, (byte*) emit_buf, bytes_written);
ptr += LOG_EVENT_MINIMAL_HEADER_LEN;
hexdump_from += LOG_EVENT_MINIMAL_HEADER_LEN;
}
@@ -1011,9 +1100,21 @@ void Log_event::print_header(FILE* file, PRINT_EVENT_INFO* print_event_info)
if (i % 16 == 15)
{
- fprintf(file, "# %8.8lx %-48.48s |%16s|\n",
- (unsigned long) (hexdump_from + (i & 0xfffffff0)),
- hex_string, char_string);
+ /*
+ my_b_printf() does not support full printf() formats, so we
+ have to do it this way.
+
+ TODO: Rewrite my_b_printf() to support full printf() syntax.
+ */
+ char emit_buf[256];
+ int const bytes_written=
+ my_snprintf(emit_buf, sizeof(emit_buf),
+ "# %8.8lx %-48.48s |%16s|\n",
+ (unsigned long) (hexdump_from + (i & 0xfffffff0)),
+ hex_string, char_string);
+ DBUG_ASSERT(bytes_written >= 0);
+ DBUG_ASSERT(static_cast<my_size_t>(bytes_written) < sizeof(emit_buf));
+ my_b_write(file, (byte*) emit_buf, bytes_written);
hex_string[0]= 0;
char_string[0]= 0;
c= char_string;
@@ -1025,28 +1126,52 @@ void Log_event::print_header(FILE* file, PRINT_EVENT_INFO* print_event_info)
/* Non-full last line */
if (hex_string[0])
- fprintf(file, "# %8.8lx %-48.48s |%s|\n# ",
- (unsigned long) (hexdump_from + (i & 0xfffffff0)),
- hex_string, char_string);
+ {
+ char emit_buf[256];
+ int const bytes_written=
+ my_snprintf(emit_buf, sizeof(emit_buf),
+ "# %8.8lx %-48.48s |%s|\n# ",
+ (unsigned long) (hexdump_from + (i & 0xfffffff0)),
+ hex_string, char_string);
+ DBUG_ASSERT(bytes_written >= 0);
+ DBUG_ASSERT(static_cast<my_size_t>(bytes_written) < sizeof(emit_buf));
+ my_b_write(file, (byte*) emit_buf, bytes_written);
+ }
}
+ DBUG_VOID_RETURN;
}
-void Log_event::print_base64(FILE* file, PRINT_EVENT_INFO* print_event_info)
+void Log_event::print_base64(IO_CACHE* file,
+ PRINT_EVENT_INFO* print_event_info,
+ bool more)
{
- uchar *ptr= (uchar*)temp_buf;
+ const uchar *ptr= (const uchar *)temp_buf;
my_off_t size= uint4korr(ptr + EVENT_LEN_OFFSET);
- char *tmp_str=
- (char *) my_malloc(base64_needed_encoded_length(size), MYF(MY_WME));
+ DBUG_ENTER("Log_event::print_base64");
+
+ size_t const tmp_str_sz= base64_needed_encoded_length(size);
+ char *const tmp_str= (char *) my_malloc(tmp_str_sz, MYF(MY_WME));
if (!tmp_str) {
fprintf(stderr, "\nError: Out of memory. "
"Could not print correct binlog event.\n");
- return;
+ DBUG_VOID_RETURN;
}
- int res= base64_encode(ptr, size, tmp_str);
- fprintf(file, "\nBINLOG '\n%s\n';\n", tmp_str);
+
+ int const res= base64_encode(ptr, size, tmp_str);
+ DBUG_ASSERT(res == 0);
+
+ if (my_b_tell(file) == 0)
+ my_b_printf(file, "\nBINLOG '\n");
+
+ my_b_printf(file, "%s\n", tmp_str);
+
+ if (!more)
+ my_b_printf(file, "';\n");
+
my_free(tmp_str, MYF(0));
+ DBUG_VOID_RETURN;
}
@@ -1054,9 +1179,10 @@ void Log_event::print_base64(FILE* file, PRINT_EVENT_INFO* print_event_info)
Log_event::print_timestamp()
*/
-void Log_event::print_timestamp(FILE* file, time_t* ts)
+void Log_event::print_timestamp(IO_CACHE* file, time_t* ts)
{
struct tm *res;
+ DBUG_ENTER("Log_event::print_timestamp");
if (!ts)
ts = &when;
#ifdef MYSQL_SERVER // This is always false
@@ -1066,13 +1192,14 @@ void Log_event::print_timestamp(FILE* file, time_t* ts)
res=localtime(ts);
#endif
- fprintf(file,"%02d%02d%02d %2d:%02d:%02d",
- res->tm_year % 100,
- res->tm_mon+1,
- res->tm_mday,
- res->tm_hour,
- res->tm_min,
- res->tm_sec);
+ my_b_printf(file,"%02d%02d%02d %2d:%02d:%02d",
+ res->tm_year % 100,
+ res->tm_mon+1,
+ res->tm_mday,
+ res->tm_hour,
+ res->tm_min,
+ res->tm_sec);
+ DBUG_VOID_RETURN;
}
#endif /* MYSQL_CLIENT */
@@ -1544,7 +1671,7 @@ Query_log_event::Query_log_event(const char* buf, uint event_len,
*/
#ifdef MYSQL_CLIENT
-void Query_log_event::print_query_header(FILE* file,
+void Query_log_event::print_query_header(IO_CACHE* file,
PRINT_EVENT_INFO* print_event_info)
{
// TODO: print the catalog ??
@@ -1554,9 +1681,10 @@ void Query_log_event::print_query_header(FILE* file,
if (!print_event_info->short_form)
{
- print_header(file, print_event_info);
- fprintf(file, "\t%s\tthread_id=%lu\texec_time=%lu\terror_code=%d\n",
- get_type_str(), (ulong) thread_id, (ulong) exec_time, error_code);
+ print_header(file, print_event_info, FALSE);
+ my_b_printf(file, "\t%s\tthread_id=%lu\texec_time=%lu\terror_code=%d\n",
+ get_type_str(), (ulong) thread_id, (ulong) exec_time,
+ error_code);
}
if (!(flags & LOG_EVENT_SUPPRESS_USE_F) && db)
@@ -1564,15 +1692,15 @@ void Query_log_event::print_query_header(FILE* file,
if (different_db= memcmp(print_event_info->db, db, db_len + 1))
memcpy(print_event_info->db, db, db_len + 1);
if (db[0] && different_db)
- fprintf(file, "use %s;\n", db);
+ my_b_printf(file, "use %s;\n", db);
}
end=int10_to_str((long) when, strmov(buff,"SET TIMESTAMP="),10);
*end++=';';
*end++='\n';
- my_fwrite(file, (byte*) buff, (uint) (end-buff),MYF(MY_NABP | MY_WME));
+ my_b_write(file, (byte*) buff, (uint) (end-buff));
if (flags & LOG_EVENT_THREAD_SPECIFIC_F)
- fprintf(file,"SET @@session.pseudo_thread_id=%lu;\n",(ulong)thread_id);
+ my_b_printf(file,"SET @@session.pseudo_thread_id=%lu;\n",(ulong)thread_id);
/*
If flags2_inited==0, this is an event from 3.23 or 4.0; nothing to
@@ -1594,14 +1722,14 @@ void Query_log_event::print_query_header(FILE* file,
if (unlikely(tmp)) /* some bits have changed */
{
bool need_comma= 0;
- fprintf(file, "SET ");
+ my_b_printf(file, "SET ");
print_set_option(file, tmp, OPTION_NO_FOREIGN_KEY_CHECKS, ~flags2,
"@@session.foreign_key_checks", &need_comma);
print_set_option(file, tmp, OPTION_AUTO_IS_NULL, flags2,
"@@session.sql_auto_is_null", &need_comma);
print_set_option(file, tmp, OPTION_RELAXED_UNIQUE_CHECKS, ~flags2,
"@@session.unique_checks", &need_comma);
- fprintf(file,";\n");
+ my_b_printf(file,";\n");
print_event_info->flags2= flags2;
}
}
@@ -1629,14 +1757,14 @@ void Query_log_event::print_query_header(FILE* file,
}
if (unlikely(print_event_info->sql_mode != sql_mode))
{
- fprintf(file,"SET @@session.sql_mode=%lu;\n",(ulong)sql_mode);
+ my_b_printf(file,"SET @@session.sql_mode=%lu;\n",(ulong)sql_mode);
print_event_info->sql_mode= sql_mode;
}
}
if (print_event_info->auto_increment_increment != auto_increment_increment ||
print_event_info->auto_increment_offset != auto_increment_offset)
{
- fprintf(file,"SET @@session.auto_increment_increment=%lu, @@session.auto_increment_offset=%lu;\n",
+ my_b_printf(file,"SET @@session.auto_increment_increment=%lu, @@session.auto_increment_offset=%lu;\n",
auto_increment_increment,auto_increment_offset);
print_event_info->auto_increment_increment= auto_increment_increment;
print_event_info->auto_increment_offset= auto_increment_offset;
@@ -1656,16 +1784,17 @@ void Query_log_event::print_query_header(FILE* file,
CHARSET_INFO *cs_info= get_charset(uint2korr(charset), MYF(MY_WME));
if (cs_info)
{
- fprintf(file, "/*!\\C %s */;\n", cs_info->csname); /* for mysql client */
+ /* for mysql client */
+ my_b_printf(file, "/*!\\C %s */;\n", cs_info->csname);
}
- fprintf(file,"SET "
- "@@session.character_set_client=%d,"
- "@@session.collation_connection=%d,"
- "@@session.collation_server=%d"
- ";\n",
- uint2korr(charset),
- uint2korr(charset+2),
- uint2korr(charset+4));
+ my_b_printf(file,"SET "
+ "@@session.character_set_client=%d,"
+ "@@session.collation_connection=%d,"
+ "@@session.collation_server=%d"
+ ";\n",
+ uint2korr(charset),
+ uint2korr(charset+2),
+ uint2korr(charset+4));
memcpy(print_event_info->charset, charset, 6);
}
}
@@ -1673,7 +1802,7 @@ void Query_log_event::print_query_header(FILE* file,
{
if (bcmp(print_event_info->time_zone_str, time_zone_str, time_zone_len+1))
{
- fprintf(file,"SET @@session.time_zone='%s';\n", time_zone_str);
+ my_b_printf(file,"SET @@session.time_zone='%s';\n", time_zone_str);
memcpy(print_event_info->time_zone_str, time_zone_str, time_zone_len+1);
}
}
@@ -1682,9 +1811,11 @@ void Query_log_event::print_query_header(FILE* file,
void Query_log_event::print(FILE* file, PRINT_EVENT_INFO* print_event_info)
{
- print_query_header(file, print_event_info);
- my_fwrite(file, (byte*) query, q_len, MYF(MY_NABP | MY_WME));
- fputs(";\n", file);
+ Write_on_release_cache cache(&print_event_info->head_cache, file);
+
+ print_query_header(&cache, print_event_info);
+ my_b_write(&cache, (byte*) query, q_len);
+ my_b_printf(&cache, ";\n");
}
#endif /* MYSQL_CLIENT */
@@ -2014,18 +2145,23 @@ void Start_log_event_v3::pack_info(Protocol *protocol)
#ifdef MYSQL_CLIENT
void Start_log_event_v3::print(FILE* file, PRINT_EVENT_INFO* print_event_info)
{
+ DBUG_ENTER("Start_log_event_v3::print");
+
+ Write_on_release_cache cache(&print_event_info->head_cache, file,
+ Write_on_release_cache::FLUSH_F);
+
if (!print_event_info->short_form)
{
- print_header(file, print_event_info);
- fprintf(file, "\tStart: binlog v %d, server v %s created ", binlog_version,
- server_version);
- print_timestamp(file);
+ print_header(&cache, print_event_info, FALSE);
+ my_b_printf(&cache, "\tStart: binlog v %d, server v %s created ",
+ binlog_version, server_version);
+ print_timestamp(&cache);
if (created)
- fprintf(file," at startup");
- fputc('\n', file);
+ my_b_printf(&cache," at startup");
+ my_b_printf(&cache, "\n");
if (flags & LOG_EVENT_BINLOG_IN_USE_F)
- fprintf(file, "# Warning: this binlog was not closed properly. "
- "Most probably mysqld crashed writing it.\n");
+ my_b_printf(&cache, "# Warning: this binlog was not closed properly. "
+ "Most probably mysqld crashed writing it.\n");
}
if (!artificial_event && created)
{
@@ -2036,12 +2172,12 @@ void Start_log_event_v3::print(FILE* file, PRINT_EVENT_INFO* print_event_info)
and rollback unfinished transaction.
Probably this can be done with RESET CONNECTION (syntax to be defined).
*/
- fprintf(file,"RESET CONNECTION;\n");
+ my_b_printf(&cache,"RESET CONNECTION;\n");
#else
- fprintf(file,"ROLLBACK;\n");
+ my_b_printf(&cache,"ROLLBACK;\n");
#endif
}
- fflush(file);
+ DBUG_VOID_RETURN;
}
#endif /* MYSQL_CLIENT */
@@ -2381,19 +2517,19 @@ int Format_description_log_event::exec_event(struct st_relay_log_info* rli)
if (server_id == (uint32) ::server_id)
{
/*
- Do not modify rli->group_master_log_pos, as this event did not exist on
- the master. That is, just update the *relay log* coordinates; this is
- done by passing log_pos=0 to inc_group_relay_log_pos, like we do in
- Stop_log_event::exec_event().
- If in a transaction, don't touch group_* coordinates.
- */
- if (thd->options & OPTION_BEGIN)
- rli->inc_event_relay_log_pos();
- else
- {
- rli->inc_group_relay_log_pos(0);
- flush_relay_log_info(rli);
- }
+ We only increase the relay log position if we are skipping
+ events and do not touch any group_* variables, nor flush the
+ relay log info. If there is a crash, we will have to re-skip
+ the events again, but that is a minor issue.
+
+ If we do not skip stepping the group log position (and the
+ server id was changed when restarting the server), it might well
+ be that we start executing at a position that is invalid, e.g.,
+ at a Rows_log_event or a Query_log_event preceeded by a
+ Intvar_log_event instead of starting at a Table_map_log_event or
+ the Intvar_log_event respectively.
+ */
+ rli->inc_event_relay_log_pos();
DBUG_RETURN(0);
}
@@ -2765,15 +2901,17 @@ void Load_log_event::print(FILE* file, PRINT_EVENT_INFO* print_event_info)
}
-void Load_log_event::print(FILE* file, PRINT_EVENT_INFO* print_event_info,
+void Load_log_event::print(FILE* file_arg, PRINT_EVENT_INFO* print_event_info,
bool commented)
{
+ Write_on_release_cache cache(&print_event_info->head_cache, file_arg);
+
DBUG_ENTER("Load_log_event::print");
if (!print_event_info->short_form)
{
- print_header(file, print_event_info);
- fprintf(file, "\tQuery\tthread_id=%ld\texec_time=%ld\n",
- thread_id, exec_time);
+ print_header(&cache, print_event_info, FALSE);
+ my_b_printf(&cache, "\tQuery\tthread_id=%ld\texec_time=%ld\n",
+ thread_id, exec_time);
}
bool different_db= 1;
@@ -2791,65 +2929,65 @@ void Load_log_event::print(FILE* file, PRINT_EVENT_INFO* print_event_info,
}
if (db && db[0] && different_db)
- fprintf(file, "%suse %s;\n",
+ my_b_printf(&cache, "%suse %s;\n",
commented ? "# " : "",
db);
if (flags & LOG_EVENT_THREAD_SPECIFIC_F)
- fprintf(file,"%sSET @@session.pseudo_thread_id=%lu;\n",
+ my_b_printf(&cache,"%sSET @@session.pseudo_thread_id=%lu;\n",
commented ? "# " : "", (ulong)thread_id);
- fprintf(file, "%sLOAD DATA ",
+ my_b_printf(&cache, "%sLOAD DATA ",
commented ? "# " : "");
if (check_fname_outside_temp_buf())
- fprintf(file, "LOCAL ");
- fprintf(file, "INFILE '%-*s' ", fname_len, fname);
+ my_b_printf(&cache, "LOCAL ");
+ my_b_printf(&cache, "INFILE '%-*s' ", fname_len, fname);
if (sql_ex.opt_flags & REPLACE_FLAG)
- fprintf(file," REPLACE ");
+ my_b_printf(&cache," REPLACE ");
else if (sql_ex.opt_flags & IGNORE_FLAG)
- fprintf(file," IGNORE ");
+ my_b_printf(&cache," IGNORE ");
- fprintf(file, "INTO TABLE `%s`", table_name);
- fprintf(file, " FIELDS TERMINATED BY ");
- pretty_print_str(file, sql_ex.field_term, sql_ex.field_term_len);
+ my_b_printf(&cache, "INTO TABLE `%s`", table_name);
+ my_b_printf(&cache, " FIELDS TERMINATED BY ");
+ pretty_print_str(&cache, sql_ex.field_term, sql_ex.field_term_len);
if (sql_ex.opt_flags & OPT_ENCLOSED_FLAG)
- fprintf(file," OPTIONALLY ");
- fprintf(file, " ENCLOSED BY ");
- pretty_print_str(file, sql_ex.enclosed, sql_ex.enclosed_len);
+ my_b_printf(&cache," OPTIONALLY ");
+ my_b_printf(&cache, " ENCLOSED BY ");
+ pretty_print_str(&cache, sql_ex.enclosed, sql_ex.enclosed_len);
- fprintf(file, " ESCAPED BY ");
- pretty_print_str(file, sql_ex.escaped, sql_ex.escaped_len);
+ my_b_printf(&cache, " ESCAPED BY ");
+ pretty_print_str(&cache, sql_ex.escaped, sql_ex.escaped_len);
- fprintf(file," LINES TERMINATED BY ");
- pretty_print_str(file, sql_ex.line_term, sql_ex.line_term_len);
+ my_b_printf(&cache," LINES TERMINATED BY ");
+ pretty_print_str(&cache, sql_ex.line_term, sql_ex.line_term_len);
if (sql_ex.line_start)
{
- fprintf(file," STARTING BY ");
- pretty_print_str(file, sql_ex.line_start, sql_ex.line_start_len);
+ my_b_printf(&cache," STARTING BY ");
+ pretty_print_str(&cache, sql_ex.line_start, sql_ex.line_start_len);
}
if ((long) skip_lines > 0)
- fprintf(file, " IGNORE %ld LINES", (long) skip_lines);
+ my_b_printf(&cache, " IGNORE %ld LINES", (long) skip_lines);
if (num_fields)
{
uint i;
const char* field = fields;
- fprintf(file, " (");
+ my_b_printf(&cache, " (");
for (i = 0; i < num_fields; i++)
{
if (i)
- fputc(',', file);
- fprintf(file, field);
+ my_b_printf(&cache, ",");
+ my_b_printf(&cache, field);
field += field_lens[i] + 1;
}
- fputc(')', file);
+ my_b_printf(&cache, ")");
}
- fprintf(file, ";\n");
+ my_b_printf(&cache, ";\n");
DBUG_VOID_RETURN;
}
#endif /* MYSQL_CLIENT */
@@ -3185,17 +3323,16 @@ void Rotate_log_event::pack_info(Protocol *protocol)
void Rotate_log_event::print(FILE* file, PRINT_EVENT_INFO* print_event_info)
{
char buf[22];
+ Write_on_release_cache cache(&print_event_info->head_cache, file,
+ Write_on_release_cache::FLUSH_F);
if (print_event_info->short_form)
return;
- print_header(file, print_event_info);
- fprintf(file, "\tRotate to ");
+ print_header(&cache, print_event_info, FALSE);
+ my_b_printf(&cache, "\tRotate to ");
if (new_log_ident)
- my_fwrite(file, (byte*) new_log_ident, (uint)ident_len,
- MYF(MY_NABP | MY_WME));
- fprintf(file, " pos: %s", llstr(pos, buf));
- fputc('\n', file);
- fflush(file);
+ my_b_write(&cache, (byte*) new_log_ident, (uint)ident_len);
+ my_b_printf(&cache, " pos: %s\n", llstr(pos, buf));
}
#endif /* MYSQL_CLIENT */
@@ -3407,14 +3544,16 @@ void Intvar_log_event::print(FILE* file, PRINT_EVENT_INFO* print_event_info)
char llbuff[22];
const char *msg;
LINT_INIT(msg);
+ Write_on_release_cache cache(&print_event_info->head_cache, file,
+ Write_on_release_cache::FLUSH_F);
if (!print_event_info->short_form)
{
- print_header(file, print_event_info);
- fprintf(file, "\tIntvar\n");
+ print_header(&cache, print_event_info, FALSE);
+ my_b_printf(&cache, "\tIntvar\n");
}
- fprintf(file, "SET ");
+ my_b_printf(&cache, "SET ");
switch (type) {
case LAST_INSERT_ID_EVENT:
msg="LAST_INSERT_ID";
@@ -3427,8 +3566,7 @@ void Intvar_log_event::print(FILE* file, PRINT_EVENT_INFO* print_event_info)
msg="INVALID_INT";
break;
}
- fprintf(file, "%s=%s;\n", msg, llstr(val,llbuff));
- fflush(file);
+ my_b_printf(&cache, "%s=%s;\n", msg, llstr(val,llbuff));
}
#endif
@@ -3497,15 +3635,17 @@ bool Rand_log_event::write(IO_CACHE* file)
#ifdef MYSQL_CLIENT
void Rand_log_event::print(FILE* file, PRINT_EVENT_INFO* print_event_info)
{
+ Write_on_release_cache cache(&print_event_info->head_cache, file,
+ Write_on_release_cache::FLUSH_F);
+
char llbuff[22],llbuff2[22];
if (!print_event_info->short_form)
{
- print_header(file, print_event_info);
- fprintf(file, "\tRand\n");
+ print_header(&cache, print_event_info, FALSE);
+ my_b_printf(&cache, "\tRand\n");
}
- fprintf(file, "SET @@RAND_SEED1=%s, @@RAND_SEED2=%s;\n",
- llstr(seed1, llbuff),llstr(seed2, llbuff2));
- fflush(file);
+ my_b_printf(&cache, "SET @@RAND_SEED1=%s, @@RAND_SEED2=%s;\n",
+ llstr(seed1, llbuff),llstr(seed2, llbuff2));
}
#endif /* MYSQL_CLIENT */
@@ -3567,16 +3707,18 @@ bool Xid_log_event::write(IO_CACHE* file)
#ifdef MYSQL_CLIENT
void Xid_log_event::print(FILE* file, PRINT_EVENT_INFO* print_event_info)
{
+ Write_on_release_cache cache(&print_event_info->head_cache, file,
+ Write_on_release_cache::FLUSH_F);
+
if (!print_event_info->short_form)
{
char buf[64];
longlong10_to_str(xid, buf, 10);
- print_header(file, print_event_info);
- fprintf(file, "\tXid = %s\n", buf);
- fflush(file);
+ print_header(&cache, print_event_info, FALSE);
+ my_b_printf(&cache, "\tXid = %s\n", buf);
}
- fprintf(file, "COMMIT;\n");
+ my_b_printf(&cache, "COMMIT;\n");
}
#endif /* MYSQL_CLIENT */
@@ -3766,19 +3908,22 @@ bool User_var_log_event::write(IO_CACHE* file)
#ifdef MYSQL_CLIENT
void User_var_log_event::print(FILE* file, PRINT_EVENT_INFO* print_event_info)
{
+ Write_on_release_cache cache(&print_event_info->head_cache, file,
+ Write_on_release_cache::FLUSH_F);
+
if (!print_event_info->short_form)
{
- print_header(file, print_event_info);
- fprintf(file, "\tUser_var\n");
+ print_header(&cache, print_event_info, FALSE);
+ my_b_printf(&cache, "\tUser_var\n");
}
- fprintf(file, "SET @`");
- my_fwrite(file, (byte*) name, (uint) (name_len), MYF(MY_NABP | MY_WME));
- fprintf(file, "`");
+ my_b_printf(&cache, "SET @`");
+ my_b_write(&cache, (byte*) name, (uint) (name_len));
+ my_b_printf(&cache, "`");
if (is_null)
{
- fprintf(file, ":=NULL;\n");
+ my_b_printf(&cache, ":=NULL;\n");
}
else
{
@@ -3786,12 +3931,12 @@ void User_var_log_event::print(FILE* file, PRINT_EVENT_INFO* print_event_info)
case REAL_RESULT:
double real_val;
float8get(real_val, val);
- fprintf(file, ":=%.14g;\n", real_val);
+ my_b_printf(&cache, ":=%.14g;\n", real_val);
break;
case INT_RESULT:
char int_buf[22];
longlong10_to_str(uint8korr(val), int_buf, -10);
- fprintf(file, ":=%s;\n", int_buf);
+ my_b_printf(&cache, ":=%s;\n", int_buf);
break;
case DECIMAL_RESULT:
{
@@ -3807,7 +3952,7 @@ void User_var_log_event::print(FILE* file, PRINT_EVENT_INFO* print_event_info)
bin2decimal(val+2, &dec, precision, scale);
decimal2string(&dec, str_buf, &str_len, 0, 0, 0);
str_buf[str_len]= 0;
- fprintf(file, ":=%s;\n",str_buf);
+ my_b_printf(&cache, ":=%s;\n",str_buf);
break;
}
case STRING_RESULT:
@@ -3843,9 +3988,9 @@ void User_var_log_event::print(FILE* file, PRINT_EVENT_INFO* print_event_info)
Generate an unusable command (=> syntax error) is probably the best
thing we can do here.
*/
- fprintf(file, ":=???;\n");
+ my_b_printf(&cache, ":=???;\n");
else
- fprintf(file, ":=_%s %s COLLATE `%s`;\n", cs->csname, hex_str, cs->name);
+ my_b_printf(&cache, ":=_%s %s COLLATE `%s`;\n", cs->csname, hex_str, cs->name);
my_afree(hex_str);
}
break;
@@ -3855,7 +4000,6 @@ void User_var_log_event::print(FILE* file, PRINT_EVENT_INFO* print_event_info)
return;
}
}
- fflush(file);
}
#endif
@@ -3939,13 +4083,14 @@ int User_var_log_event::exec_event(struct st_relay_log_info* rli)
#ifdef HAVE_REPLICATION
#ifdef MYSQL_CLIENT
-void Unknown_log_event::print(FILE* file, PRINT_EVENT_INFO* print_event_info)
+void Unknown_log_event::print(FILE* file_arg, PRINT_EVENT_INFO* print_event_info)
{
+ Write_on_release_cache cache(&print_event_info->head_cache, file_arg);
+
if (print_event_info->short_form)
return;
- print_header(file, print_event_info);
- fputc('\n', file);
- fprintf(file, "# %s", "Unknown event\n");
+ print_header(&cache, print_event_info, FALSE);
+ my_b_printf(&cache, "\n# %s", "Unknown event\n");
}
#endif
@@ -4012,12 +4157,13 @@ Slave_log_event::~Slave_log_event()
#ifdef MYSQL_CLIENT
void Slave_log_event::print(FILE* file, PRINT_EVENT_INFO* print_event_info)
{
+ Write_on_release_cache cache(&print_event_info->head_cache, file);
+
char llbuff[22];
if (print_event_info->short_form)
return;
- print_header(file, print_event_info);
- fputc('\n', file);
- fprintf(file, "\
+ print_header(&cache, print_event_info, FALSE);
+ my_b_printf(&cache, "\n\
Slave: master_host: '%s' master_port: %d master_log: '%s' master_pos: %s\n",
master_host, master_port, master_log, llstr(master_pos, llbuff));
}
@@ -4097,12 +4243,14 @@ int Slave_log_event::exec_event(struct st_relay_log_info* rli)
#ifdef MYSQL_CLIENT
void Stop_log_event::print(FILE* file, PRINT_EVENT_INFO* print_event_info)
{
+ Write_on_release_cache cache(&print_event_info->head_cache, file,
+ Write_on_release_cache::FLUSH_F);
+
if (print_event_info->short_form)
return;
- print_header(file, print_event_info);
- fprintf(file, "\tStop\n");
- fflush(file);
+ print_header(&cache, print_event_info, FALSE);
+ my_b_printf(&cache, "\tStop\n");
}
#endif /* MYSQL_CLIENT */
@@ -4277,6 +4425,8 @@ Create_file_log_event::Create_file_log_event(const char* buf, uint len,
void Create_file_log_event::print(FILE* file, PRINT_EVENT_INFO* print_event_info,
bool enable_local)
{
+ Write_on_release_cache cache(&print_event_info->head_cache, file);
+
if (print_event_info->short_form)
{
if (enable_local && check_fname_outside_temp_buf())
@@ -4292,10 +4442,10 @@ void Create_file_log_event::print(FILE* file, PRINT_EVENT_INFO* print_event_info
That one is for "file_id: etc" below: in mysqlbinlog we want the #, in
SHOW BINLOG EVENTS we don't.
*/
- fprintf(file, "#");
+ my_b_printf(&cache, "#");
}
- fprintf(file, " file_id: %d block_len: %d\n", file_id, block_len);
+ my_b_printf(&cache, " file_id: %d block_len: %d\n", file_id, block_len);
}
@@ -4465,12 +4615,13 @@ bool Append_block_log_event::write(IO_CACHE* file)
void Append_block_log_event::print(FILE* file,
PRINT_EVENT_INFO* print_event_info)
{
+ Write_on_release_cache cache(&print_event_info->head_cache, file);
+
if (print_event_info->short_form)
return;
- print_header(file, print_event_info);
- fputc('\n', file);
- fprintf(file, "#%s: file_id: %d block_len: %d\n",
- get_type_str(), file_id, block_len);
+ print_header(&cache, print_event_info, FALSE);
+ my_b_printf(&cache, "\n#%s: file_id: %d block_len: %d\n",
+ get_type_str(), file_id, block_len);
}
#endif /* MYSQL_CLIENT */
@@ -4608,11 +4759,12 @@ bool Delete_file_log_event::write(IO_CACHE* file)
void Delete_file_log_event::print(FILE* file,
PRINT_EVENT_INFO* print_event_info)
{
+ Write_on_release_cache cache(&print_event_info->head_cache, file);
+
if (print_event_info->short_form)
return;
- print_header(file, print_event_info);
- fputc('\n', file);
- fprintf(file, "#Delete_file: file_id=%u\n", file_id);
+ print_header(&cache, print_event_info, FALSE);
+ my_b_printf(&cache, "\n#Delete_file: file_id=%u\n", file_id);
}
#endif /* MYSQL_CLIENT */
@@ -4703,12 +4855,13 @@ bool Execute_load_log_event::write(IO_CACHE* file)
void Execute_load_log_event::print(FILE* file,
PRINT_EVENT_INFO* print_event_info)
{
+ Write_on_release_cache cache(&print_event_info->head_cache, file);
+
if (print_event_info->short_form)
return;
- print_header(file, print_event_info);
- fputc('\n', file);
- fprintf(file, "#Exec_load: file_id=%d\n",
- file_id);
+ print_header(&cache, print_event_info, FALSE);
+ my_b_printf(&cache, "\n#Exec_load: file_id=%d\n",
+ file_id);
}
#endif
@@ -4925,29 +5078,30 @@ void Execute_load_query_log_event::print(FILE* file,
PRINT_EVENT_INFO* print_event_info,
const char *local_fname)
{
- print_query_header(file, print_event_info);
+ Write_on_release_cache cache(&print_event_info->head_cache, file);
+
+ print_query_header(&cache, print_event_info);
if (local_fname)
{
- my_fwrite(file, (byte*) query, fn_pos_start, MYF(MY_NABP | MY_WME));
- fprintf(file, " LOCAL INFILE \'");
- fprintf(file, local_fname);
- fprintf(file, "\'");
+ my_b_write(&cache, (byte*) query, fn_pos_start);
+ my_b_printf(&cache, " LOCAL INFILE \'");
+ my_b_printf(&cache, local_fname);
+ my_b_printf(&cache, "\'");
if (dup_handling == LOAD_DUP_REPLACE)
- fprintf(file, " REPLACE");
- fprintf(file, " INTO");
- my_fwrite(file, (byte*) query + fn_pos_end, q_len-fn_pos_end,
- MYF(MY_NABP | MY_WME));
- fprintf(file, ";\n");
+ my_b_printf(&cache, " REPLACE");
+ my_b_printf(&cache, " INTO");
+ my_b_write(&cache, (byte*) query + fn_pos_end, q_len-fn_pos_end);
+ my_b_printf(&cache, ";\n");
}
else
{
- my_fwrite(file, (byte*) query, q_len, MYF(MY_NABP | MY_WME));
- fprintf(file, ";\n");
+ my_b_write(&cache, (byte*) query, q_len);
+ my_b_printf(&cache, ";\n");
}
if (!print_event_info->short_form)
- fprintf(file, "# file_id: %d \n", file_id);
+ my_b_printf(&cache, "# file_id: %d \n", file_id);
}
#endif
@@ -5797,6 +5951,31 @@ void Rows_log_event::pack_info(Protocol *protocol)
}
#endif
+#ifdef MYSQL_CLIENT
+void Rows_log_event::print_helper(FILE *file,
+ PRINT_EVENT_INFO *print_event_info,
+ char const *const name)
+{
+ IO_CACHE *const head= &print_event_info->head_cache;
+ IO_CACHE *const body= &print_event_info->body_cache;
+ if (!print_event_info->short_form)
+ {
+ bool const last_stmt_event= get_flags(STMT_END_F);
+ print_header(head, print_event_info, !last_stmt_event);
+ my_b_printf(head, "\t%s: table id %lu", name, m_table_id);
+ print_base64(body, print_event_info, !last_stmt_event);
+ }
+
+ if (get_flags(STMT_END_F))
+ {
+ my_b_copy_to_file(head, file);
+ my_b_copy_to_file(body, file);
+ reinit_io_cache(head, WRITE_CACHE, 0, FALSE, TRUE);
+ reinit_io_cache(body, WRITE_CACHE, 0, FALSE, TRUE);
+ }
+}
+#endif
+
/**************************************************************************
Table_map_log_event member functions and support functions
**************************************************************************/
@@ -6148,10 +6327,11 @@ void Table_map_log_event::print(FILE *file, PRINT_EVENT_INFO *print_event_info)
{
if (!print_event_info->short_form)
{
- print_header(file, print_event_info);
- fprintf(file, "\tTable_map: `%s`.`%s` mapped to number %lu\n",
- m_dbnam, m_tblnam, m_table_id);
- print_base64(file, print_event_info);
+ print_header(&print_event_info->head_cache, print_event_info, TRUE);
+ my_b_printf(&print_event_info->head_cache,
+ "\tTable_map: `%s`.`%s` mapped to number %lu\n",
+ m_dbnam, m_tblnam, m_table_id);
+ print_base64(&print_event_info->body_cache, print_event_info, TRUE);
}
}
#endif
@@ -6513,12 +6693,7 @@ int Write_rows_log_event::do_exec_row(TABLE *table)
#ifdef MYSQL_CLIENT
void Write_rows_log_event::print(FILE *file, PRINT_EVENT_INFO* print_event_info)
{
- if (!print_event_info->short_form)
- {
- print_header(file, print_event_info);
- fprintf(file, "\tWrite_rows: table id %lu", m_table_id);
- print_base64(file, print_event_info);
- }
+ Rows_log_event::print_helper(file, print_event_info, "Write_rows");
}
#endif
@@ -6846,12 +7021,7 @@ int Delete_rows_log_event::do_exec_row(TABLE *table)
void Delete_rows_log_event::print(FILE *file,
PRINT_EVENT_INFO* print_event_info)
{
- if (!print_event_info->short_form)
- {
- print_header(file, print_event_info);
- fprintf(file, "\tDelete_rows: table id %lu", m_table_id);
- print_base64(file, print_event_info);
- }
+ Rows_log_event::print_helper(file, print_event_info, "Delete_rows");
}
#endif
@@ -7017,12 +7187,7 @@ int Update_rows_log_event::do_exec_row(TABLE *table)
void Update_rows_log_event::print(FILE *file,
PRINT_EVENT_INFO* print_event_info)
{
- if (!print_event_info->short_form)
- {
- print_header(file, print_event_info);
- fprintf(file, "\tUpdate_rows: table id %lu", m_table_id);
- print_base64(file, print_event_info);
- }
+ Rows_log_event::print_helper(file, print_event_info, "Update_rows");
}
#endif
diff --git a/sql/log_event.h b/sql/log_event.h
index 801a83dcc97..81ce2f18b4d 100644
--- a/sql/log_event.h
+++ b/sql/log_event.h
@@ -519,14 +519,30 @@ typedef struct st_print_event_info
bzero(db, sizeof(db));
bzero(charset, sizeof(charset));
bzero(time_zone_str, sizeof(time_zone_str));
+ uint const flags = MYF(MY_WME | MY_NABP);
+ init_io_cache(&head_cache, -1, 0, WRITE_CACHE, 0L, FALSE, flags);
+ init_io_cache(&body_cache, -1, 0, WRITE_CACHE, 0L, FALSE, flags);
}
+ ~st_print_event_info() {
+ end_io_cache(&head_cache);
+ end_io_cache(&body_cache);
+ }
+
+
/* Settings on how to print the events */
bool short_form;
bool base64_output;
my_off_t hexdump_from;
uint8 common_header_len;
+ /*
+ These two caches are used by the row-based replication events to
+ collect the header information and the main body of the events
+ making up a statement.
+ */
+ IO_CACHE head_cache;
+ IO_CACHE body_cache;
} PRINT_EVENT_INFO;
#endif
@@ -637,9 +653,11 @@ public:
const Format_description_log_event *description_event);
/* print*() functions are used by mysqlbinlog */
virtual void print(FILE* file, PRINT_EVENT_INFO* print_event_info) = 0;
- void print_timestamp(FILE* file, time_t *ts = 0);
- void print_header(FILE* file, PRINT_EVENT_INFO* print_event_info);
- void print_base64(FILE* file, PRINT_EVENT_INFO* print_event_info);
+ void print_timestamp(IO_CACHE* file, time_t *ts = 0);
+ void print_header(IO_CACHE* file, PRINT_EVENT_INFO* print_event_info,
+ bool is_more);
+ void print_base64(IO_CACHE* file, PRINT_EVENT_INFO* print_event_info,
+ bool is_more);
#endif
static void *operator new(size_t size)
@@ -804,7 +822,7 @@ public:
uint32 q_len_arg);
#endif /* HAVE_REPLICATION */
#else
- void print_query_header(FILE* file, PRINT_EVENT_INFO* print_event_info);
+ void print_query_header(IO_CACHE* file, PRINT_EVENT_INFO* print_event_info);
void print(FILE* file, PRINT_EVENT_INFO* print_event_info);
#endif
@@ -1864,6 +1882,10 @@ protected:
Log_event_type event_type,
const Format_description_log_event *description_event);
+#ifdef MYSQL_CLIENT
+ void print_helper(FILE *, PRINT_EVENT_INFO *, char const *const name);
+#endif
+
#ifndef MYSQL_CLIENT
virtual int do_add_row_data(byte *data, my_size_t length);
#endif
diff --git a/sql/mysql_priv.h b/sql/mysql_priv.h
index c6f5ff9c3fe..339ca9d965a 100644
--- a/sql/mysql_priv.h
+++ b/sql/mysql_priv.h
@@ -140,7 +140,18 @@ MY_LOCALE *my_locale_by_name(const char *name);
#define MAX_ACCEPT_RETRY 10 // Test accept this many times
#define MAX_FIELDS_BEFORE_HASH 32
#define USER_VARS_HASH_SIZE 16
-#define STACK_MIN_SIZE 8192 // Abort if less stack during eval.
+
+/*
+ Value of 9236 discovered through binary search 2006-09-26 on Ubuntu Dapper
+ Drake, libc6 2.3.6-0ubuntu2, Linux kernel 2.6.15-27-686, on x86. (Added
+ 100 bytes as reasonable buffer against growth and other environments'
+ requirements.)
+
+ Feel free to raise this by the smallest amount you can to get the
+ "execution_constants" test to pass.
+ */
+#define STACK_MIN_SIZE 9336 // Abort if less stack during eval.
+
#define STACK_MIN_SIZE_FOR_OPEN 1024*80
#define STACK_BUFF_ALLOC 256 // For stack overrun checks
#ifndef MYSQLD_NET_RETRY_COUNT
@@ -458,7 +469,8 @@ enum enum_parsing_place
NO_MATTER,
IN_HAVING,
SELECT_LIST,
- IN_WHERE
+ IN_WHERE,
+ IN_ON
};
struct st_table;
@@ -588,7 +600,7 @@ void get_default_definer(THD *thd, LEX_USER *definer);
LEX_USER *create_default_definer(THD *thd);
LEX_USER *create_definer(THD *thd, LEX_STRING *user_name, LEX_STRING *host_name);
LEX_USER *get_current_user(THD *thd, LEX_USER *user);
-bool check_string_length(CHARSET_INFO *cs, LEX_STRING *str,
+bool check_string_length(LEX_STRING *str,
const char *err_msg, uint max_length);
enum enum_mysql_completiontype {
@@ -1417,7 +1429,7 @@ void key_restore(byte *to_record, byte *from_key, KEY *key_info,
uint key_length);
bool key_cmp_if_same(TABLE *form,const byte *key,uint index,uint key_length);
void key_unpack(String *to,TABLE *form,uint index);
-bool check_if_key_used(TABLE *table, uint idx, List<Item> &fields);
+bool is_key_used(TABLE *table, uint idx, const MY_BITMAP *fields);
int key_cmp(KEY_PART_INFO *key_part, const byte *key, uint key_length);
int key_rec_cmp(void *key_info, byte *a, byte *b);
@@ -1427,10 +1439,12 @@ void sql_perror(const char *message);
int vprint_msg_to_log(enum loglevel level, const char *format, va_list args);
-void sql_print_error(const char *format, ...);
-void sql_print_warning(const char *format, ...);
-void sql_print_information(const char *format, ...);
-typedef void (*sql_print_message_func)(const char *format, ...);
+void sql_print_error(const char *format, ...) ATTRIBUTE_FORMAT(printf, 1, 2);
+void sql_print_warning(const char *format, ...) ATTRIBUTE_FORMAT(printf, 1, 2);
+void sql_print_information(const char *format, ...)
+ ATTRIBUTE_FORMAT(printf, 1, 2);
+typedef void (*sql_print_message_func)(const char *format, ...)
+ ATTRIBUTE_FORMAT(printf, 1, 2);
extern sql_print_message_func sql_print_message_handlers[];
/* type of the log table */
@@ -1637,19 +1651,7 @@ extern SHOW_COMP_OPTION have_ndbcluster;
extern SHOW_COMP_OPTION have_partition_db;
extern SHOW_COMP_OPTION have_merge_db;
-#ifdef WITH_CSV_STORAGE_ENGINE
-extern handlerton *tina_hton;
-#endif
-#ifdef WITH_NDBCLUSTER_STORAGE_ENGINE
-extern handlerton *ndbcluster_hton;
-#endif
-#ifdef WITH_PARTITION_STORAGE_ENGINE
extern handlerton *partition_hton;
-#endif
-#ifdef WITH_MYISAMMRG_STORAGE_ENGINE
-extern handlerton *myisammrg_hton;
-#endif
-
extern handlerton *myisam_hton;
extern handlerton *heap_hton;
diff --git a/sql/mysqld.cc b/sql/mysqld.cc
index a3844ea8fc0..6674dd87757 100644
--- a/sql/mysqld.cc
+++ b/sql/mysqld.cc
@@ -354,6 +354,14 @@ my_bool opt_safe_user_create = 0, opt_no_mix_types = 0;
my_bool opt_show_slave_auth_info, opt_sql_bin_update = 0;
my_bool opt_log_slave_updates= 0;
my_bool opt_innodb;
+
+/*
+ Legacy global handlerton. These will be removed (please do not add more).
+*/
+handlerton *heap_hton;
+handlerton *myisam_hton;
+handlerton *partition_hton;
+
#ifdef WITH_INNOBASE_STORAGE_ENGINE
extern ulong innobase_fast_shutdown;
extern ulong innobase_large_page_size;
@@ -1091,7 +1099,7 @@ pthread_handler_t kill_server_thread(void *arg __attribute__((unused)))
extern "C" sig_handler print_signal_warning(int sig)
{
if (global_system_variables.log_warnings)
- sql_print_warning("Got signal %d from thread %d", sig,my_thread_id());
+ sql_print_warning("Got signal %d from thread %ld", sig,my_thread_id());
#ifdef DONT_REMEMBER_SIGNAL
my_sigset(sig,print_signal_warning); /* int. thread system calls */
#endif
@@ -1601,8 +1609,8 @@ static void network_init(void)
if (strlen(mysqld_unix_port) > (sizeof(UNIXaddr.sun_path) - 1))
{
- sql_print_error("The socket file path is too long (> %d): %s",
- sizeof(UNIXaddr.sun_path) - 1, mysqld_unix_port);
+ sql_print_error("The socket file path is too long (> %lu): %s",
+ sizeof(UNIXaddr.sun_path) - 1, mysqld_unix_port);
unireg_abort(1);
}
if ((unix_sock= socket(AF_UNIX, SOCK_STREAM, 0)) < 0)
@@ -2953,7 +2961,7 @@ static void openssl_lock(int mode, openssl_lock_t *lock, const char *file,
}
if (err)
{
- sql_print_error("Fatal: can't %s OpenSSL %s lock", what);
+ sql_print_error("Fatal: can't %s OpenSSL lock", what);
abort();
}
}
@@ -7656,14 +7664,15 @@ get_one_option(int optid, const struct my_option *opt __attribute__((unused)),
exit(1);
}
switch (method-1) {
- case 0:
- method_conv= MI_STATS_METHOD_NULLS_NOT_EQUAL;
+ case 2:
+ method_conv= MI_STATS_METHOD_IGNORE_NULLS;
break;
case 1:
method_conv= MI_STATS_METHOD_NULLS_EQUAL;
break;
- case 2:
- method_conv= MI_STATS_METHOD_IGNORE_NULLS;
+ case 0:
+ default:
+ method_conv= MI_STATS_METHOD_NULLS_NOT_EQUAL;
break;
}
global_system_variables.myisam_stats_method= method_conv;
diff --git a/sql/opt_range.cc b/sql/opt_range.cc
index d8922489d5f..0abb37b5345 100644
--- a/sql/opt_range.cc
+++ b/sql/opt_range.cc
@@ -4913,9 +4913,17 @@ static SEL_TREE *get_func_mm_tree(RANGE_OPT_PARAM *param, Item_func *cond_func,
{
Item_func_in *func=(Item_func_in*) cond_func;
+ /*
+ Array for IN() is constructed when all values have the same result
+ type. Tree won't be built for values with different result types,
+ so we check it here to avoid unnecessary work.
+ */
+ if (!func->array)
+ break;
+
if (inv)
{
- if (func->array && func->cmp_type != ROW_RESULT)
+ if (func->array->result_type() != ROW_RESULT)
{
/*
We get here for conditions in form "t.key NOT IN (c1, c2, ...)",
@@ -6946,8 +6954,9 @@ void SEL_ARG::test_use_count(SEL_ARG *root)
ulong count=count_key_part_usage(root,pos->next_key_part);
if (count > pos->next_key_part->use_count)
{
- sql_print_information("Use_count: Wrong count for key at 0x%lx, %lu should be %lu",
- pos,pos->next_key_part->use_count,count);
+ sql_print_information("Use_count: Wrong count for key at 0x%lx, %lu "
+ "should be %lu", (long unsigned int)pos,
+ pos->next_key_part->use_count, count);
return;
}
pos->next_key_part->test_use_count(root);
@@ -6955,7 +6964,7 @@ void SEL_ARG::test_use_count(SEL_ARG *root)
}
if (e_count != elements)
sql_print_warning("Wrong use count: %u (should be %u) for tree at 0x%lx",
- e_count, elements, (gptr) this);
+ e_count, elements, (long unsigned int) this);
}
#endif
@@ -7526,42 +7535,42 @@ static bool null_part_in_key(KEY_PART *key_part, const char *key, uint length)
}
-bool QUICK_SELECT_I::check_if_keys_used(List<Item> *fields)
+bool QUICK_SELECT_I::is_keys_used(const MY_BITMAP *fields)
{
- return check_if_key_used(head, index, *fields);
+ return is_key_used(head, index, fields);
}
-bool QUICK_INDEX_MERGE_SELECT::check_if_keys_used(List<Item> *fields)
+bool QUICK_INDEX_MERGE_SELECT::is_keys_used(const MY_BITMAP *fields)
{
QUICK_RANGE_SELECT *quick;
List_iterator_fast<QUICK_RANGE_SELECT> it(quick_selects);
while ((quick= it++))
{
- if (check_if_key_used(head, quick->index, *fields))
+ if (is_key_used(head, quick->index, fields))
return 1;
}
return 0;
}
-bool QUICK_ROR_INTERSECT_SELECT::check_if_keys_used(List<Item> *fields)
+bool QUICK_ROR_INTERSECT_SELECT::is_keys_used(const MY_BITMAP *fields)
{
QUICK_RANGE_SELECT *quick;
List_iterator_fast<QUICK_RANGE_SELECT> it(quick_selects);
while ((quick= it++))
{
- if (check_if_key_used(head, quick->index, *fields))
+ if (is_key_used(head, quick->index, fields))
return 1;
}
return 0;
}
-bool QUICK_ROR_UNION_SELECT::check_if_keys_used(List<Item> *fields)
+bool QUICK_ROR_UNION_SELECT::is_keys_used(const MY_BITMAP *fields)
{
QUICK_SELECT_I *quick;
List_iterator_fast<QUICK_SELECT_I> it(quick_selects);
while ((quick= it++))
{
- if (quick->check_if_keys_used(fields))
+ if (quick->is_keys_used(fields))
return 1;
}
return 0;
diff --git a/sql/opt_range.h b/sql/opt_range.h
index 6f26f9f782c..6099608f7cd 100644
--- a/sql/opt_range.h
+++ b/sql/opt_range.h
@@ -224,10 +224,9 @@ public:
virtual void add_info_string(String *str) {};
/*
Return 1 if any index used by this quick select
- a) uses field that is listed in passed field list or
- b) is automatically updated (like a timestamp)
+ uses field which is marked in passed bitmap.
*/
- virtual bool check_if_keys_used(List<Item> *fields);
+ virtual bool is_keys_used(const MY_BITMAP *fields);
/*
rowid of last row retrieved by this quick select. This is used only when
@@ -425,7 +424,7 @@ public:
int get_type() { return QS_TYPE_INDEX_MERGE; }
void add_keys_and_lengths(String *key_names, String *used_lengths);
void add_info_string(String *str);
- bool check_if_keys_used(List<Item> *fields);
+ bool is_keys_used(const MY_BITMAP *fields);
#ifndef DBUG_OFF
void dbug_dump(int indent, bool verbose);
#endif
@@ -484,7 +483,7 @@ public:
int get_type() { return QS_TYPE_ROR_INTERSECT; }
void add_keys_and_lengths(String *key_names, String *used_lengths);
void add_info_string(String *str);
- bool check_if_keys_used(List<Item> *fields);
+ bool is_keys_used(const MY_BITMAP *fields);
#ifndef DBUG_OFF
void dbug_dump(int indent, bool verbose);
#endif
@@ -538,7 +537,7 @@ public:
int get_type() { return QS_TYPE_ROR_UNION; }
void add_keys_and_lengths(String *key_names, String *used_lengths);
void add_info_string(String *str);
- bool check_if_keys_used(List<Item> *fields);
+ bool is_keys_used(const MY_BITMAP *fields);
#ifndef DBUG_OFF
void dbug_dump(int indent, bool verbose);
#endif
diff --git a/sql/partition_info.cc b/sql/partition_info.cc
index 2a06a649eca..a20fca9404b 100644
--- a/sql/partition_info.cc
+++ b/sql/partition_info.cc
@@ -443,11 +443,9 @@ bool partition_info::check_engine_mix(handlerton **engine_array, uint no_parts)
DBUG_RETURN(TRUE);
}
} while (++i < no_parts);
- if (engine_array[0] == myisammrg_hton ||
- engine_array[0] == tina_hton)
+ if (engine_array[0]->flags & HTON_NO_PARTITION)
{
- my_error(ER_PARTITION_MERGE_ERROR, MYF(0),
- engine_array[0] == myisammrg_hton ? "MyISAM Merge" : "CSV");
+ my_error(ER_PARTITION_MERGE_ERROR, MYF(0));
DBUG_RETURN(TRUE);
}
DBUG_RETURN(FALSE);
diff --git a/sql/set_var.cc b/sql/set_var.cc
index 5fb209b8b11..4369c288cd5 100644
--- a/sql/set_var.cc
+++ b/sql/set_var.cc
@@ -1218,8 +1218,8 @@ static void fix_tx_isolation(THD *thd, enum_var_type type)
thd->variables.tx_isolation);
}
-static void fix_completion_type(THD *thd __attribute__(unused),
- enum_var_type type __attribute__(unused)) {}
+static void fix_completion_type(THD *thd __attribute__((unused)),
+ enum_var_type type __attribute__((unused))) {}
static int check_completion_type(THD *thd, set_var *var)
{
@@ -1258,14 +1258,14 @@ static void fix_net_retry_count(THD *thd, enum_var_type type)
thd->net.retry_count=thd->variables.net_retry_count;
}
#else /* HAVE_REPLICATION */
-static void fix_net_read_timeout(THD *thd __attribute__(unused),
- enum_var_type type __attribute__(unused))
+static void fix_net_read_timeout(THD *thd __attribute__((unused)),
+ enum_var_type type __attribute__((unused)))
{}
-static void fix_net_write_timeout(THD *thd __attribute__(unused),
- enum_var_type type __attribute__(unused))
+static void fix_net_write_timeout(THD *thd __attribute__((unused)),
+ enum_var_type type __attribute__((unused)))
{}
-static void fix_net_retry_count(THD *thd __attribute__(unused),
- enum_var_type type __attribute__(unused))
+static void fix_net_retry_count(THD *thd __attribute__((unused)),
+ enum_var_type type __attribute__((unused)))
{}
#endif /* HAVE_REPLICATION */
diff --git a/sql/share/errmsg.txt b/sql/share/errmsg.txt
index c90e771fd40..0bcd15c2b82 100644
--- a/sql/share/errmsg.txt
+++ b/sql/share/errmsg.txt
@@ -3791,7 +3791,7 @@ ER_WRONG_MRG_TABLE
cze "V-B¹echny tabulky v MERGE tabulce nejsou definovány stejnì"
dan "Tabellerne i MERGE er ikke defineret ens"
nla "Niet alle tabellen in de MERGE tabel hebben identieke gedefinities"
- eng "All tables in the MERGE table are not identically defined"
+ eng "Unable to open underlying table which is differently defined or of non-MyISAM type or doesn't exist"
est "Kõik tabelid MERGE tabeli määratluses ei ole identsed"
fre "Toutes les tables de la table de type MERGE n'ont pas la même définition"
ger "Nicht alle Tabellen in der MERGE-Tabelle sind gleich definiert"
@@ -5960,34 +5960,48 @@ ER_EVENT_SET_VAR_ERROR
eng "Error during starting/stopping of the scheduler. Error code %u"
ger "Fehler während des Startens oder Anhalten des Schedulers. Fehlercode %u"
ER_PARTITION_MERGE_ERROR
- eng "%s handler cannot be used in partitioned tables"
- ger "%s-Handler kann in partitionierten Tabellen nicht verwendet werden"
- swe "%s kan inte användas i en partitionerad tabell"
+ eng "Engine cannot be used in partitioned tables"
+ ger "Engine kann in partitionierten Tabellen nicht verwendet werden"
+ swe "Engine inte användas i en partitionerad tabell"
ER_CANT_ACTIVATE_LOG
eng "Cannot activate '%-.64s' log"
ger "Kann Logdatei '%-.64s' nicht aktivieren"
ER_RBR_NOT_AVAILABLE
eng "The server was not built with row-based replication"
+ER_BASE64_DECODE_ERROR
+ eng "Decoding of base64 string failed"
+ swe "Avkodning av base64 sträng misslyckades"
ger "Der Server hat keine zeilenbasierte Replikation"
ER_NO_TRIGGERS_ON_SYSTEM_SCHEMA
eng "Triggers can not be created on system tables"
ger "Trigger können nicht auf Systemtabellen erzeugt werden"
ER_EVENT_RECURSIVITY_FORBIDDEN
eng "Recursivity of EVENT DDL statements is forbidden when body is present"
+ ger "Rekursivität von EVENT-DDL-Anweisungen ist unzulässig wenn ein Hauptteil (Body) existiert"
ER_EVENTS_DB_ERROR
eng "Cannot proceed because the tables used by events were found damaged at server start"
+ ger "Kann nicht weitermachen, weil die Tabellen, die von Events verwendet werden, beim Serverstart als beschädigt markiert wurden"
ER_ONLY_INTEGERS_ALLOWED
- eng "Only normal integers allowed as number here"
+ eng "Only integers allowed as number here"
+ ger "An dieser Stelle sind nur Ganzzahlen zulässig"
ER_AUTOINC_READ_FAILED
eng "Failed to read auto-increment value from storage engine"
+ ger "Lesen des Autoincrement-Werts von der Speicher-Engine fehlgeschlagen"
ER_USERNAME
- eng "user name"
+ eng "user name"
+ ger "Benutzername"
ER_HOSTNAME
- eng "host name"
+ eng "host name"
+ ger "Hostname"
ER_WRONG_STRING_LENGTH
- eng "String '%-.70s' is too long for %s (should be no longer than %d)"
+ eng "String '%-.70s' is too long for %s (should be no longer than %d)"
+ ger "String '%-.70s' ist zu lang für %s (sollte nicht länger sein als %d)"
ER_UNSUPORTED_LOG_ENGINE
eng "This storage engine cannot be used for log tables""
+ ger "Diese Speicher-Engine kann für Logtabellen nicht verwendet werden"
ER_BAD_LOG_STATEMENT
eng "You cannot '%s' a log table if logging is enabled"
+ ger "Sie können eine Logtabelle nicht '%s', wenn Loggen angeschaltet ist"
+ER_NON_INSERTABLE_TABLE
+ eng "The target table %-.100s of the %s is not insertable-into"
diff --git a/sql/slave.cc b/sql/slave.cc
index f9645fc83e3..1852ff68070 100644
--- a/sql/slave.cc
+++ b/sql/slave.cc
@@ -3101,17 +3101,22 @@ static int exec_relay_log_event(THD* thd, RELAY_LOG_INFO* rli)
type_code != START_EVENT_V3 && type_code!= FORMAT_DESCRIPTION_EVENT))
{
DBUG_PRINT("info", ("event skipped"));
- if (thd->options & OPTION_BEGIN)
- rli->inc_event_relay_log_pos();
- else
- {
- rli->inc_group_relay_log_pos((type_code == ROTATE_EVENT ||
- type_code == STOP_EVENT ||
- type_code == FORMAT_DESCRIPTION_EVENT) ?
- LL(0) : ev->log_pos,
- 1/* skip lock*/);
- flush_relay_log_info(rli);
- }
+ /*
+ We only skip the event here and do not increase the group log
+ position. In the event that we have to restart, this means
+ that we might have to skip the event again, but that is a
+ minor issue.
+
+ If we were to increase the group log position when skipping an
+ event, it might be that we are restarting at the wrong
+ position and have events before that we should have executed,
+ so not increasing the group log position is a sure bet in this
+ case.
+
+ In this way, we just step the group log position when we
+ *know* that we are at the end of a group.
+ */
+ rli->inc_event_relay_log_pos();
/*
Protect against common user error of setting the counter to 1
@@ -4447,7 +4452,7 @@ static int connect_to_master(THD* thd, MYSQL* mysql, MASTER_INFO* mi,
suppress_warnings= 0;
sql_print_error("Slave I/O thread: error %s to master \
'%s@%s:%d': \
-Error: '%s' errno: %d retry-time: %d retries: %d",
+Error: '%s' errno: %d retry-time: %d retries: %lu",
(reconnect ? "reconnecting" : "connecting"),
mi->user,mi->host,mi->port,
mysql_error(mysql), last_errno,
diff --git a/sql/slave.h b/sql/slave.h
index 9d76277da0d..e70b2e4b326 100644
--- a/sql/slave.h
+++ b/sql/slave.h
@@ -152,7 +152,7 @@ typedef struct st_master_info
/* the variables below are needed because we can change masters on the fly */
char master_log_name[FN_REFLEN];
char host[HOSTNAME_LENGTH+1];
- char user[USERNAME_BYTE_LENGTH+1];
+ char user[USERNAME_LENGTH+1];
char password[MAX_PASSWORD_LENGTH+1];
my_bool ssl; // enables use of SSL connection if true
char ssl_ca[FN_REFLEN], ssl_capath[FN_REFLEN], ssl_cert[FN_REFLEN];
@@ -272,7 +272,8 @@ const char *print_slave_db_safe(const char *db);
int check_expected_error(THD* thd, RELAY_LOG_INFO* rli, int error_code);
void skip_load_data_infile(NET* net);
void slave_print_msg(enum loglevel level, RELAY_LOG_INFO* rli,
- int err_code, const char* msg, ...);
+ int err_code, const char* msg, ...)
+ ATTRIBUTE_FORMAT(printf, 4, 5);
void end_slave(); /* clean up */
void init_master_info_with_options(MASTER_INFO* mi);
diff --git a/sql/sp.cc b/sql/sp.cc
index 8ddf55e1837..3411a18c17a 100644
--- a/sql/sp.cc
+++ b/sql/sp.cc
@@ -387,16 +387,16 @@ db_load_routine(THD *thd, int type, sp_name *name, sp_head **sphp,
{
LEX *old_lex= thd->lex, newlex;
String defstr;
- char old_db_buf[NAME_BYTE_LEN+1];
+ char old_db_buf[NAME_LEN+1];
LEX_STRING old_db= { old_db_buf, sizeof(old_db_buf) };
bool dbchanged;
ulong old_sql_mode= thd->variables.sql_mode;
ha_rows old_select_limit= thd->variables.select_limit;
sp_rcontext *old_spcont= thd->spcont;
-
- char definer_user_name_holder[USERNAME_BYTE_LENGTH + 1];
+
+ char definer_user_name_holder[USERNAME_LENGTH + 1];
LEX_STRING definer_user_name= { definer_user_name_holder,
- USERNAME_BYTE_LENGTH };
+ USERNAME_LENGTH };
char definer_host_name_holder[HOSTNAME_LENGTH + 1];
LEX_STRING definer_host_name= { definer_host_name_holder, HOSTNAME_LENGTH };
@@ -495,7 +495,7 @@ db_create_routine(THD *thd, int type, sp_head *sp)
int ret;
TABLE *table;
char definer[USER_HOST_BUFF_SIZE];
- char old_db_buf[NAME_BYTE_LEN+1];
+ char old_db_buf[NAME_LEN+1];
LEX_STRING old_db= { old_db_buf, sizeof(old_db_buf) };
bool dbchanged;
DBUG_ENTER("db_create_routine");
@@ -1606,7 +1606,17 @@ sp_cache_routines_and_add_tables_aux(THD *thd, LEX *lex,
*/
if (!thd->net.report_error)
{
- char n[NAME_LEN*2+2];
+ /*
+ SP allows full NAME_LEN chars thus he have to allocate enough
+ size in bytes. Otherwise there is stack overrun could happen
+ if multibyte sequence is `name`. `db` is still safe because the
+ rest of the server checks agains NAME_LEN bytes and not chars.
+ Hence, the overrun happens only if the name is in length > 32 and
+ uses multibyte (cyrillic, greek, etc.)
+
+ !! Change 3 with SYSTEM_CHARSET_MBMAXLEN when it's defined.
+ */
+ char n[NAME_LEN*3*2+2];
/* m_qname.str is not always \0 terminated */
memcpy(n, name.m_qname.str, name.m_qname.length);
diff --git a/sql/sp_head.cc b/sql/sp_head.cc
index db5f35cc5ee..a061ae12dd1 100644
--- a/sql/sp_head.cc
+++ b/sql/sp_head.cc
@@ -962,7 +962,7 @@ bool
sp_head::execute(THD *thd)
{
DBUG_ENTER("sp_head::execute");
- char old_db_buf[NAME_BYTE_LEN+1];
+ char old_db_buf[NAME_LEN+1];
LEX_STRING old_db= { old_db_buf, sizeof(old_db_buf) };
bool dbchanged;
sp_rcontext *ctx;
@@ -2010,8 +2010,8 @@ sp_head::set_info(longlong created, longlong modified,
void
sp_head::set_definer(const char *definer, uint definerlen)
{
- char user_name_holder[USERNAME_BYTE_LENGTH + 1];
- LEX_STRING user_name= { user_name_holder, USERNAME_BYTE_LENGTH };
+ char user_name_holder[USERNAME_LENGTH + 1];
+ LEX_STRING user_name= { user_name_holder, USERNAME_LENGTH };
char host_name_holder[HOSTNAME_LENGTH + 1];
LEX_STRING host_name= { host_name_holder, HOSTNAME_LENGTH };
diff --git a/sql/sql_acl.cc b/sql/sql_acl.cc
index 5badccef544..c55fc744cd0 100644
--- a/sql/sql_acl.cc
+++ b/sql/sql_acl.cc
@@ -169,7 +169,7 @@ static byte* acl_entry_get_key(acl_entry *entry,uint *length,
}
#define IP_ADDR_STRLEN (3+1+3+1+3+1+3)
-#define ACL_KEY_LENGTH (IP_ADDR_STRLEN+1+NAME_BYTE_LEN+1+USERNAME_BYTE_LENGTH+1)
+#define ACL_KEY_LENGTH (IP_ADDR_STRLEN+1+NAME_LEN+1+USERNAME_LENGTH+1)
static DYNAMIC_ARRAY acl_hosts,acl_users,acl_dbs;
static MEM_ROOT mem, memex;
@@ -312,7 +312,7 @@ static my_bool acl_load(THD *thd, TABLE_LIST *tables)
READ_RECORD read_record_info;
my_bool return_val= 1;
bool check_no_resolve= specialflag & SPECIAL_NO_RESOLVE;
- char tmp_name[NAME_BYTE_LEN+1];
+ char tmp_name[NAME_LEN+1];
int password_length;
DBUG_ENTER("acl_load");
@@ -2400,7 +2400,7 @@ static GRANT_NAME *name_hash_search(HASH *name_hash,
const char *user, const char *tname,
bool exact)
{
- char helping [NAME_BYTE_LEN*2+USERNAME_BYTE_LENGTH+3];
+ char helping [NAME_LEN*2+USERNAME_LENGTH+3];
uint len;
GRANT_NAME *grant_name,*found=0;
HASH_SEARCH_STATE state;
@@ -3307,7 +3307,7 @@ bool mysql_grant(THD *thd, const char *db, List <LEX_USER> &list,
{
List_iterator <LEX_USER> str_list (list);
LEX_USER *Str, *tmp_Str;
- char tmp_db[NAME_BYTE_LEN+1];
+ char tmp_db[NAME_LEN+1];
bool create_new_users=0;
TABLE_LIST tables[2];
DBUG_ENTER("mysql_grant");
@@ -3371,7 +3371,7 @@ bool mysql_grant(THD *thd, const char *db, List <LEX_USER> &list,
{
result= TRUE;
continue;
- }
+ }
if (replace_user_table(thd, tables[0].table, *Str,
(!db ? rights : 0), revoke_grant, create_new_users,
test(thd->variables.sql_mode &
@@ -4011,7 +4011,7 @@ err2:
bool check_grant_db(THD *thd,const char *db)
{
Security_context *sctx= thd->security_ctx;
- char helping [NAME_BYTE_LEN+USERNAME_BYTE_LENGTH+2];
+ char helping [NAME_LEN+USERNAME_LENGTH+2];
uint len;
bool error= 1;
diff --git a/sql/sql_analyse.cc b/sql/sql_analyse.cc
index 9f1a0561138..264e3e2b988 100644
--- a/sql/sql_analyse.cc
+++ b/sql/sql_analyse.cc
@@ -806,9 +806,9 @@ void field_str::get_opt_type(String *answer, ha_rows total_rows)
else if (num_info.decimals) // DOUBLE(%d,%d) sometime
{
if (num_info.dval > -FLT_MAX && num_info.dval < FLT_MAX)
- sprintf(buff, "FLOAT(%d,%d)", num_info.integers, num_info.decimals);
+ sprintf(buff, "FLOAT(%d,%d)", (num_info.integers + num_info.decimals), num_info.decimals);
else
- sprintf(buff, "DOUBLE(%d,%d)", num_info.integers, num_info.decimals);
+ sprintf(buff, "DOUBLE(%d,%d)", (num_info.integers + num_info.decimals), num_info.decimals);
}
else if (ev_num_info.llval >= -128 &&
ev_num_info.ullval <=
@@ -915,10 +915,10 @@ void field_real::get_opt_type(String *answer,
else
{
if (min_arg >= -FLT_MAX && max_arg <= FLT_MAX)
- sprintf(buff, "FLOAT(%d,%d)", (int) max_length - (item->decimals + 1),
+ sprintf(buff, "FLOAT(%d,%d)", (int) max_length - (item->decimals + 1) + max_notzero_dec_len,
max_notzero_dec_len);
else
- sprintf(buff, "DOUBLE(%d,%d)", (int) max_length - (item->decimals + 1),
+ sprintf(buff, "DOUBLE(%d,%d)", (int) max_length - (item->decimals + 1) + max_notzero_dec_len,
max_notzero_dec_len);
answer->append(buff, (uint) strlen(buff));
}
diff --git a/sql/sql_base.cc b/sql/sql_base.cc
index 9e3049d433b..a530c7f7fdc 100644
--- a/sql/sql_base.cc
+++ b/sql/sql_base.cc
@@ -1461,8 +1461,11 @@ void update_non_unique_table_error(TABLE_LIST *update,
*/
if (update->view)
{
+ /* Issue the ER_NON_INSERTABLE_TABLE error for an INSERT */
if (update->view == duplicate->view)
- my_error(ER_NON_UPDATABLE_TABLE, MYF(0), update->alias, operation);
+ my_error(!strncmp(operation, "INSERT", 6) ?
+ ER_NON_INSERTABLE_TABLE : ER_NON_UPDATABLE_TABLE, MYF(0),
+ update->alias, operation);
else
my_error(ER_VIEW_PREVENT_UPDATE, MYF(0),
(duplicate->view ? duplicate->alias : update->alias),
diff --git a/sql/sql_binlog.cc b/sql/sql_binlog.cc
index 0939ad66cd0..23ca5330053 100644
--- a/sql/sql_binlog.cc
+++ b/sql/sql_binlog.cc
@@ -31,6 +31,7 @@
void mysql_client_binlog_statement(THD* thd)
{
+ DBUG_ENTER("mysql_client_binlog_statement");
DBUG_PRINT("info",("binlog base64: '%*s'",
(thd->lex->comment.length < 2048 ?
thd->lex->comment.length : 2048),
@@ -43,8 +44,8 @@ void mysql_client_binlog_statement(THD* thd)
my_bool nsok= thd->net.no_send_ok;
thd->net.no_send_ok= TRUE;
- const my_size_t coded_len= thd->lex->comment.length + 1;
- const my_size_t event_len= base64_needed_decoded_length(coded_len);
+ my_size_t coded_len= thd->lex->comment.length + 1;
+ my_size_t decoded_len= base64_needed_decoded_length(coded_len);
DBUG_ASSERT(coded_len > 0);
/*
@@ -57,9 +58,8 @@ void mysql_client_binlog_statement(THD* thd)
new Format_description_log_event(4);
const char *error= 0;
- char *buf= (char *) my_malloc(event_len, MYF(MY_WME));
+ char *buf= (char *) my_malloc(decoded_len, MYF(MY_WME));
Log_event *ev = 0;
- int res;
/*
Out of memory check
@@ -73,43 +73,97 @@ void mysql_client_binlog_statement(THD* thd)
thd->rli_fake->sql_thd= thd;
thd->rli_fake->no_storage= TRUE;
- res= base64_decode(thd->lex->comment.str, coded_len, buf);
-
- DBUG_PRINT("info",("binlog base64 decoded_len=%d, event_len=%d\n",
- res, uint4korr(buf + EVENT_LEN_OFFSET)));
- /*
- Note that 'res' is the correct event length, 'event_len' was
- calculated based on the base64-string that possibly contained
- extra spaces, so it can be longer than the real event.
- */
- if (res < EVENT_LEN_OFFSET
- || (uint) res != uint4korr(buf+EVENT_LEN_OFFSET))
+ for (char const *strptr= thd->lex->comment.str ;
+ strptr < thd->lex->comment.str + thd->lex->comment.length ; )
{
- my_error(ER_SYNTAX_ERROR, MYF(0));
- goto end;
- }
-
- ev= Log_event::read_log_event(buf, res, &error, desc);
+ char const *endptr= 0;
+ int bytes_decoded= base64_decode(strptr, coded_len, buf, &endptr);
+
+ DBUG_PRINT("info",
+ ("bytes_decoded=%d; strptr=0x%lu; endptr=0x%lu ('%c':%d)",
+ bytes_decoded, strptr, endptr, *endptr, *endptr));
+
+ if (bytes_decoded < 0)
+ {
+ my_error(ER_BASE64_DECODE_ERROR, MYF(0));
+ goto end;
+ }
+ else if (bytes_decoded == 0)
+ break; // If no bytes where read, the string contained only whitespace
+
+ DBUG_ASSERT(bytes_decoded > 0);
+ DBUG_ASSERT(endptr > strptr);
+ coded_len-= endptr - strptr;
+ strptr= endptr;
- DBUG_PRINT("info",("binlog base64 err=%s", error));
- if (!ev)
- {
/*
- This could actually be an out-of-memory, but it is more
- likely causes by a bad statement
+ Now we have one or more events stored in the buffer. The size of
+ the buffer is computed based on how much base64-encoded data
+ there were, so there should be ample space for the data (maybe
+ even too much, since a statement can consist of a considerable
+ number of events).
+
+ TODO: Switch to use a stream-based base64 encoder/decoder in
+ order to be able to read exactly what is necessary.
*/
- my_error(ER_SYNTAX_ERROR, MYF(0));
- goto end;
- }
- DBUG_PRINT("info",("ev->get_type_code()=%d", ev->get_type_code()));
- DBUG_PRINT("info",("buf+EVENT_TYPE_OFFSET=%d", buf+EVENT_TYPE_OFFSET));
+ DBUG_PRINT("info",("binlog base64 decoded_len=%d, bytes_decoded=%d",
+ decoded_len, bytes_decoded));
- ev->thd= thd;
- if (ev->exec_event(thd->rli_fake))
- {
- my_error(ER_UNKNOWN_ERROR, MYF(0), "Error executing BINLOG statement");
- goto end;
+ /*
+ Now we start to read events of the buffer, until there are no
+ more.
+ */
+ for (char *bufptr= buf ; bytes_decoded > 0 ; )
+ {
+ /*
+ Checking that the first event in the buffer is not truncated.
+ */
+ ulong event_len= uint4korr(bufptr + EVENT_LEN_OFFSET);
+ DBUG_PRINT("info", ("event_len=%lu, bytes_decoded=%d",
+ event_len, bytes_decoded));
+ if (bytes_decoded < EVENT_LEN_OFFSET || (uint) bytes_decoded < event_len)
+ {
+ my_error(ER_SYNTAX_ERROR, MYF(0));
+ goto end;
+ }
+
+ ev= Log_event::read_log_event(bufptr, event_len, &error, desc);
+
+ DBUG_PRINT("info",("binlog base64 err=%s", error));
+ if (!ev)
+ {
+ /*
+ This could actually be an out-of-memory, but it is more likely
+ causes by a bad statement
+ */
+ my_error(ER_SYNTAX_ERROR, MYF(0));
+ goto end;
+ }
+
+ bytes_decoded -= event_len;
+ bufptr += event_len;
+
+ DBUG_PRINT("info",("ev->get_type_code()=%d", ev->get_type_code()));
+ DBUG_PRINT("info",("bufptr+EVENT_TYPE_OFFSET=0x%lx",
+ bufptr+EVENT_TYPE_OFFSET));
+ DBUG_PRINT("info", ("bytes_decoded=%d; bufptr=0x%lx; buf[EVENT_LEN_OFFSET]=%u",
+ bytes_decoded, bufptr, uint4korr(bufptr+EVENT_LEN_OFFSET)));
+ ev->thd= thd;
+ if (int err= ev->exec_event(thd->rli_fake))
+ {
+ DBUG_PRINT("info", ("exec_event() - error=%d", error));
+ /*
+ TODO: Maybe a better error message since the BINLOG statement
+ now contains several events.
+ */
+ my_error(ER_UNKNOWN_ERROR, MYF(0), "Error executing BINLOG statement");
+ goto end;
+ }
+
+ delete ev;
+ ev= 0;
+ }
}
/*
@@ -126,10 +180,7 @@ end:
*/
thd->net.no_send_ok= nsok;
- if (ev)
- delete ev;
- if (desc)
- delete desc;
- if (buf)
- my_free(buf, MYF(0));
+ delete desc;
+ my_free(buf, MYF(MY_ALLOW_ZERO_PTR));
+ DBUG_VOID_RETURN;
}
diff --git a/sql/sql_cache.cc b/sql/sql_cache.cc
index e0831b0f8ee..ee3b8aa79fe 100644
--- a/sql/sql_cache.cc
+++ b/sql/sql_cache.cc
@@ -2389,7 +2389,7 @@ Query_cache::register_tables_from_list(TABLE_LIST *tables_used,
tables_used->engine_data))
DBUG_RETURN(0);
- if (tables_used->table->s->db_type == myisammrg_hton)
+ if (tables_used->table->s->db_type->db_type == DB_TYPE_MRG_MYISAM)
{
ha_myisammrg *handler = (ha_myisammrg *) tables_used->table->file;
MYRG_INFO *file = handler->myrg_info();
@@ -3013,7 +3013,7 @@ static TABLE_COUNTER_TYPE process_and_count_tables(TABLE_LIST *tables_used,
"other non-cacheable table(s)"));
DBUG_RETURN(0);
}
- if (tables_used->table->s->db_type == myisammrg_hton)
+ if (tables_used->table->s->db_type->db_type == DB_TYPE_MRG_MYISAM)
{
ha_myisammrg *handler = (ha_myisammrg *)tables_used->table->file;
MYRG_INFO *file = handler->myrg_info();
diff --git a/sql/sql_class.cc b/sql/sql_class.cc
index ceaf568ac6b..3fd0e621422 100644
--- a/sql/sql_class.cc
+++ b/sql/sql_class.cc
@@ -630,7 +630,21 @@ bool THD::store_globals()
}
-/* Cleanup after a query */
+/*
+ Cleanup after query.
+
+ SYNOPSIS
+ THD::cleanup_after_query()
+
+ DESCRIPTION
+ This function is used to reset thread data to its default state.
+
+ NOTE
+ This function is not suitable for setting thread data to some
+ non-default values, as there is only one replication thread, so
+ different master threads may overwrite data of each other on
+ slave.
+*/
void THD::cleanup_after_query()
{
@@ -655,6 +669,7 @@ void THD::cleanup_after_query()
where= THD::DEFAULT_WHERE;
}
+
/*
Convert a string to another character set
diff --git a/sql/sql_class.h b/sql/sql_class.h
index 6b46c9676f7..95283ec2fc8 100644
--- a/sql/sql_class.h
+++ b/sql/sql_class.h
@@ -930,6 +930,7 @@ public:
/*
Public interface to write RBR events to the binlog
*/
+ void binlog_start_trans_and_stmt();
int binlog_write_table_map(TABLE *table, bool is_transactional);
int binlog_write_row(TABLE* table, bool is_transactional,
MY_BITMAP const* cols, my_size_t colcnt,
diff --git a/sql/sql_cursor.cc b/sql/sql_cursor.cc
index 2784e71ccae..46fae3ffb99 100644
--- a/sql/sql_cursor.cc
+++ b/sql/sql_cursor.cc
@@ -45,7 +45,7 @@ class Sensitive_cursor: public Server_side_cursor
query_id_t query_id;
struct Engine_info
{
- const handlerton *ht;
+ handlerton *ht;
void *read_view;
};
Engine_info ht_info[MAX_HA];
@@ -318,12 +318,12 @@ Sensitive_cursor::post_open(THD *thd)
info= &ht_info[0];
for (handlerton **pht= thd->transaction.stmt.ht; *pht; pht++)
{
- const handlerton *ht= *pht;
+ handlerton *ht= *pht;
close_at_commit|= test(ht->flags & HTON_CLOSE_CURSORS_AT_COMMIT);
if (ht->create_cursor_read_view)
{
info->ht= ht;
- info->read_view= (ht->create_cursor_read_view)();
+ info->read_view= (ht->create_cursor_read_view)(ht, thd);
++info;
}
}
@@ -433,7 +433,7 @@ Sensitive_cursor::fetch(ulong num_rows)
thd->set_n_backup_active_arena(this, &backup_arena);
for (info= ht_info; info->read_view ; info++)
- (info->ht->set_cursor_read_view)(info->read_view);
+ (info->ht->set_cursor_read_view)(info->ht, thd, info->read_view);
join->fetch_limit+= num_rows;
@@ -454,7 +454,7 @@ Sensitive_cursor::fetch(ulong num_rows)
reset_thd(thd);
for (info= ht_info; info->read_view; info++)
- (info->ht->set_cursor_read_view)(0);
+ (info->ht->set_cursor_read_view)(info->ht, thd, 0);
if (error == NESTED_LOOP_CURSOR_LIMIT)
{
@@ -487,7 +487,7 @@ Sensitive_cursor::close()
for (Engine_info *info= ht_info; info->read_view; info++)
{
- (info->ht->close_cursor_read_view)(info->read_view);
+ (info->ht->close_cursor_read_view)(info->ht, thd, info->read_view);
info->read_view= 0;
info->ht= 0;
}
diff --git a/sql/sql_insert.cc b/sql/sql_insert.cc
index 946a6233bc2..4dcbf9af4a0 100644
--- a/sql/sql_insert.cc
+++ b/sql/sql_insert.cc
@@ -112,7 +112,7 @@ static int check_insert_fields(THD *thd, TABLE_LIST *table_list,
if (!table_list->updatable)
{
- my_error(ER_NON_UPDATABLE_TABLE, MYF(0), table_list->alias, "INSERT");
+ my_error(ER_NON_INSERTABLE_TABLE, MYF(0), table_list->alias, "INSERT");
return -1;
}
@@ -228,7 +228,7 @@ static int check_insert_fields(THD *thd, TABLE_LIST *table_list,
(table_list->view &&
check_view_insertability(thd, table_list)))
{
- my_error(ER_NON_UPDATABLE_TABLE, MYF(0), table_list->alias, "INSERT");
+ my_error(ER_NON_INSERTABLE_TABLE, MYF(0), table_list->alias, "INSERT");
return -1;
}
@@ -1266,7 +1266,7 @@ err:
if (thd->lex->current_select)
thd->lex->current_select->no_error= 0; // Give error
table->file->print_error(error,MYF(0));
-
+
before_trg_err:
table->file->restore_auto_increment(prev_insert_id);
if (key)
@@ -1334,13 +1334,16 @@ public:
bool query_start_used, ignore, log_query;
bool stmt_depends_on_first_successful_insert_id_in_prev_stmt;
ulonglong first_successful_insert_id_in_prev_stmt;
+ ulonglong forced_insert_id;
+ ulong auto_increment_increment;
+ ulong auto_increment_offset;
timestamp_auto_set_type timestamp_field_type;
LEX_STRING query;
delayed_row(LEX_STRING const query_arg, enum_duplicates dup_arg,
bool ignore_arg, bool log_query_arg)
: record(0), dup(dup_arg), ignore(ignore_arg), log_query(log_query_arg),
- query(query_arg)
+ forced_insert_id(0), query(query_arg)
{}
~delayed_row()
{
@@ -1698,6 +1701,7 @@ write_delayed(THD *thd,TABLE *table, enum_duplicates duplic,
{
delayed_row *row;
delayed_insert *di=thd->di;
+ const Discrete_interval *forced_auto_inc;
DBUG_ENTER("write_delayed");
DBUG_PRINT("enter", ("query = '%s' length %u", query.str, query.length));
@@ -1747,6 +1751,17 @@ write_delayed(THD *thd,TABLE *table, enum_duplicates duplic,
thd->first_successful_insert_id_in_prev_stmt;
row->timestamp_field_type= table->timestamp_field_type;
+ /* Copy session variables. */
+ row->auto_increment_increment= thd->variables.auto_increment_increment;
+ row->auto_increment_offset= thd->variables.auto_increment_offset;
+ /* Copy the next forced auto increment value, if any. */
+ if ((forced_auto_inc= thd->auto_inc_intervals_forced.get_next()))
+ {
+ row->forced_insert_id= forced_auto_inc->minimum();
+ DBUG_PRINT("delayed", ("transmitting auto_inc: %lu",
+ (ulong) row->forced_insert_id));
+ }
+
di->rows.push_back(row);
di->stacked_inserts++;
di->status=1;
@@ -1998,6 +2013,10 @@ pthread_handler_t handle_delayed_insert(void *arg)
MYSQL_LOCK *lock=thd->lock;
thd->lock=0;
pthread_mutex_unlock(&di->mutex);
+ /*
+ We need to release next_insert_id before unlocking. This is
+ enforced by handler::ha_external_lock().
+ */
di->table->file->ha_release_auto_increment();
mysql_unlock_tables(thd, lock);
di->group_count=0;
@@ -2014,6 +2033,10 @@ err:
rolled back. We only need to roll back a potential statement
transaction, since real transactions are rolled back in
close_thread_tables().
+
+ TODO: This is not true any more, table maps are generated on the
+ first call to ha_*_row() instead. Remove code that are used to
+ cover for the case outlined above.
*/
ha_rollback_stmt(thd);
@@ -2123,8 +2146,18 @@ bool delayed_insert::handle_inserts(void)
use values from the previous interval (of the previous rows).
*/
bool log_query= (row->log_query && row->query.str != NULL);
+ DBUG_PRINT("delayed", ("query: '%s' length: %u", row->query.str ?
+ row->query.str : "[NULL]", row->query.length));
if (log_query)
{
+ /*
+ This is the first value of an INSERT statement.
+ It is the right place to clear a forced insert_id.
+ This is usually done after the last value of an INSERT statement,
+ but we won't know this in the insert delayed thread. But before
+ the first value is sufficiently equivalent to after the last
+ value of the previous statement.
+ */
table->file->ha_release_auto_increment();
thd.auto_inc_intervals_in_cur_stmt_for_binlog.empty();
}
@@ -2134,6 +2167,17 @@ bool delayed_insert::handle_inserts(void)
row->stmt_depends_on_first_successful_insert_id_in_prev_stmt;
table->timestamp_field_type= row->timestamp_field_type;
+ /* Copy the session variables. */
+ thd.variables.auto_increment_increment= row->auto_increment_increment;
+ thd.variables.auto_increment_offset= row->auto_increment_offset;
+ /* Copy a forced insert_id, if any. */
+ if (row->forced_insert_id)
+ {
+ DBUG_PRINT("delayed", ("received auto_inc: %lu",
+ (ulong) row->forced_insert_id));
+ thd.force_one_auto_inc_interval(row->forced_insert_id);
+ }
+
info.ignore= row->ignore;
info.handle_duplicates= row->dup;
if (info.ignore ||
@@ -2211,6 +2255,7 @@ bool delayed_insert::handle_inserts(void)
/* This should never happen */
table->file->print_error(error,MYF(0));
sql_print_error("%s",thd.net.last_error);
+ DBUG_PRINT("error", ("HA_EXTRA_NO_CACHE failed in loop"));
goto err;
}
query_cache_invalidate3(&thd, table, 1);
@@ -2253,6 +2298,7 @@ bool delayed_insert::handle_inserts(void)
{ // This shouldn't happen
table->file->print_error(error,MYF(0));
sql_print_error("%s",thd.net.last_error);
+ DBUG_PRINT("error", ("HA_EXTRA_NO_CACHE failed after loop"));
goto err;
}
query_cache_invalidate3(&thd, table, 1);
@@ -2260,13 +2306,16 @@ bool delayed_insert::handle_inserts(void)
DBUG_RETURN(0);
err:
+ DBUG_EXECUTE("error", max_rows= 0;);
/* Remove all not used rows */
while ((row=rows.get()))
{
delete row;
thread_safe_increment(delayed_insert_errors,&LOCK_delayed_status);
stacked_inserts--;
+ DBUG_EXECUTE("error", max_rows++;);
}
+ DBUG_PRINT("error", ("dropped %lu rows after an error", max_rows));
thread_safe_increment(delayed_insert_errors, &LOCK_delayed_status);
pthread_mutex_lock(&mutex);
DBUG_RETURN(1);
@@ -2357,6 +2406,7 @@ select_insert::prepare(List<Item> &values, SELECT_LEX_UNIT *u)
DBUG_ENTER("select_insert::prepare");
unit= u;
+
/*
Since table in which we are going to insert is added to the first
select, LEX::current_select should point to the first select while
@@ -2586,58 +2636,56 @@ void select_insert::send_error(uint errcode,const char *err)
if (errcode != ER_UNKNOWN_ERROR && !thd->net.report_error)
my_message(errcode, err, MYF(0));
- if (!table)
+ /*
+ If the creation of the table failed (due to a syntax error, for
+ example), no table will have been opened and therefore 'table'
+ will be NULL. In that case, we still need to execute the rollback
+ and the end of the function to truncate the binary log, but we can
+ skip all the intermediate steps.
+ */
+ if (table)
{
/*
- This can only happen when using CREATE ... SELECT and the table was not
- created becasue of an syntax error
+ If we are not in prelocked mode, we end the bulk insert started
+ before.
*/
- DBUG_VOID_RETURN;
- }
- if (!thd->prelocked_mode)
- table->file->ha_end_bulk_insert();
- /*
- If at least one row has been inserted/modified and will stay in the table
- (the table doesn't have transactions) we must write to the binlog (and
- the error code will make the slave stop).
-
- For many errors (example: we got a duplicate key error while
- inserting into a MyISAM table), no row will be added to the table,
- so passing the error to the slave will not help since there will
- be an error code mismatch (the inserts will succeed on the slave
- with no error).
-
- If we are using row-based replication we have two cases where this
- code is executed: replication of CREATE-SELECT and replication of
- INSERT-SELECT.
-
- When replicating a CREATE-SELECT statement, we shall not write the
- events to the binary log and should thus not set
- OPTION_STATUS_NO_TRANS_UPDATE.
-
- When replicating INSERT-SELECT, we shall not write the events to
- the binary log for transactional table, but shall write all events
- if there is one or more writes to non-transactional tables. In
- this case, the OPTION_STATUS_NO_TRANS_UPDATE is set if there is a
- write to a non-transactional table, otherwise it is cleared.
- */
- if (info.copied || info.deleted || info.updated)
- {
- if (!table->file->has_transactions())
+ if (!thd->prelocked_mode)
+ table->file->ha_end_bulk_insert();
+
+ /*
+ If at least one row has been inserted/modified and will stay in
+ the table (the table doesn't have transactions) we must write to
+ the binlog (and the error code will make the slave stop).
+
+ For many errors (example: we got a duplicate key error while
+ inserting into a MyISAM table), no row will be added to the table,
+ so passing the error to the slave will not help since there will
+ be an error code mismatch (the inserts will succeed on the slave
+ with no error).
+
+ If table creation failed, the number of rows modified will also be
+ zero, so no check for that is made.
+ */
+ if (info.copied || info.deleted || info.updated)
{
- if (mysql_bin_log.is_open())
+ DBUG_ASSERT(table != NULL);
+ if (!table->file->has_transactions())
{
- thd->binlog_query(THD::ROW_QUERY_TYPE, thd->query, thd->query_length,
- table->file->has_transactions(), FALSE);
+ if (mysql_bin_log.is_open())
+ {
+ thd->binlog_query(THD::ROW_QUERY_TYPE, thd->query, thd->query_length,
+ table->file->has_transactions(), FALSE);
+ }
+ if (!thd->current_stmt_binlog_row_based && !table->s->tmp_table &&
+ !can_rollback_data())
+ thd->options|= OPTION_STATUS_NO_TRANS_UPDATE;
+ query_cache_invalidate3(thd, table, 1);
}
- if (!thd->current_stmt_binlog_row_based && !table->s->tmp_table &&
- !can_rollback_data())
- thd->options|= OPTION_STATUS_NO_TRANS_UPDATE;
- query_cache_invalidate3(thd, table, 1);
}
+ table->file->ha_release_auto_increment();
}
+
ha_rollback_stmt(thd);
- table->file->ha_release_auto_increment();
DBUG_VOID_RETURN;
}
@@ -2645,8 +2693,11 @@ void select_insert::send_error(uint errcode,const char *err)
bool select_insert::send_eof()
{
int error,error2;
+ bool const trans_table= table->file->has_transactions();
ulonglong id;
DBUG_ENTER("select_insert::send_eof");
+ DBUG_PRINT("enter", ("trans_table=%d, table_type='%s'",
+ trans_table, table->file->table_type()));
error= (!thd->prelocked_mode) ? table->file->ha_end_bulk_insert():0;
table->file->extra(HA_EXTRA_NO_IGNORE_DUP_KEY);
@@ -2666,9 +2717,8 @@ bool select_insert::send_eof()
are not logged in RBR)
- We are using statement based replication
*/
- if (!table->file->has_transactions() &&
- (!table->s->tmp_table ||
- !thd->current_stmt_binlog_row_based))
+ if (!trans_table &&
+ (!table->s->tmp_table || !thd->current_stmt_binlog_row_based))
thd->options|= OPTION_STATUS_NO_TRANS_UPDATE;
}
@@ -2684,11 +2734,22 @@ bool select_insert::send_eof()
thd->clear_error();
thd->binlog_query(THD::ROW_QUERY_TYPE,
thd->query, thd->query_length,
- table->file->has_transactions(), FALSE);
+ trans_table, FALSE);
+ }
+ /*
+ We will call ha_autocommit_or_rollback() also for
+ non-transactional tables under row-based replication: there might
+ be events in the binary logs transaction, and we need to write
+ them to the binary log.
+ */
+ if (trans_table || thd->current_stmt_binlog_row_based)
+ {
+ int const error2= ha_autocommit_or_rollback(thd, error);
+ if (error2 && !error)
+ error=error2;
}
- if ((error2=ha_autocommit_or_rollback(thd,error)) && ! error)
- error=error2;
table->file->ha_release_auto_increment();
+
if (error)
{
table->file->print_error(error,MYF(0));
@@ -2885,14 +2946,19 @@ select_create::prepare(List<Item> &values, SELECT_LEX_UNIT *u)
class MY_HOOKS : public TABLEOP_HOOKS {
public:
MY_HOOKS(select_create *x) : ptr(x) { }
+
+ private:
virtual void do_prelock(TABLE **tables, uint count)
{
- if (ptr->get_thd()->current_stmt_binlog_row_based &&
- !(ptr->get_create_info()->options & HA_LEX_CREATE_TMP_TABLE))
- ptr->binlog_show_create_table(tables, count);
+ TABLE const *const table = *tables;
+ if (ptr->get_thd()->current_stmt_binlog_row_based &&
+ table->s->tmp_table == NO_TMP_TABLE &&
+ !ptr->get_create_info()->table_existed)
+ {
+ ptr->binlog_show_create_table(tables, count);
+ }
}
- private:
select_create *ptr;
};
@@ -2901,6 +2967,20 @@ select_create::prepare(List<Item> &values, SELECT_LEX_UNIT *u)
#endif
unit= u;
+
+#ifdef HAVE_ROW_BASED_REPLICATION
+ /*
+ Start a statement transaction before the create if we are creating
+ a non-temporary table and are using row-based replication for the
+ statement.
+ */
+ if ((thd->lex->create_info.options & HA_LEX_CREATE_TMP_TABLE) == 0 &&
+ thd->current_stmt_binlog_row_based)
+ {
+ thd->binlog_start_trans_and_stmt();
+ }
+#endif
+
if (!(table= create_table_from_items(thd, create_info, create_table,
extra_fields, keys, &values,
&thd->extra_lock, hook_ptr)))
@@ -3048,8 +3128,17 @@ void select_create::abort()
table->s->version= 0;
hash_delete(&open_cache,(byte*) table);
if (!create_info->table_existed)
+ {
quick_rm_table(table_type, create_table->db,
create_table->table_name, 0);
+ /*
+ We roll back the statement, including truncating the
+ transaction cache of the binary log, if the statement
+ failed.
+ */
+ if (thd->current_stmt_binlog_row_based)
+ ha_rollback_stmt(thd);
+ }
/* Tell threads waiting for refresh that something has happened */
if (version != refresh_version)
broadcast_refresh();
diff --git a/sql/sql_lex.cc b/sql/sql_lex.cc
index 3f3fde03bce..d94c45c4bdd 100644
--- a/sql/sql_lex.cc
+++ b/sql/sql_lex.cc
@@ -1722,7 +1722,8 @@ bool st_lex::can_be_merged()
unit= unit->next_unit())
{
if (unit->first_select()->parent_lex == this &&
- (unit->item == 0 || unit->item->place() != IN_WHERE))
+ (unit->item == 0 ||
+ (unit->item->place() != IN_WHERE && unit->item->place() != IN_ON)))
{
selects_allow_merge= 0;
break;
diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc
index 8cbc7bc46f6..fc7ed7ff673 100644
--- a/sql/sql_parse.cc
+++ b/sql/sql_parse.cc
@@ -1047,8 +1047,8 @@ static int check_connection(THD *thd)
char *passwd= strend(user)+1;
uint user_len= passwd - user - 1;
char *db= passwd;
- char db_buff[NAME_BYTE_LEN + 1]; // buffer to store db in utf8
- char user_buff[USERNAME_BYTE_LENGTH + 1]; // buffer to store user in utf8
+ char db_buff[NAME_LEN + 1]; // buffer to store db in utf8
+ char user_buff[USERNAME_LENGTH + 1]; // buffer to store user in utf8
uint dummy_errors;
/*
@@ -1724,7 +1724,7 @@ bool dispatch_command(enum enum_server_command command, THD *thd,
password. New clients send the size (1 byte) + string (not null
terminated, so also '\0' for empty string).
*/
- char db_buff[NAME_BYTE_LEN+1]; // buffer to store db in utf8
+ char db_buff[NAME_LEN+1]; // buffer to store db in utf8
char *db= passwd;
uint passwd_len= thd->client_capabilities & CLIENT_SECURE_CONNECTION ?
*passwd++ : strlen(passwd);
@@ -7783,7 +7783,6 @@ LEX_USER *get_current_user(THD *thd, LEX_USER *user)
SYNOPSIS
check_string_length()
- cs string charset
str string to be checked
err_msg error message to be displayed if the string is too long
max_length max length
@@ -7793,13 +7792,13 @@ LEX_USER *get_current_user(THD *thd, LEX_USER *user)
TRUE the passed string is longer than max_length
*/
-bool check_string_length(CHARSET_INFO *cs, LEX_STRING *str,
- const char *err_msg, uint max_length)
+bool check_string_length(LEX_STRING *str, const char *err_msg,
+ uint max_length)
{
- if (cs->cset->charpos(cs, str->str, str->str + str->length,
- max_length) >= str->length)
- return FALSE;
+ if (str->length <= max_length)
+ return FALSE;
my_error(ER_WRONG_STRING_LENGTH, MYF(0), str->str, err_msg, max_length);
+
return TRUE;
}
diff --git a/sql/sql_partition.cc b/sql/sql_partition.cc
index a20e5dd512b..8df527fd25b 100644
--- a/sql/sql_partition.cc
+++ b/sql/sql_partition.cc
@@ -2173,18 +2173,17 @@ close_file:
SYNOPSIS
partition_key_modified
table TABLE object for which partition fields are set-up
- fields A list of the to be modifed
+ fields Bitmap representing fields to be modified
RETURN VALUES
TRUE Need special handling of UPDATE
FALSE Normal UPDATE handling is ok
*/
-bool partition_key_modified(TABLE *table, List<Item> &fields)
+bool partition_key_modified(TABLE *table, const MY_BITMAP *fields)
{
- List_iterator_fast<Item> f(fields);
+ Field **fld;
partition_info *part_info= table->part_info;
- Item_field *item_field;
DBUG_ENTER("partition_key_modified");
if (!part_info)
@@ -2192,9 +2191,8 @@ bool partition_key_modified(TABLE *table, List<Item> &fields)
if (table->s->db_type->partition_flags &&
(table->s->db_type->partition_flags() & HA_CAN_UPDATE_PARTITION_KEY))
DBUG_RETURN(FALSE);
- f.rewind();
- while ((item_field=(Item_field*) f++))
- if (item_field->field->flags & FIELD_IN_PART_FUNC_FLAG)
+ for (fld= part_info->full_part_field_array; *fld; fld++)
+ if (bitmap_is_set(fields, (*fld)->field_index))
DBUG_RETURN(TRUE);
DBUG_RETURN(FALSE);
}
diff --git a/sql/sql_partition.h b/sql/sql_partition.h
index c5b930162a9..4372c26a851 100644
--- a/sql/sql_partition.h
+++ b/sql/sql_partition.h
@@ -70,7 +70,7 @@ bool fix_partition_func(THD *thd, TABLE *table, bool create_table_ind);
char *generate_partition_syntax(partition_info *part_info,
uint *buf_length, bool use_sql_alloc,
bool show_partition_options);
-bool partition_key_modified(TABLE *table, List<Item> &fields);
+bool partition_key_modified(TABLE *table, const MY_BITMAP *fields);
void get_partition_set(const TABLE *table, byte *buf, const uint index,
const key_range *key_spec,
part_id_range *part_spec);
diff --git a/sql/sql_plugin.cc b/sql/sql_plugin.cc
index 97c28dd1fa5..34fb447792e 100644
--- a/sql/sql_plugin.cc
+++ b/sql/sql_plugin.cc
@@ -759,14 +759,16 @@ void plugin_load(void)
while (!(error= read_record_info.read_record(&read_record_info)))
{
DBUG_PRINT("info", ("init plugin record"));
- LEX_STRING name, dl;
- name.str= get_field(&mem, table->field[0]);
- name.length= strlen(name.str);
- dl.str= get_field(&mem, table->field[1]);
- dl.length= strlen(dl.str);
+ String str_name, str_dl;
+ get_field(&mem, table->field[0], &str_name);
+ get_field(&mem, table->field[1], &str_dl);
+
+ LEX_STRING name= {(char *)str_name.ptr(), str_name.length()};
+ LEX_STRING dl= {(char *)str_dl.ptr(), str_dl.length()};
+
if (plugin_add(&name, &dl, REPORT_TO_LOG))
- DBUG_PRINT("warning", ("Couldn't load plugin named '%s' with soname '%s'.",
- name.str, dl.str));
+ sql_print_warning("Couldn't load plugin named '%s' with soname '%s'.",
+ str_name.c_ptr(), str_dl.c_ptr());
}
if (error > 0)
sql_print_error(ER(ER_GET_ERRNO), my_errno);
@@ -862,8 +864,8 @@ my_bool mysql_install_plugin(THD *thd, const LEX_STRING *name, const LEX_STRING
DBUG_RETURN(FALSE);
deinit:
plugin_deinitialize(tmp);
-err:
plugin_del(tmp);
+err:
rw_unlock(&THR_LOCK_plugin);
DBUG_RETURN(TRUE);
}
diff --git a/sql/sql_repl.h b/sql/sql_repl.h
index 45d3254dad0..789de64da85 100644
--- a/sql/sql_repl.h
+++ b/sql/sql_repl.h
@@ -24,7 +24,7 @@ typedef struct st_slave_info
uint32 server_id;
uint32 rpl_recovery_rank, master_id;
char host[HOSTNAME_LENGTH+1];
- char user[USERNAME_BYTE_LENGTH+1];
+ char user[USERNAME_LENGTH+1];
char password[MAX_PASSWORD_LENGTH+1];
uint16 port;
THD* thd;
diff --git a/sql/sql_select.cc b/sql/sql_select.cc
index 63b81c10067..ed91719fd46 100644
--- a/sql/sql_select.cc
+++ b/sql/sql_select.cc
@@ -70,7 +70,7 @@ static int join_tab_cmp_straight(const void* ptr1, const void* ptr2);
static void find_best(JOIN *join,table_map rest_tables,uint index,
double record_count,double read_time);
static uint cache_record_length(JOIN *join,uint index);
-static double prev_record_reads(JOIN *join,table_map found_ref);
+static double prev_record_reads(JOIN *join, uint idx, table_map found_ref);
static bool get_best_combination(JOIN *join);
static store_key *get_store_key(THD *thd,
KEYUSE *keyuse, table_map used_tables,
@@ -1137,17 +1137,28 @@ JOIN::optimize()
tmp_table_param.hidden_field_count= (all_fields.elements -
fields_list.elements);
+ ORDER *tmp_group= ((!simple_group && !procedure &&
+ !(test_flags & TEST_NO_KEY_GROUP)) ? group_list :
+ (ORDER*) 0);
+ /*
+ Pushing LIMIT to the temporary table creation is not applicable
+ when there is ORDER BY or GROUP BY or there is no GROUP BY, but
+ there are aggregate functions, because in all these cases we need
+ all result rows.
+ */
+ ha_rows tmp_rows_limit= ((order == 0 || skip_sort_order ||
+ test(select_options & OPTION_BUFFER_RESULT)) &&
+ !tmp_group &&
+ !thd->lex->current_select->with_sum_func) ?
+ select_limit : HA_POS_ERROR;
+
if (!(exec_tmp_table1=
create_tmp_table(thd, &tmp_table_param, all_fields,
- ((!simple_group && !procedure &&
- !(test_flags & TEST_NO_KEY_GROUP)) ?
- group_list : (ORDER*) 0),
+ tmp_group,
group_list ? 0 : select_distinct,
group_list && simple_group,
select_options,
- (order == 0 || skip_sort_order ||
- test(select_options & OPTION_BUFFER_RESULT)) ?
- select_limit : HA_POS_ERROR,
+ tmp_rows_limit,
(char *) "")))
DBUG_RETURN(1);
@@ -3426,6 +3437,7 @@ set_position(JOIN *join,uint idx,JOIN_TAB *table,KEYUSE *key)
join->positions[idx].table= table;
join->positions[idx].key=key;
join->positions[idx].records_read=1.0; /* This is a const table */
+ join->positions[idx].ref_depend_map= 0;
/* Move the const table as down as possible in best_ref */
JOIN_TAB **pos=join->best_ref+idx+1;
@@ -3483,6 +3495,7 @@ best_access_path(JOIN *join,
double best= DBL_MAX;
double best_time= DBL_MAX;
double records= DBL_MAX;
+ table_map best_ref_depends_map;
double tmp;
ha_rows rec;
@@ -3511,13 +3524,20 @@ best_access_path(JOIN *join,
/* Calculate how many key segments of the current key we can use */
start_key= keyuse;
- do
- { /* for each keypart */
+
+ do /* For each keypart */
+ {
uint keypart= keyuse->keypart;
table_map best_part_found_ref= 0;
double best_prev_record_reads= DBL_MAX;
- do
+
+ do /* For each way to access the keypart */
{
+
+ /*
+ if 1. expression doesn't refer to forward tables
+ 2. we won't get two ref-or-null's
+ */
if (!(remaining_tables & keyuse->used_tables) &&
!(ref_or_null_part && (keyuse->optimize &
KEY_OPTIMIZE_REF_OR_NULL)))
@@ -3525,8 +3545,9 @@ best_access_path(JOIN *join,
found_part|= keyuse->keypart_map;
if (!(keyuse->used_tables & ~join->const_table_map))
const_part|= keyuse->keypart_map;
- double tmp= prev_record_reads(join, (found_ref |
- keyuse->used_tables));
+
+ double tmp= prev_record_reads(join, idx, (found_ref |
+ keyuse->used_tables));
if (tmp < best_prev_record_reads)
{
best_part_found_ref= keyuse->used_tables & ~join->const_table_map;
@@ -3565,7 +3586,7 @@ best_access_path(JOIN *join,
Really, there should be records=0.0 (yes!)
but 1.0 would be probably safer
*/
- tmp= prev_record_reads(join, found_ref);
+ tmp= prev_record_reads(join, idx, found_ref);
records= 1.0;
}
else
@@ -3580,7 +3601,7 @@ best_access_path(JOIN *join,
max_key_part= (uint) ~0;
if ((keyinfo->flags & (HA_NOSAME | HA_NULL_PART_KEY)) == HA_NOSAME)
{
- tmp = prev_record_reads(join, found_ref);
+ tmp = prev_record_reads(join, idx, found_ref);
records=1.0;
}
else
@@ -3717,7 +3738,30 @@ best_access_path(JOIN *join,
{
/* Check if we have statistic about the distribution */
if ((records= keyinfo->rec_per_key[max_key_part-1]))
+ {
+ /*
+ Fix for the case where the index statistics is too
+ optimistic: If
+ (1) We're considering ref(const) and there is quick select
+ on the same index,
+ (2) and that quick select uses more keyparts (i.e. it will
+ scan equal/smaller interval then this ref(const))
+ (3) and E(#rows) for quick select is higher then our
+ estimate,
+ Then
+ We'll use E(#rows) from quick select.
+
+ Q: Why do we choose to use 'ref'? Won't quick select be
+ cheaper in some cases ?
+ TODO: figure this out and adjust the plan choice if needed.
+ */
+ if (!found_ref && table->quick_keys.is_set(key) && // (1)
+ table->quick_key_parts[key] > max_key_part && // (2)
+ records < (double)table->quick_rows[key]) // (3)
+ records= (double)table->quick_rows[key];
+
tmp= records;
+ }
else
{
/*
@@ -3810,6 +3854,7 @@ best_access_path(JOIN *join,
best_records= records;
best_key= start_key;
best_max_key_part= max_key_part;
+ best_ref_depends_map= found_ref;
}
}
records= best_records;
@@ -3938,6 +3983,8 @@ best_access_path(JOIN *join,
best= tmp;
records= rows2double(rnd_records);
best_key= 0;
+ /* range/index_merge/ALL/index access method are "independent", so: */
+ best_ref_depends_map= 0;
}
}
@@ -3946,6 +3993,7 @@ best_access_path(JOIN *join,
join->positions[idx].read_time= best;
join->positions[idx].key= best_key;
join->positions[idx].table= s;
+ join->positions[idx].ref_depend_map= best_ref_depends_map;
if (!best_key &&
idx == join->const_tables &&
@@ -4713,17 +4761,85 @@ cache_record_length(JOIN *join,uint idx)
}
+/*
+ Get the number of different row combinations for subset of partial join
+
+ SYNOPSIS
+ prev_record_reads()
+ join The join structure
+ idx Number of tables in the partial join order (i.e. the
+ partial join order is in join->positions[0..idx-1])
+ found_ref Bitmap of tables for which we need to find # of distinct
+ row combinations.
+
+ DESCRIPTION
+ Given a partial join order (in join->positions[0..idx-1]) and a subset of
+ tables within that join order (specified in found_ref), find out how many
+ distinct row combinations of subset tables will be in the result of the
+ partial join order.
+
+ This is used as follows: Suppose we have a table accessed with a ref-based
+ method. The ref access depends on current rows of tables in found_ref.
+ We want to count # of different ref accesses. We assume two ref accesses
+ will be different if at least one of access parameters is different.
+ Example: consider a query
+
+ SELECT * FROM t1, t2, t3 WHERE t1.key=c1 AND t2.key=c2 AND t3.key=t1.field
+
+ and a join order:
+ t1, ref access on t1.key=c1
+ t2, ref access on t2.key=c2
+ t3, ref access on t3.key=t1.field
+
+ For t1: n_ref_scans = 1, n_distinct_ref_scans = 1
+ For t2: n_ref_scans = records_read(t1), n_distinct_ref_scans=1
+ For t3: n_ref_scans = records_read(t1)*records_read(t2)
+ n_distinct_ref_scans = #records_read(t1)
+
+ The reason for having this function (at least the latest version of it)
+ is that we need to account for buffering in join execution.
+
+ An edge-case example: if we have a non-first table in join accessed via
+ ref(const) or ref(param) where there is a small number of different
+ values of param, then the access will likely hit the disk cache and will
+ not require any disk seeks.
+
+ The proper solution would be to assume an LRU disk cache of some size,
+ calculate probability of cache hits, etc. For now we just count
+ identical ref accesses as one.
+
+ RETURN
+ Expected number of row combinations
+*/
+
static double
-prev_record_reads(JOIN *join,table_map found_ref)
+prev_record_reads(JOIN *join, uint idx, table_map found_ref)
{
double found=1.0;
- found_ref&= ~OUTER_REF_TABLE_BIT;
- for (POSITION *pos=join->positions ; found_ref ; pos++)
+ POSITION *pos_end= join->positions - 1;
+ for (POSITION *pos= join->positions + idx - 1; pos != pos_end; pos--)
{
if (pos->table->table->map & found_ref)
{
- found_ref&= ~pos->table->table->map;
- found*=pos->records_read;
+ found_ref|= pos->ref_depend_map;
+ /*
+ For the case of "t1 LEFT JOIN t2 ON ..." where t2 is a const table
+ with no matching row we will get position[t2].records_read==0.
+ Actually the size of output is one null-complemented row, therefore
+ we will use value of 1 whenever we get records_read==0.
+
+ Note
+ - the above case can't occur if inner part of outer join has more
+ than one table: table with no matches will not be marked as const.
+
+ - Ideally we should add 1 to records_read for every possible null-
+ complemented row. We're not doing it because: 1. it will require
+ non-trivial code and add overhead. 2. The value of records_read
+ is an inprecise estimate and adding 1 (or, in the worst case,
+ #max_nested_outer_joins=64-1) will not make it any more precise.
+ */
+ if (pos->records_read)
+ found*= pos->records_read;
}
}
return found;
@@ -9197,6 +9313,13 @@ create_tmp_table(THD *thd,TMP_TABLE_PARAM *param,List<Item> &fields,
thd->variables.max_heap_table_size) :
thd->variables.tmp_table_size)/ share->reclength);
set_if_bigger(share->max_rows,1); // For dummy start options
+ /*
+ Push the LIMIT clause to the temporary table creation, so that we
+ materialize only up to 'rows_limit' records instead of all result records.
+ */
+ set_if_smaller(share->max_rows, rows_limit);
+ param->end_write_records= rows_limit;
+
keyinfo= param->keyinfo;
if (group)
@@ -9329,19 +9452,6 @@ create_tmp_table(THD *thd,TMP_TABLE_PARAM *param,List<Item> &fields,
}
}
- /*
- Push the LIMIT clause to the temporary table creation, so that we
- materialize only up to 'rows_limit' records instead of all result records.
- This optimization is not applicable when there is GROUP BY or there is
- no GROUP BY, but there are aggregate functions, because both must be
- computed for all result rows.
- */
- if (!group && !thd->lex->current_select->with_sum_func)
- {
- set_if_smaller(table->s->max_rows, rows_limit);
- param->end_write_records= rows_limit;
- }
-
if (thd->is_fatal_error) // If end of memory
goto err; /* purecov: inspected */
share->db_record_offset= 1;
@@ -10473,6 +10583,7 @@ join_read_const_table(JOIN_TAB *tab, POSITION *pos)
tab->info="const row not found";
/* Mark for EXPLAIN that the row was not found */
pos->records_read=0.0;
+ pos->ref_depend_map= 0;
if (!table->maybe_null || error > 0)
DBUG_RETURN(error);
}
@@ -10498,6 +10609,7 @@ join_read_const_table(JOIN_TAB *tab, POSITION *pos)
tab->info="unique row not found";
/* Mark for EXPLAIN that the row was not found */
pos->records_read=0.0;
+ pos->ref_depend_map= 0;
if (!table->maybe_null || error > 0)
DBUG_RETURN(error);
}
diff --git a/sql/sql_select.h b/sql/sql_select.h
index 3b0c312757d..eb6d2d5d34f 100644
--- a/sql/sql_select.h
+++ b/sql/sql_select.h
@@ -176,7 +176,13 @@ enum_nested_loop_state sub_select(JOIN *join,JOIN_TAB *join_tab, bool
*/
typedef struct st_position
{
+ /*
+ The "fanout": number of output rows that will be produced (after
+ pushed down selection condition is applied) per each row combination of
+ previous tables.
+ */
double records_read;
+
/*
Cost accessing the table in course of the entire complete join execution,
i.e. cost of one access method use (e.g. 'range' or 'ref' scan ) times
@@ -184,7 +190,15 @@ typedef struct st_position
*/
double read_time;
JOIN_TAB *table;
+
+ /*
+ NULL - 'index' or 'range' or 'index_merge' or 'ALL' access is used.
+ Other - [eq_]ref[_or_null] access is used. Pointer to {t.keypart1 = expr}
+ */
KEYUSE *key;
+
+ /* If ref-based access is used: bitmap of tables this table depends on */
+ table_map ref_depend_map;
} POSITION;
diff --git a/sql/sql_show.cc b/sql/sql_show.cc
index ce7832569fe..30f494a48ac 100644
--- a/sql/sql_show.cc
+++ b/sql/sql_show.cc
@@ -211,6 +211,22 @@ static my_bool show_plugins(THD *thd, st_plugin_int *plugin,
else
table->field[8]->set_null();
+ switch (plug->license) {
+ case PLUGIN_LICENSE_GPL:
+ table->field[9]->store(PLUGIN_LICENSE_GPL_STRING,
+ strlen(PLUGIN_LICENSE_GPL_STRING), cs);
+ break;
+ case PLUGIN_LICENSE_BSD:
+ table->field[9]->store(PLUGIN_LICENSE_BSD_STRING,
+ strlen(PLUGIN_LICENSE_BSD_STRING), cs);
+ break;
+ default:
+ table->field[9]->store(PLUGIN_LICENSE_PROPRIETARY_STRING,
+ strlen(PLUGIN_LICENSE_PROPRIETARY_STRING), cs);
+ break;
+ }
+ table->field[9]->set_notnull();
+
return schema_table_store_record(thd, table);
}
@@ -4999,7 +5015,7 @@ static my_bool run_hton_fill_schema_files(THD *thd, st_plugin_int *plugin,
(run_hton_fill_schema_files_args *) arg;
handlerton *hton= (handlerton *)plugin->data;
if(hton->fill_files_table && hton->state == SHOW_OPTION_YES)
- hton->fill_files_table(thd, args->tables, args->cond);
+ hton->fill_files_table(hton, thd, args->tables, args->cond);
return false;
}
@@ -5533,7 +5549,7 @@ ST_FIELD_INFO partitions_fields_info[]=
ST_FIELD_INFO variables_fields_info[]=
{
{"Variable_name", 80, MYSQL_TYPE_STRING, 0, 0, "Variable_name"},
- {"Value", 255, MYSQL_TYPE_STRING, 0, 0, "Value"},
+ {"Value", FN_REFLEN, MYSQL_TYPE_STRING, 0, 0, "Value"},
{0, 0, MYSQL_TYPE_STRING, 0, 0, 0}
};
@@ -5579,6 +5595,7 @@ ST_FIELD_INFO plugin_fields_info[]=
{"PLUGIN_LIBRARY_VERSION", 20, MYSQL_TYPE_STRING, 0, 1, 0},
{"PLUGIN_AUTHOR", NAME_LEN, MYSQL_TYPE_STRING, 0, 1, 0},
{"PLUGIN_DESCRIPTION", 65535, MYSQL_TYPE_STRING, 0, 1, 0},
+ {"PLUGIN_LICENSE", 80, MYSQL_TYPE_STRING, 0, 1, "License"},
{0, 0, MYSQL_TYPE_STRING, 0, 0, 0}
};
diff --git a/sql/sql_table.cc b/sql/sql_table.cc
index 4658ebb6cf4..7796bc35a79 100644
--- a/sql/sql_table.cc
+++ b/sql/sql_table.cc
@@ -1650,7 +1650,7 @@ int mysql_rm_table_part2(THD *thd, TABLE_LIST *tables, bool if_exists,
}
}
- if (lock_table_names(thd, tables))
+ if (!drop_temporary && lock_table_names(thd, tables))
DBUG_RETURN(1);
/* Don't give warnings for not found errors, as we already generate notes */
@@ -1835,7 +1835,8 @@ int mysql_rm_table_part2(THD *thd, TABLE_LIST *tables, bool if_exists,
}
}
- unlock_table_names(thd, tables, (TABLE_LIST*) 0);
+ if (!drop_temporary)
+ unlock_table_names(thd, tables, (TABLE_LIST*) 0);
thd->no_warnings_for_error= 0;
DBUG_RETURN(error);
}
diff --git a/sql/sql_tablespace.cc b/sql/sql_tablespace.cc
index 13dfb491af4..470fa5bc862 100644
--- a/sql/sql_tablespace.cc
+++ b/sql/sql_tablespace.cc
@@ -21,7 +21,7 @@
int mysql_alter_tablespace(THD *thd, st_alter_tablespace *ts_info)
{
int error= HA_ADMIN_NOT_IMPLEMENTED;
- const handlerton *hton= ts_info->storage_engine;
+ handlerton *hton= ts_info->storage_engine;
DBUG_ENTER("mysql_alter_tablespace");
/*
@@ -42,7 +42,7 @@ int mysql_alter_tablespace(THD *thd, st_alter_tablespace *ts_info)
if (hton->alter_tablespace)
{
- if ((error= hton->alter_tablespace(thd, ts_info)))
+ if ((error= hton->alter_tablespace(hton, thd, ts_info)))
{
if (error == HA_ADMIN_NOT_IMPLEMENTED)
{
diff --git a/sql/sql_trigger.h b/sql/sql_trigger.h
index b2464745f7c..09576f5e523 100644
--- a/sql/sql_trigger.h
+++ b/sql/sql_trigger.h
@@ -116,11 +116,6 @@ public:
bodies[TRG_EVENT_DELETE][TRG_ACTION_AFTER]);
}
- bool has_before_update_triggers()
- {
- return test(bodies[TRG_EVENT_UPDATE][TRG_ACTION_BEFORE]);
- }
-
void set_table(TABLE *new_table);
void mark_fields_used(trg_event_type event);
diff --git a/sql/sql_update.cc b/sql/sql_update.cc
index 3130220515a..51ec287a6cb 100644
--- a/sql/sql_update.cc
+++ b/sql/sql_update.cc
@@ -25,7 +25,7 @@
#include "sp_head.h"
#include "sql_trigger.h"
-static bool safe_update_on_fly(JOIN_TAB *join_tab, List<Item> *fields);
+static bool safe_update_on_fly(JOIN_TAB *join_tab);
/* Return 0 if row hasn't changed */
@@ -271,13 +271,16 @@ int mysql_update(THD *thd,
}
}
init_ftfuncs(thd, select_lex, 1);
+
+ table->mark_columns_needed_for_update();
+
/* Check if we are modifying a key that we are used to search with */
if (select && select->quick)
{
used_index= select->quick->index;
used_key_is_modified= (!select->quick->unique_key_range() &&
- select->quick->check_if_keys_used(&fields));
+ select->quick->is_keys_used(table->write_set));
}
else
{
@@ -285,12 +288,13 @@ int mysql_update(THD *thd,
if (used_index == MAX_KEY) // no index for sort order
used_index= table->file->key_used_on_scan;
if (used_index != MAX_KEY)
- used_key_is_modified= check_if_key_used(table, used_index, fields);
+ used_key_is_modified= is_key_used(table, used_index, table->write_set);
}
+
#ifdef WITH_PARTITION_STORAGE_ENGINE
if (used_key_is_modified || order ||
- partition_key_modified(table, fields))
+ partition_key_modified(table, table->write_set))
#else
if (used_key_is_modified || order)
#endif
@@ -449,8 +453,6 @@ int mysql_update(THD *thd,
MODE_STRICT_ALL_TABLES)));
will_batch= !table->file->start_bulk_update();
- table->mark_columns_needed_for_update();
-
/*
We can use compare_record() to optimize away updates if
the table handler is returning all columns OR if
@@ -1215,9 +1217,11 @@ multi_update::initialize_tables(JOIN *join)
TMP_TABLE_PARAM *tmp_param;
table->mark_columns_needed_for_update();
+ if (ignore)
+ table->file->extra(HA_EXTRA_IGNORE_DUP_KEY);
if (table == main_table) // First table in join
{
- if (safe_update_on_fly(join->join_tab, &temp_fields))
+ if (safe_update_on_fly(join->join_tab))
{
table_to_update= main_table; // Update table on the fly
continue;
@@ -1275,7 +1279,6 @@ multi_update::initialize_tables(JOIN *join)
SYNOPSIS
safe_update_on_fly
join_tab How table is used in join
- fields Fields that are updated
NOTES
We can update the first table in join on the fly if we know that
@@ -1288,9 +1291,8 @@ multi_update::initialize_tables(JOIN *join)
- We are doing a range scan and we don't update the scan key or
the primary key for a clustered table handler.
- When checking for above cases we also should take into account that
- BEFORE UPDATE trigger potentially may change value of any field in row
- being updated.
+ This function gets information about fields to be updated from
+ the TABLE::write_set bitmap.
WARNING
This code is a bit dependent of how make_join_readinfo() works.
@@ -1300,7 +1302,7 @@ multi_update::initialize_tables(JOIN *join)
1 Safe to update
*/
-static bool safe_update_on_fly(JOIN_TAB *join_tab, List<Item> *fields)
+static bool safe_update_on_fly(JOIN_TAB *join_tab)
{
TABLE *table= join_tab->table;
switch (join_tab->type) {
@@ -1310,21 +1312,15 @@ static bool safe_update_on_fly(JOIN_TAB *join_tab, List<Item> *fields)
return TRUE; // At most one matching row
case JT_REF:
case JT_REF_OR_NULL:
- return !check_if_key_used(table, join_tab->ref.key, *fields) &&
- !(table->triggers &&
- table->triggers->has_before_update_triggers());
+ return !is_key_used(table, join_tab->ref.key, table->write_set);
case JT_ALL:
/* If range search on index */
if (join_tab->quick)
- return !join_tab->quick->check_if_keys_used(fields) &&
- !(table->triggers &&
- table->triggers->has_before_update_triggers());
+ return !join_tab->quick->is_keys_used(table->write_set);
/* If scanning in clustered key */
if ((table->file->ha_table_flags() & HA_PRIMARY_KEY_IN_READ_INDEX) &&
table->s->primary_key < MAX_KEY)
- return !check_if_key_used(table, table->s->primary_key, *fields) &&
- !(table->triggers &&
- table->triggers->has_before_update_triggers());
+ return !is_key_used(table, table->s->primary_key, table->write_set);
return TRUE;
default:
break; // Avoid compler warning
@@ -1337,7 +1333,11 @@ multi_update::~multi_update()
{
TABLE_LIST *table;
for (table= update_tables ; table; table= table->next_local)
+ {
table->table->no_keyread= table->table->no_cache= 0;
+ if (ignore)
+ table->table->file->extra(HA_EXTRA_NO_IGNORE_DUP_KEY);
+ }
if (tmp_tables)
{
diff --git a/sql/sql_view.cc b/sql/sql_view.cc
index 187d289cb16..7f6d935ff5e 100644
--- a/sql/sql_view.cc
+++ b/sql/sql_view.cc
@@ -1603,7 +1603,7 @@ bool insert_view_fields(THD *thd, List<Item> *list, TABLE_LIST *view)
list->push_back(fld);
else
{
- my_error(ER_NON_UPDATABLE_TABLE, MYF(0), view->alias, "INSERT");
+ my_error(ER_NON_INSERTABLE_TABLE, MYF(0), view->alias, "INSERT");
DBUG_RETURN(TRUE);
}
}
diff --git a/sql/sql_yacc.yy b/sql/sql_yacc.yy
index fd53983c33f..26dea00029a 100644
--- a/sql/sql_yacc.yy
+++ b/sql/sql_yacc.yy
@@ -1353,7 +1353,7 @@ event_tail:
Lex->sql_command= SQLCOM_CREATE_EVENT;
Lex->expr_allows_subselect= TRUE;
}
-
+ ;
ev_schedule_time: EVERY_SYM expr interval
{
@@ -1366,7 +1366,7 @@ ev_schedule_time: EVERY_SYM expr interval
{
Lex->event_parse_data->item_execute_at= $2;
}
- ;
+ ;
opt_ev_status: /* empty */ { $$= 0; }
| ENABLE_SYM
@@ -6853,11 +6853,13 @@ join_table:
/* Change the current name resolution context to a local context. */
if (push_new_name_resolution_context(YYTHD, $1, $3))
YYABORT;
+ Select->parsing_place= IN_ON;
}
expr
{
add_join_on($3,$6);
Lex->pop_context();
+ Select->parsing_place= NO_MATTER;
}
| table_ref STRAIGHT_JOIN table_factor
ON
@@ -6866,12 +6868,14 @@ join_table:
/* Change the current name resolution context to a local context. */
if (push_new_name_resolution_context(YYTHD, $1, $3))
YYABORT;
+ Select->parsing_place= IN_ON;
}
expr
{
$3->straight=1;
add_join_on($3,$6);
Lex->pop_context();
+ Select->parsing_place= NO_MATTER;
}
| table_ref normal_join table_ref
USING
@@ -6895,6 +6899,7 @@ join_table:
/* Change the current name resolution context to a local context. */
if (push_new_name_resolution_context(YYTHD, $1, $5))
YYABORT;
+ Select->parsing_place= IN_ON;
}
expr
{
@@ -6902,6 +6907,7 @@ join_table:
Lex->pop_context();
$5->outer_join|=JOIN_TYPE_LEFT;
$$=$5;
+ Select->parsing_place= NO_MATTER;
}
| table_ref LEFT opt_outer JOIN_SYM table_factor
{
@@ -6926,6 +6932,7 @@ join_table:
/* Change the current name resolution context to a local context. */
if (push_new_name_resolution_context(YYTHD, $1, $5))
YYABORT;
+ Select->parsing_place= IN_ON;
}
expr
{
@@ -6934,6 +6941,7 @@ join_table:
YYABORT;
add_join_on($$, $8);
Lex->pop_context();
+ Select->parsing_place= NO_MATTER;
}
| table_ref RIGHT opt_outer JOIN_SYM table_factor
{
@@ -9243,7 +9251,7 @@ user:
$$->host.str= (char *) "%";
$$->host.length= 1;
- if (check_string_length(system_charset_info, &$$->user,
+ if (check_string_length(&$$->user,
ER(ER_USERNAME), USERNAME_LENGTH))
YYABORT;
}
@@ -9254,9 +9262,9 @@ user:
YYABORT;
$$->user = $1; $$->host=$3;
- if (check_string_length(system_charset_info, &$$->user,
+ if (check_string_length(&$$->user,
ER(ER_USERNAME), USERNAME_LENGTH) ||
- check_string_length(&my_charset_latin1, &$$->host,
+ check_string_length(&$$->host,
ER(ER_HOSTNAME), HOSTNAME_LENGTH))
YYABORT;
}
diff --git a/sql/stacktrace.c b/sql/stacktrace.c
index 43f35c452f7..a2fe2ab88f1 100644
--- a/sql/stacktrace.c
+++ b/sql/stacktrace.c
@@ -222,7 +222,7 @@ terribly wrong...\n");
fprintf(stderr, "Stack trace seems successful - bottom reached\n");
end:
- fprintf(stderr, "Please read http://dev.mysql.com/doc/mysql/en/Using_stack_trace.html and follow instructions on how to resolve the stack trace. Resolved\n\
+ fprintf(stderr, "Please read http://dev.mysql.com/doc/mysql/en/using-stack-trace.html and follow instructions on how to resolve the stack trace. Resolved\n\
stack trace is much more helpful in diagnosing the problem, so please do \n\
resolve it\n");
}
diff --git a/sql/table.cc b/sql/table.cc
index 834c2ed9c82..5b41ad48696 100644
--- a/sql/table.cc
+++ b/sql/table.cc
@@ -2257,7 +2257,7 @@ char *get_field(MEM_ROOT *mem, Field *field)
bool check_db_name(char *name)
{
- uint name_length= 0; // name length in symbols
+ char *start= name;
/* Used to catch empty names and names with end space */
bool last_char_is_space= TRUE;
@@ -2277,15 +2277,13 @@ bool check_db_name(char *name)
name += len;
continue;
}
- name_length++;
}
#else
last_char_is_space= *name==' ';
#endif
- name_length++;
name++;
}
- return last_char_is_space || name_length > NAME_LEN;
+ return last_char_is_space || (uint) (name - start) > NAME_LEN;
}
diff --git a/sql/unireg.cc b/sql/unireg.cc
index 396ff4fba27..2ea572c782c 100644
--- a/sql/unireg.cc
+++ b/sql/unireg.cc
@@ -292,13 +292,19 @@ bool mysql_create_frm(THD *thd, const char *file_name,
goto err3;
{
- /* Unescape all UCS2 intervals: were escaped in pack_headers */
+ /*
+ Restore all UCS2 intervals.
+ HEX representation of them is not needed anymore.
+ */
List_iterator<create_field> it(create_fields);
create_field *field;
while ((field=it++))
{
- if (field->interval && field->charset->mbminlen > 1)
- unhex_type2(field->interval);
+ if (field->save_interval)
+ {
+ field->interval= field->save_interval;
+ field->save_interval= 0;
+ }
}
}
DBUG_RETURN(0);
@@ -589,18 +595,36 @@ static bool pack_header(uchar *forminfo, enum legacy_db_type table_type,
reclength=(uint) (field->offset+ data_offset + length);
n_length+= (ulong) strlen(field->field_name)+1;
field->interval_id=0;
+ field->save_interval= 0;
if (field->interval)
{
uint old_int_count=int_count;
if (field->charset->mbminlen > 1)
{
- /* Escape UCS2 intervals using HEX notation */
+ /*
+ Escape UCS2 intervals using HEX notation to avoid
+ problems with delimiters between enum elements.
+ As the original representation is still needed in
+ the function make_empty_rec to create a record of
+ filled with default values it is saved in save_interval
+ The HEX representation is created from this copy.
+ */
+ field->save_interval= field->interval;
+ field->interval= (TYPELIB*) sql_alloc(sizeof(TYPELIB));
+ *field->interval= *field->save_interval;
+ field->interval->type_names=
+ (const char **) sql_alloc(sizeof(char*) *
+ (field->interval->count+1));
+ field->interval->type_names[field->interval->count]= 0;
+ field->interval->type_lengths=
+ (uint *) sql_alloc(sizeof(uint) * field->interval->count);
+
for (uint pos= 0; pos < field->interval->count; pos++)
{
char *dst;
- uint length= field->interval->type_lengths[pos], hex_length;
- const char *src= field->interval->type_names[pos];
+ uint length= field->save_interval->type_lengths[pos], hex_length;
+ const char *src= field->save_interval->type_names[pos];
hex_length= length * 2;
field->interval->type_lengths[pos]= hex_length;
field->interval->type_names[pos]= dst= sql_alloc(hex_length + 1);
@@ -852,7 +876,8 @@ static bool make_empty_rec(THD *thd, File file,enum legacy_db_type table_type,
field->charset,
field->geom_type,
field->unireg_check,
- field->interval,
+ field->save_interval ? field->save_interval :
+ field->interval,
field->field_name);
if (!regfield)
goto err; // End of memory
diff --git a/storage/archive/ha_archive.cc b/storage/archive/ha_archive.cc
index c31bbfd612e..b7673fc96ea 100644
--- a/storage/archive/ha_archive.cc
+++ b/storage/archive/ha_archive.cc
@@ -139,17 +139,21 @@ static HASH archive_open_tables;
#define ARCHIVE_CHECK_HEADER 254 // The number we use to determine corruption
/* Static declarations for handerton */
-static handler *archive_create_handler(TABLE_SHARE *table, MEM_ROOT *mem_root);
+static handler *archive_create_handler(handlerton *hton,
+ TABLE_SHARE *table,
+ MEM_ROOT *mem_root);
+int archive_db_end(handlerton *hton, ha_panic_function type);
+
/*
Number of rows that will force a bulk insert.
*/
#define ARCHIVE_MIN_ROWS_TO_USE_BULK_INSERT 2
-handlerton *archive_hton;
-
-static handler *archive_create_handler(TABLE_SHARE *table, MEM_ROOT *mem_root)
+static handler *archive_create_handler(handlerton *hton,
+ TABLE_SHARE *table,
+ MEM_ROOT *mem_root)
{
- return new (mem_root) ha_archive(table);
+ return new (mem_root) ha_archive(hton, table);
}
/*
@@ -178,6 +182,7 @@ static byte* archive_get_key(ARCHIVE_SHARE *share,uint *length,
int archive_db_init(void *p)
{
DBUG_ENTER("archive_db_init");
+ handlerton *archive_hton;
if (archive_inited)
DBUG_RETURN(FALSE);
archive_hton= (handlerton *)p;
@@ -226,13 +231,13 @@ int archive_db_done(void *p)
}
-int archive_db_end(ha_panic_function type)
+int archive_db_end(handlerton *hton, ha_panic_function type)
{
return archive_db_done(NULL);
}
-ha_archive::ha_archive(TABLE_SHARE *table_arg)
- :handler(archive_hton, table_arg), delayed_insert(0), bulk_insert(0)
+ha_archive::ha_archive(handlerton *hton, TABLE_SHARE *table_arg)
+ :handler(hton, table_arg), delayed_insert(0), bulk_insert(0)
{
/* Set our original buffer from pre-allocated memory */
buffer.set((char *)byte_buffer, IO_SIZE, system_charset_info);
@@ -1571,7 +1576,7 @@ bool ha_archive::check_and_repair(THD *thd)
}
struct st_mysql_storage_engine archive_storage_engine=
-{ MYSQL_HANDLERTON_INTERFACE_VERSION, archive_hton };
+{ MYSQL_HANDLERTON_INTERFACE_VERSION };
mysql_declare_plugin(archive)
{
@@ -1580,6 +1585,7 @@ mysql_declare_plugin(archive)
"ARCHIVE",
"Brian Aker, MySQL AB",
"Archive storage engine",
+ PLUGIN_LICENSE_GPL,
archive_db_init, /* Plugin Init */
archive_db_done, /* Plugin Deinit */
0x0100 /* 1.0 */,
diff --git a/storage/archive/ha_archive.h b/storage/archive/ha_archive.h
index d1069afd87f..1a601c8451a 100644
--- a/storage/archive/ha_archive.h
+++ b/storage/archive/ha_archive.h
@@ -67,7 +67,7 @@ class ha_archive: public handler
uint current_k_offset;
public:
- ha_archive(TABLE_SHARE *table_arg);
+ ha_archive(handlerton *hton, TABLE_SHARE *table_arg);
~ha_archive()
{
}
@@ -139,5 +139,3 @@ public:
bool check_and_repair(THD *thd);
};
-int archive_db_end(ha_panic_function type);
-
diff --git a/storage/blackhole/ha_blackhole.cc b/storage/blackhole/ha_blackhole.cc
index bef5ee656fe..2515f059e02 100644
--- a/storage/blackhole/ha_blackhole.cc
+++ b/storage/blackhole/ha_blackhole.cc
@@ -24,11 +24,11 @@
/* Static declarations for handlerton */
-handlerton *blackhole_hton;
-static handler *blackhole_create_handler(TABLE_SHARE *table,
+static handler *blackhole_create_handler(handlerton *hton,
+ TABLE_SHARE *table,
MEM_ROOT *mem_root)
{
- return new (mem_root) ha_blackhole(table);
+ return new (mem_root) ha_blackhole(hton, table);
}
@@ -36,8 +36,9 @@ static handler *blackhole_create_handler(TABLE_SHARE *table,
** BLACKHOLE tables
*****************************************************************************/
-ha_blackhole::ha_blackhole(TABLE_SHARE *table_arg)
- :handler(blackhole_hton, table_arg)
+ha_blackhole::ha_blackhole(handlerton *hton,
+ TABLE_SHARE *table_arg)
+ :handler(hton, table_arg)
{}
@@ -203,6 +204,7 @@ int ha_blackhole::index_last(byte * buf)
static int blackhole_init(void *p)
{
+ handlerton *blackhole_hton;
blackhole_hton= (handlerton *)p;
blackhole_hton->state= SHOW_OPTION_YES;
blackhole_hton->db_type= DB_TYPE_BLACKHOLE_DB;
@@ -212,7 +214,7 @@ static int blackhole_init(void *p)
}
struct st_mysql_storage_engine blackhole_storage_engine=
-{ MYSQL_HANDLERTON_INTERFACE_VERSION, blackhole_hton };
+{ MYSQL_HANDLERTON_INTERFACE_VERSION };
mysql_declare_plugin(blackhole)
{
@@ -221,6 +223,7 @@ mysql_declare_plugin(blackhole)
"BLACKHOLE",
"MySQL AB",
"/dev/null storage engine (anything you write to it disappears)",
+ PLUGIN_LICENSE_GPL,
blackhole_init, /* Plugin Init */
NULL, /* Plugin Deinit */
0x0100 /* 1.0 */,
diff --git a/storage/blackhole/ha_blackhole.h b/storage/blackhole/ha_blackhole.h
index 55c26f6f02e..54cec41fd26 100644
--- a/storage/blackhole/ha_blackhole.h
+++ b/storage/blackhole/ha_blackhole.h
@@ -28,7 +28,7 @@ class ha_blackhole: public handler
THR_LOCK thr_lock;
public:
- ha_blackhole(TABLE_SHARE *table_arg);
+ ha_blackhole(handlerton *hton, TABLE_SHARE *table_arg);
~ha_blackhole()
{
}
diff --git a/storage/csv/ha_tina.cc b/storage/csv/ha_tina.cc
index eaa11d5b061..dad28a74af6 100644
--- a/storage/csv/ha_tina.cc
+++ b/storage/csv/ha_tina.cc
@@ -74,7 +74,11 @@ static int write_meta_file(File meta_file, ha_rows rows, bool dirty);
pthread_mutex_t tina_mutex;
static HASH tina_open_tables;
static int tina_init= 0;
-static handler *tina_create_handler(TABLE_SHARE *table, MEM_ROOT *mem_root);
+static handler *tina_create_handler(handlerton *hton,
+ TABLE_SHARE *table,
+ MEM_ROOT *mem_root);
+int tina_end(handlerton *hton, ha_panic_function type);
+
off_t Transparent_file::read_next()
{
@@ -123,7 +127,6 @@ char Transparent_file::get_value(off_t offset)
return buff[0];
}
}
-handlerton *tina_hton;
/*****************************************************************************
** TINA tables
@@ -150,6 +153,8 @@ static byte* tina_get_key(TINA_SHARE *share,uint *length,
static int tina_init_func(void *p)
{
+ handlerton *tina_hton;
+
if (!tina_init)
{
tina_hton= (handlerton *)p;
@@ -161,7 +166,8 @@ static int tina_init_func(void *p)
tina_hton->db_type= DB_TYPE_CSV_DB;
tina_hton->create= tina_create_handler;
tina_hton->panic= tina_end;
- tina_hton->flags= HTON_CAN_RECREATE | HTON_SUPPORT_LOG_TABLES;
+ tina_hton->flags= (HTON_CAN_RECREATE | HTON_SUPPORT_LOG_TABLES |
+ HTON_NO_PARTITION);
}
return 0;
}
@@ -449,7 +455,7 @@ static int free_share(TINA_SHARE *share)
DBUG_RETURN(result_code);
}
-int tina_end(ha_panic_function type)
+int tina_end(handlerton *hton, ha_panic_function type)
{
return tina_done_func(NULL);
}
@@ -493,14 +499,16 @@ off_t find_eoln_buff(Transparent_file *data_buff, off_t begin,
}
-static handler *tina_create_handler(TABLE_SHARE *table, MEM_ROOT *mem_root)
+static handler *tina_create_handler(handlerton *hton,
+ TABLE_SHARE *table,
+ MEM_ROOT *mem_root)
{
- return new (mem_root) ha_tina(table);
+ return new (mem_root) ha_tina(hton, table);
}
-ha_tina::ha_tina(TABLE_SHARE *table_arg)
- :handler(tina_hton, table_arg),
+ha_tina::ha_tina(handlerton *hton, TABLE_SHARE *table_arg)
+ :handler(hton, table_arg),
/*
These definitions are found in handler.h
They are not probably completely right.
@@ -540,7 +548,10 @@ int ha_tina::encode_quote(byte *buf)
in the code.
*/
if ((*field)->is_null())
- ptr= end_ptr= 0;
+ {
+ buffer.append(STRING_WITH_LEN("\"\","));
+ continue;
+ }
else
{
(*field)->val_str(&attribute,&attribute);
@@ -641,6 +652,7 @@ int ha_tina::find_current_row(byte *buf)
off_t end_offset, curr_offset= current_position;
int eoln_len;
my_bitmap_map *org_bitmap;
+ int error;
DBUG_ENTER("ha_tina::find_current_row");
/*
@@ -654,23 +666,23 @@ int ha_tina::find_current_row(byte *buf)
/* Avoid asserts in ::store() for columns that are not going to be updated */
org_bitmap= dbug_tmp_use_all_columns(table, table->write_set);
+ error= HA_ERR_CRASHED_ON_USAGE;
+
+ memset(buf, 0, table->s->null_bytes);
for (Field **field=table->field ; *field ; field++)
{
buffer.length(0);
- if (file_buff->get_value(curr_offset) == '"')
+ if (curr_offset < end_offset &&
+ file_buff->get_value(curr_offset) == '"')
curr_offset++; // Incrementpast the first quote
else
- {
- dbug_tmp_restore_column_map(table->write_set, org_bitmap);
- DBUG_RETURN(HA_ERR_CRASHED_ON_USAGE);
- }
- for(;curr_offset != end_offset; curr_offset++)
+ goto err;
+ for(;curr_offset < end_offset; curr_offset++)
{
// Need to convert line feeds!
if (file_buff->get_value(curr_offset) == '"' &&
- (((file_buff->get_value(curr_offset + 1) == ',') &&
- (file_buff->get_value(curr_offset + 2) == '"')) ||
+ ((file_buff->get_value(curr_offset + 1) == ',') ||
(curr_offset == end_offset -1 )))
{
curr_offset+= 2; // Move past the , and the "
@@ -700,10 +712,7 @@ int ha_tina::find_current_row(byte *buf)
we are working with a damaged file.
*/
if (curr_offset == end_offset - 1)
- {
- dbug_tmp_restore_column_map(table->write_set, org_bitmap);
- DBUG_RETURN(HA_ERR_CRASHED_ON_USAGE);
- }
+ goto err;
buffer.append(file_buff->get_value(curr_offset));
}
}
@@ -711,11 +720,12 @@ int ha_tina::find_current_row(byte *buf)
(*field)->store(buffer.ptr(), buffer.length(), system_charset_info);
}
next_position= end_offset + eoln_len;
- /* Maybe use \N for null? */
- memset(buf, 0, table->s->null_bytes); /* We do not implement nulls! */
+ error= 0;
+
+err:
dbug_tmp_restore_column_map(table->write_set, org_bitmap);
- DBUG_RETURN(0);
+ DBUG_RETURN(error);
}
/*
@@ -1516,7 +1526,7 @@ bool ha_tina::check_if_incompatible_data(HA_CREATE_INFO *info,
}
struct st_mysql_storage_engine csv_storage_engine=
-{ MYSQL_HANDLERTON_INTERFACE_VERSION, tina_hton };
+{ MYSQL_HANDLERTON_INTERFACE_VERSION };
mysql_declare_plugin(csv)
{
@@ -1525,6 +1535,7 @@ mysql_declare_plugin(csv)
"CSV",
"Brian Aker, MySQL AB",
"CSV storage engine",
+ PLUGIN_LICENSE_GPL,
tina_init_func, /* Plugin Init */
tina_done_func, /* Plugin Deinit */
0x0100 /* 1.0 */,
diff --git a/storage/csv/ha_tina.h b/storage/csv/ha_tina.h
index 14ca848c855..f408e8f4a7d 100644
--- a/storage/csv/ha_tina.h
+++ b/storage/csv/ha_tina.h
@@ -129,7 +129,7 @@ private:
int init_tina_writer();
public:
- ha_tina(TABLE_SHARE *table_arg);
+ ha_tina(handlerton *hton, TABLE_SHARE *table_arg);
~ha_tina()
{
if (chain_alloced)
@@ -212,5 +212,3 @@ public:
int chain_append();
};
-int tina_end(ha_panic_function type);
-
diff --git a/storage/example/ha_example.cc b/storage/example/ha_example.cc
index c4c2524a118..212def8c18e 100644
--- a/storage/example/ha_example.cc
+++ b/storage/example/ha_example.cc
@@ -73,7 +73,9 @@
#include <mysql/plugin.h>
-static handler *example_create_handler(TABLE_SHARE *table, MEM_ROOT *mem_root);
+static handler *example_create_handler(handlerton *hton,
+ TABLE_SHARE *table,
+ MEM_ROOT *mem_root);
static int example_init_func();
static bool example_init_func_for_handlerton();
static int example_panic(enum ha_panic_function flag);
@@ -201,14 +203,16 @@ static int free_share(EXAMPLE_SHARE *share)
}
-static handler* example_create_handler(TABLE_SHARE *table, MEM_ROOT *mem_root)
+static handler* example_create_handler(handlerton *hton,
+ TABLE_SHARE *table,
+ MEM_ROOT *mem_root)
{
- return new (mem_root) ha_example(table);
+ return new (mem_root) ha_example(hton, table);
}
-ha_example::ha_example(TABLE_SHARE *table_arg)
- :handler(example_hton, table_arg)
+ha_example::ha_example(handlerton *hton, TABLE_SHARE *table_arg)
+ :handler(hton, table_arg)
{}
/*
@@ -703,7 +707,7 @@ int ha_example::create(const char *name, TABLE *table_arg,
}
struct st_mysql_storage_engine example_storage_engine=
-{ MYSQL_HANDLERTON_INTERFACE_VERSION, example_hton };
+{ MYSQL_HANDLERTON_INTERFACE_VERSION };
mysql_declare_plugin(example)
@@ -713,6 +717,7 @@ mysql_declare_plugin(example)
"EXAMPLE",
"Brian Aker, MySQL AB",
"Example storage engine",
+ PLUGIN_LICENSE_GPL,
example_init_func, /* Plugin Init */
example_done_func, /* Plugin Deinit */
0x0001 /* 0.1 */,
diff --git a/storage/example/ha_example.h b/storage/example/ha_example.h
index 956dc62311c..2f5dbc29c56 100644
--- a/storage/example/ha_example.h
+++ b/storage/example/ha_example.h
@@ -45,7 +45,7 @@ class ha_example: public handler
EXAMPLE_SHARE *share; /* Shared lock info */
public:
- ha_example(TABLE_SHARE *table_arg);
+ ha_example(handlerton *hton, TABLE_SHARE *table_arg);
~ha_example()
{
}
diff --git a/storage/federated/ha_federated.cc b/storage/federated/ha_federated.cc
index 3bb34e5aacc..00b2ac87cd4 100644
--- a/storage/federated/ha_federated.cc
+++ b/storage/federated/ha_federated.cc
@@ -359,19 +359,22 @@ static const uint sizeof_trailing_and= sizeof(" AND ") - 1;
static const uint sizeof_trailing_where= sizeof(" WHERE ") - 1;
/* Static declaration for handerton */
-static handler *federated_create_handler(TABLE_SHARE *table,
+static handler *federated_create_handler(handlerton *hton,
+ TABLE_SHARE *table,
MEM_ROOT *mem_root);
-static int federated_commit(THD *thd, bool all);
-static int federated_rollback(THD *thd, bool all);
+static int federated_commit(handlerton *hton, THD *thd, bool all);
+static int federated_rollback(handlerton *hton, THD *thd, bool all);
+static int federated_db_init(void);
+static int federated_db_end(handlerton *hton, ha_panic_function type);
-/* Federated storage engine handlerton */
-handlerton *federated_hton;
+/* Federated storage engine handlerton */
-static handler *federated_create_handler(TABLE_SHARE *table,
+static handler *federated_create_handler(handlerton *hton,
+ TABLE_SHARE *table,
MEM_ROOT *mem_root)
{
- return new (mem_root) ha_federated(table);
+ return new (mem_root) ha_federated(hton, table);
}
@@ -399,7 +402,7 @@ static byte *federated_get_key(FEDERATED_SHARE *share, uint *length,
int federated_db_init(void *p)
{
DBUG_ENTER("federated_db_init");
- federated_hton= (handlerton *)p;
+ handlerton *federated_hton= (handlerton *)p;
federated_hton->state= SHOW_OPTION_YES;
federated_hton->db_type= DB_TYPE_FEDERATED_DB;
federated_hton->commit= federated_commit;
@@ -434,7 +437,7 @@ error:
FALSE OK
*/
-int federated_db_end(ha_panic_function type)
+int federated_db_end(handlerton *hton, ha_panic_function type)
{
if (federated_init)
{
@@ -723,8 +726,9 @@ error:
** FEDERATED tables
*****************************************************************************/
-ha_federated::ha_federated(TABLE_SHARE *table_arg)
- :handler(federated_hton, table_arg),
+ha_federated::ha_federated(handlerton *hton,
+ TABLE_SHARE *table_arg)
+ :handler(hton, table_arg),
mysql(0), stored_result(0)
{
trx_next= 0;
@@ -2736,7 +2740,7 @@ bool ha_federated::get_error_message(int error, String* buf)
int ha_federated::external_lock(THD *thd, int lock_type)
{
int error= 0;
- ha_federated *trx= (ha_federated *)thd->ha_data[federated_hton->slot];
+ ha_federated *trx= (ha_federated *)thd->ha_data[ht->slot];
DBUG_ENTER("ha_federated::external_lock");
if (lock_type != F_UNLCK)
@@ -2754,7 +2758,7 @@ int ha_federated::external_lock(THD *thd, int lock_type)
DBUG_PRINT("info", ("error setting autocommit TRUE: %d", error));
DBUG_RETURN(error);
}
- trans_register_ha(thd, FALSE, federated_hton);
+ trans_register_ha(thd, FALSE, ht);
}
else
{
@@ -2770,8 +2774,8 @@ int ha_federated::external_lock(THD *thd, int lock_type)
DBUG_PRINT("info", ("error setting autocommit FALSE: %d", error));
DBUG_RETURN(error);
}
- thd->ha_data[federated_hton->slot]= this;
- trans_register_ha(thd, TRUE, federated_hton);
+ thd->ha_data[ht->slot]= this;
+ trans_register_ha(thd, TRUE, ht);
/*
Send a lock table to the remote end.
We do not support this at the moment
@@ -2796,10 +2800,10 @@ int ha_federated::external_lock(THD *thd, int lock_type)
}
-static int federated_commit(THD *thd, bool all)
+static int federated_commit(handlerton *hton, THD *thd, bool all)
{
int return_val= 0;
- ha_federated *trx= (ha_federated *)thd->ha_data[federated_hton->slot];
+ ha_federated *trx= (ha_federated *)thd->ha_data[hton->slot];
DBUG_ENTER("federated_commit");
if (all)
@@ -2814,7 +2818,7 @@ static int federated_commit(THD *thd, bool all)
if (error && !return_val);
return_val= error;
}
- thd->ha_data[federated_hton->slot]= NULL;
+ thd->ha_data[hton->slot]= NULL;
}
DBUG_PRINT("info", ("error val: %d", return_val));
@@ -2822,10 +2826,10 @@ static int federated_commit(THD *thd, bool all)
}
-static int federated_rollback(THD *thd, bool all)
+static int federated_rollback(handlerton *hton, THD *thd, bool all)
{
int return_val= 0;
- ha_federated *trx= (ha_federated *)thd->ha_data[federated_hton->slot];
+ ha_federated *trx= (ha_federated *)thd->ha_data[hton->slot];
DBUG_ENTER("federated_rollback");
if (all)
@@ -2840,7 +2844,7 @@ static int federated_rollback(THD *thd, bool all)
if (error && !return_val)
return_val= error;
}
- thd->ha_data[federated_hton->slot]= NULL;
+ thd->ha_data[hton->slot]= NULL;
}
DBUG_PRINT("info", ("error val: %d", return_val));
@@ -2882,7 +2886,7 @@ int ha_federated::execute_simple_query(const char *query, int len)
}
struct st_mysql_storage_engine federated_storage_engine=
-{ MYSQL_HANDLERTON_INTERFACE_VERSION, federated_hton };
+{ MYSQL_HANDLERTON_INTERFACE_VERSION };
mysql_declare_plugin(federated)
{
@@ -2891,6 +2895,7 @@ mysql_declare_plugin(federated)
"FEDERATED",
"Patrick Galbraith and Brian Aker, MySQL AB",
"Federated MySQL storage engine",
+ PLUGIN_LICENSE_GPL,
federated_db_init, /* Plugin Init */
NULL, /* Plugin Deinit */
0x0100 /* 1.0 */,
diff --git a/storage/federated/ha_federated.h b/storage/federated/ha_federated.h
index ebdc775d3bf..ade1e5b181e 100644
--- a/storage/federated/ha_federated.h
+++ b/storage/federated/ha_federated.h
@@ -94,7 +94,7 @@ private:
int stash_remote_error();
public:
- ha_federated(TABLE_SHARE *table_arg);
+ ha_federated(handlerton *hton, TABLE_SHARE *table_arg);
~ha_federated() {}
/* The name that will be used for display purposes */
const char *table_type() const { return "FEDERATED"; }
@@ -236,6 +236,3 @@ public:
MYSQL_RES **result);
};
-int federated_db_init(void);
-int federated_db_end(ha_panic_function type);
-
diff --git a/storage/heap/ha_heap.cc b/storage/heap/ha_heap.cc
index d550442b0ec..8e8744c2d34 100644
--- a/storage/heap/ha_heap.cc
+++ b/storage/heap/ha_heap.cc
@@ -25,12 +25,20 @@
#include "ha_heap.h"
-static handler *heap_create_handler(TABLE_SHARE *table, MEM_ROOT *mem_root);
+static handler *heap_create_handler(handlerton *hton,
+ TABLE_SHARE *table,
+ MEM_ROOT *mem_root);
+
+int heap_panic(handlerton *hton, ha_panic_function flag)
+{
+ return hp_panic(flag);
+}
-handlerton *heap_hton;
int heap_init(void *p)
{
+ handlerton *heap_hton;
+
heap_hton= (handlerton *)p;
heap_hton->state= SHOW_OPTION_YES;
heap_hton->db_type= DB_TYPE_HEAP;
@@ -41,9 +49,11 @@ int heap_init(void *p)
return 0;
}
-static handler *heap_create_handler(TABLE_SHARE *table, MEM_ROOT *mem_root)
+static handler *heap_create_handler(handlerton *hton,
+ TABLE_SHARE *table,
+ MEM_ROOT *mem_root)
{
- return new (mem_root) ha_heap(table);
+ return new (mem_root) ha_heap(hton, table);
}
@@ -51,8 +61,8 @@ static handler *heap_create_handler(TABLE_SHARE *table, MEM_ROOT *mem_root)
** HEAP tables
*****************************************************************************/
-ha_heap::ha_heap(TABLE_SHARE *table_arg)
- :handler(heap_hton, table_arg), file(0), records_changed(0),
+ha_heap::ha_heap(handlerton *hton, TABLE_SHARE *table_arg)
+ :handler(hton, table_arg), file(0), records_changed(0),
key_stat_version(0)
{}
@@ -701,7 +711,7 @@ bool ha_heap::check_if_incompatible_data(HA_CREATE_INFO *info,
}
struct st_mysql_storage_engine heap_storage_engine=
-{ MYSQL_HANDLERTON_INTERFACE_VERSION, heap_hton};
+{ MYSQL_HANDLERTON_INTERFACE_VERSION };
mysql_declare_plugin(heap)
{
@@ -710,6 +720,7 @@ mysql_declare_plugin(heap)
"MEMORY",
"MySQL AB",
"Hash based, stored in memory, useful for temporary tables",
+ PLUGIN_LICENSE_GPL,
heap_init,
NULL,
0x0100, /* 1.0 */
diff --git a/storage/heap/ha_heap.h b/storage/heap/ha_heap.h
index 00e59856f26..0f6386655cb 100644
--- a/storage/heap/ha_heap.h
+++ b/storage/heap/ha_heap.h
@@ -31,7 +31,7 @@ class ha_heap: public handler
uint records_changed;
uint key_stat_version;
public:
- ha_heap(TABLE_SHARE *table);
+ ha_heap(handlerton *hton, TABLE_SHARE *table);
~ha_heap() {}
const char *table_type() const
{
diff --git a/storage/heap/hp_panic.c b/storage/heap/hp_panic.c
index 2b659cbfbb3..08c310bec3d 100644
--- a/storage/heap/hp_panic.c
+++ b/storage/heap/hp_panic.c
@@ -19,10 +19,10 @@
/* if flag == HA_PANIC_CLOSE then all files are removed for more
memory */
-int heap_panic(enum ha_panic_function flag)
+int hp_panic(enum ha_panic_function flag)
{
LIST *element,*next_open;
- DBUG_ENTER("heap_panic");
+ DBUG_ENTER("hp_panic");
pthread_mutex_lock(&THR_LOCK_heap);
for (element=heap_open_list ; element ; element=next_open)
@@ -54,4 +54,4 @@ int heap_panic(enum ha_panic_function flag)
}
pthread_mutex_unlock(&THR_LOCK_heap);
DBUG_RETURN(0);
-} /* heap_panic */
+} /* hp_panic */
diff --git a/storage/heap/hp_test1.c b/storage/heap/hp_test1.c
index 703b39b1e2d..a7423effac8 100644
--- a/storage/heap/hp_test1.c
+++ b/storage/heap/hp_test1.c
@@ -155,7 +155,7 @@ int main(int argc, char **argv)
}
#endif
- if (heap_close(file) || heap_panic(HA_PANIC_CLOSE))
+ if (heap_close(file) || hp_panic(HA_PANIC_CLOSE))
goto err;
my_end(MY_GIVE_INFO);
return(0);
diff --git a/storage/heap/hp_test2.c b/storage/heap/hp_test2.c
index c1d987a3b5f..b4e8cf98f0b 100644
--- a/storage/heap/hp_test2.c
+++ b/storage/heap/hp_test2.c
@@ -603,7 +603,7 @@ end:
if (heap_close(file) || (file2 && heap_close(file2)))
goto err;
heap_delete_table(filename2);
- heap_panic(HA_PANIC_CLOSE);
+ hp_panic(HA_PANIC_CLOSE);
my_end(MY_GIVE_INFO);
return(0);
err:
@@ -669,7 +669,7 @@ static sig_handler endprog(int sig_number __attribute__((unused)))
else
#endif
{
- heap_panic(HA_PANIC_CLOSE);
+ hp_panic(HA_PANIC_CLOSE);
my_end(1);
exit(1);
}
diff --git a/storage/innobase/btr/btr0btr.c b/storage/innobase/btr/btr0btr.c
index 095ef6f02df..ffaf2065045 100644
--- a/storage/innobase/btr/btr0btr.c
+++ b/storage/innobase/btr/btr0btr.c
@@ -77,16 +77,6 @@ make them consecutive on disk if possible. From the other file segment
we allocate pages for the non-leaf levels of the tree.
*/
-/******************************************************************
-Creates a new index page to the tree (not the root, and also not
-used in page reorganization). */
-static
-void
-btr_page_create(
-/*============*/
- page_t* page, /* in: page to be created */
- dict_tree_t* tree, /* in: index tree */
- mtr_t* mtr); /* in: mtr */
/****************************************************************
Returns the upper level node pointer to a page. It is assumed that
mtr holds an x-latch on the tree. */
@@ -95,7 +85,7 @@ rec_t*
btr_page_get_father_node_ptr(
/*=========================*/
/* out: pointer to node pointer record */
- dict_tree_t* tree, /* in: index tree */
+ dict_index_t* index, /* in: index tree */
page_t* page, /* in: page: must contain at least one
user record */
mtr_t* mtr); /* in: mtr */
@@ -132,19 +122,18 @@ page_t*
btr_root_get(
/*=========*/
/* out: root page, x-latched */
- dict_tree_t* tree, /* in: index tree */
+ dict_index_t* index, /* in: index tree */
mtr_t* mtr) /* in: mtr */
{
ulint space;
ulint root_page_no;
page_t* root;
- space = dict_tree_get_space(tree);
- root_page_no = dict_tree_get_page(tree);
+ space = dict_index_get_space(index);
+ root_page_no = dict_index_get_page(index);
root = btr_page_get(space, root_page_no, RW_X_LATCH, mtr);
- ut_a((ibool)!!page_is_comp(root)
- == dict_table_is_comp(tree->tree_index->table));
+ ut_a((ibool)!!page_is_comp(root) == dict_table_is_comp(index->table));
return(root);
}
@@ -254,23 +243,22 @@ btr_get_next_user_rec(
}
/******************************************************************
-Creates a new index page to the tree (not the root, and also not used in
-page reorganization). */
+Creates a new index page (not the root, and also not
+used in page reorganization). */
static
void
btr_page_create(
/*============*/
page_t* page, /* in: page to be created */
- dict_tree_t* tree, /* in: index tree */
+ dict_index_t* index, /* in: index */
mtr_t* mtr) /* in: mtr */
{
ut_ad(mtr_memo_contains(mtr, buf_block_align(page),
MTR_MEMO_PAGE_X_FIX));
- page_create(page, mtr,
- dict_table_is_comp(tree->tree_index->table));
+ page_create(page, mtr, dict_table_is_comp(index->table));
buf_block_align(page)->check_index_page_at_flush = TRUE;
- btr_page_set_index_id(page, tree->id, mtr);
+ btr_page_set_index_id(page, index->id, mtr);
}
/******************************************************************
@@ -281,20 +269,20 @@ page_t*
btr_page_alloc_for_ibuf(
/*====================*/
/* out: new allocated page, x-latched */
- dict_tree_t* tree, /* in: index tree */
+ dict_index_t* index, /* in: index tree */
mtr_t* mtr) /* in: mtr */
{
fil_addr_t node_addr;
page_t* root;
page_t* new_page;
- root = btr_root_get(tree, mtr);
+ root = btr_root_get(index, mtr);
node_addr = flst_get_first(root + PAGE_HEADER
+ PAGE_BTR_IBUF_FREE_LIST, mtr);
ut_a(node_addr.page != FIL_NULL);
- new_page = buf_page_get(dict_tree_get_space(tree), node_addr.page,
+ new_page = buf_page_get(dict_index_get_space(index), node_addr.page,
RW_X_LATCH, mtr);
#ifdef UNIV_SYNC_DEBUG
buf_page_dbg_add_level(new_page, SYNC_TREE_NODE_NEW);
@@ -318,7 +306,7 @@ btr_page_alloc(
/*===========*/
/* out: new allocated page, x-latched;
NULL if out of space */
- dict_tree_t* tree, /* in: index tree */
+ dict_index_t* index, /* in: index */
ulint hint_page_no, /* in: hint of a good page */
byte file_direction, /* in: direction where a possible
page split is made */
@@ -331,12 +319,12 @@ btr_page_alloc(
page_t* new_page;
ulint new_page_no;
- if (tree->type & DICT_IBUF) {
+ if (index->type & DICT_IBUF) {
- return(btr_page_alloc_for_ibuf(tree, mtr));
+ return(btr_page_alloc_for_ibuf(index, mtr));
}
- root = btr_root_get(tree, mtr);
+ root = btr_root_get(index, mtr);
if (level == 0) {
seg_header = root + PAGE_HEADER + PAGE_BTR_SEG_LEAF;
@@ -355,7 +343,7 @@ btr_page_alloc(
return(NULL);
}
- new_page = buf_page_get(dict_tree_get_space(tree), new_page_no,
+ new_page = buf_page_get(dict_index_get_space(index), new_page_no,
RW_X_LATCH, mtr);
#ifdef UNIV_SYNC_DEBUG
buf_page_dbg_add_level(new_page, SYNC_TREE_NODE_NEW);
@@ -382,9 +370,9 @@ btr_get_size(
mtr_start(&mtr);
- mtr_s_lock(dict_tree_get_lock(index->tree), &mtr);
+ mtr_s_lock(dict_index_get_lock(index), &mtr);
- root = btr_root_get(index->tree, &mtr);
+ root = btr_root_get(index, &mtr);
if (flag == BTR_N_LEAF_PAGES) {
seg_header = root + PAGE_HEADER + PAGE_BTR_SEG_LEAF;
@@ -415,7 +403,7 @@ static
void
btr_page_free_for_ibuf(
/*===================*/
- dict_tree_t* tree, /* in: index tree */
+ dict_index_t* index, /* in: index tree */
page_t* page, /* in: page to be freed, x-latched */
mtr_t* mtr) /* in: mtr */
{
@@ -423,7 +411,7 @@ btr_page_free_for_ibuf(
ut_ad(mtr_memo_contains(mtr, buf_block_align(page),
MTR_MEMO_PAGE_X_FIX));
- root = btr_root_get(tree, mtr);
+ root = btr_root_get(index, mtr);
flst_add_first(root + PAGE_HEADER + PAGE_BTR_IBUF_FREE_LIST,
page + PAGE_HEADER + PAGE_BTR_IBUF_FREE_LIST_NODE, mtr);
@@ -440,7 +428,7 @@ argument. */
void
btr_page_free_low(
/*==============*/
- dict_tree_t* tree, /* in: index tree */
+ dict_index_t* index, /* in: index tree */
page_t* page, /* in: page to be freed, x-latched */
ulint level, /* in: page level */
mtr_t* mtr) /* in: mtr */
@@ -457,14 +445,14 @@ btr_page_free_low(
buf_frame_modify_clock_inc(page);
- if (tree->type & DICT_IBUF) {
+ if (index->type & DICT_IBUF) {
- btr_page_free_for_ibuf(tree, page, mtr);
+ btr_page_free_for_ibuf(index, page, mtr);
return;
}
- root = btr_root_get(tree, mtr);
+ root = btr_root_get(index, mtr);
if (level == 0) {
seg_header = root + PAGE_HEADER + PAGE_BTR_SEG_LEAF;
@@ -485,7 +473,7 @@ storage pages because the page must contain info on its level. */
void
btr_page_free(
/*==========*/
- dict_tree_t* tree, /* in: index tree */
+ dict_index_t* index, /* in: index tree */
page_t* page, /* in: page to be freed, x-latched */
mtr_t* mtr) /* in: mtr */
{
@@ -495,7 +483,7 @@ btr_page_free(
MTR_MEMO_PAGE_X_FIX));
level = btr_page_get_level(page, mtr);
- btr_page_free_low(tree, page, level, mtr);
+ btr_page_free_low(index, page, level, mtr);
}
/******************************************************************
@@ -558,7 +546,7 @@ btr_page_get_father_for_rec(
/*========================*/
/* out: pointer to node pointer record,
its page x-latched */
- dict_tree_t* tree, /* in: index tree */
+ dict_index_t* index, /* in: index tree */
page_t* page, /* in: page: must contain at least one
user record */
rec_t* user_rec,/* in: user_record on page */
@@ -568,22 +556,20 @@ btr_page_get_father_for_rec(
dtuple_t* tuple;
btr_cur_t cursor;
rec_t* node_ptr;
- dict_index_t* index;
ulint offsets_[REC_OFFS_NORMAL_SIZE];
ulint* offsets = offsets_;
*offsets_ = (sizeof offsets_) / sizeof *offsets_;
- ut_ad(mtr_memo_contains(mtr, dict_tree_get_lock(tree),
+ ut_ad(mtr_memo_contains(mtr, dict_index_get_lock(index),
MTR_MEMO_X_LOCK));
ut_a(page_rec_is_user_rec(user_rec));
- ut_ad(dict_tree_get_page(tree) != buf_frame_get_page_no(page));
+ ut_ad(dict_index_get_page(index) != buf_frame_get_page_no(page));
heap = mem_heap_create(100);
- tuple = dict_tree_build_node_ptr(tree, user_rec, 0, heap,
- btr_page_get_level(page, mtr));
- index = tree->tree_index;
+ tuple = dict_index_build_node_ptr(index, user_rec, 0, heap,
+ btr_page_get_level(page, mtr));
/* In the following, we choose just any index from the tree as the
first parameter for btr_cur_search_to_nth_level. */
@@ -647,14 +633,14 @@ rec_t*
btr_page_get_father_node_ptr(
/*=========================*/
/* out: pointer to node pointer record */
- dict_tree_t* tree, /* in: index tree */
+ dict_index_t* index, /* in: index tree */
page_t* page, /* in: page: must contain at least one
user record */
mtr_t* mtr) /* in: mtr */
{
- return(btr_page_get_father_for_rec
- (tree, page,
- page_rec_get_next(page_get_infimum_rec(page)), mtr));
+ return(btr_page_get_father_for_rec(
+ index, page,
+ page_rec_get_next(page_get_infimum_rec(page)), mtr));
}
/****************************************************************
@@ -683,8 +669,8 @@ btr_create(
if (type & DICT_IBUF) {
/* Allocate first the ibuf header page */
- ibuf_hdr_frame = fseg_create
- (space, 0, IBUF_HEADER + IBUF_TREE_SEG_HEADER, mtr);
+ ibuf_hdr_frame = fseg_create(
+ space, 0, IBUF_HEADER + IBUF_TREE_SEG_HEADER, mtr);
#ifdef UNIV_SYNC_DEBUG
buf_page_dbg_add_level(ibuf_hdr_frame, SYNC_TREE_NODE_NEW);
@@ -786,8 +772,8 @@ leaf_loop:
/* NOTE: page hash indexes are dropped when a page is freed inside
fsp0fsp. */
- finished = fseg_free_step
- (root + PAGE_HEADER + PAGE_BTR_SEG_LEAF, &mtr);
+ finished = fseg_free_step(root + PAGE_HEADER + PAGE_BTR_SEG_LEAF,
+ &mtr);
mtr_commit(&mtr);
if (!finished) {
@@ -799,8 +785,8 @@ top_loop:
root = btr_page_get(space, root_page_no, RW_X_LATCH, &mtr);
- finished = fseg_free_step_not_header
- (root + PAGE_HEADER + PAGE_BTR_SEG_TOP, &mtr);
+ finished = fseg_free_step_not_header(
+ root + PAGE_HEADER + PAGE_BTR_SEG_TOP, &mtr);
mtr_commit(&mtr);
if (!finished) {
@@ -827,8 +813,7 @@ btr_free_root(
btr_search_drop_page_hash_index(root);
top_loop:
- finished = fseg_free_step
- (root + PAGE_HEADER + PAGE_BTR_SEG_TOP, mtr);
+ finished = fseg_free_step(root + PAGE_HEADER + PAGE_BTR_SEG_TOP, mtr);
if (!finished) {
goto top_loop;
@@ -1000,7 +985,7 @@ btr_root_raise_and_insert(
dtuple_t* tuple, /* in: tuple to insert */
mtr_t* mtr) /* in: mtr */
{
- dict_tree_t* tree;
+ dict_index_t* index;
page_t* root;
page_t* new_page;
ulint new_page_no;
@@ -1012,10 +997,10 @@ btr_root_raise_and_insert(
page_cur_t* page_cursor;
root = btr_cur_get_page(cursor);
- tree = btr_cur_get_tree(cursor);
+ index = btr_cur_get_index(cursor);
- ut_ad(dict_tree_get_page(tree) == buf_frame_get_page_no(root));
- ut_ad(mtr_memo_contains(mtr, dict_tree_get_lock(tree),
+ ut_ad(dict_index_get_page(index) == buf_frame_get_page_no(root));
+ ut_ad(mtr_memo_contains(mtr, dict_index_get_lock(index),
MTR_MEMO_X_LOCK));
ut_ad(mtr_memo_contains(mtr, buf_block_align(root),
MTR_MEMO_PAGE_X_FIX));
@@ -1025,10 +1010,10 @@ btr_root_raise_and_insert(
moving the root records to the new page, emptying the root, putting
a node pointer to the new page, and then splitting the new page. */
- new_page = btr_page_alloc(tree, 0, FSP_NO_DIR,
+ new_page = btr_page_alloc(index, 0, FSP_NO_DIR,
btr_page_get_level(root, mtr), mtr);
- btr_page_create(new_page, tree, mtr);
+ btr_page_create(new_page, index, mtr);
level = btr_page_get_level(root, mtr);
@@ -1043,7 +1028,7 @@ btr_root_raise_and_insert(
/* Move the records from root to the new page */
page_move_rec_list_end(new_page, root, page_get_infimum_rec(root),
- cursor->index, mtr);
+ index, mtr);
/* If this is a pessimistic insert which is actually done to
perform a pessimistic update then we have stored the lock
information of the record to be inserted on the infimum of the
@@ -1060,10 +1045,10 @@ btr_root_raise_and_insert(
/* Build the node pointer (= node key and page address) for the
child */
- node_ptr = dict_tree_build_node_ptr(tree, rec, new_page_no, heap,
- level);
+ node_ptr = dict_index_build_node_ptr(index, rec, new_page_no, heap,
+ level);
/* Reorganize the root to get free space */
- btr_page_reorganize(root, cursor->index, mtr);
+ btr_page_reorganize(root, index, mtr);
page_cursor = btr_cur_get_page_cur(cursor);
@@ -1072,7 +1057,7 @@ btr_root_raise_and_insert(
page_cur_set_before_first(root, page_cursor);
node_ptr_rec = page_cur_tuple_insert(page_cursor, node_ptr,
- cursor->index, mtr);
+ index, mtr);
ut_ad(node_ptr_rec);
@@ -1092,9 +1077,9 @@ btr_root_raise_and_insert(
buf_frame_get_page_no(new_page));
#endif
- ibuf_reset_free_bits(tree->tree_index, new_page);
+ ibuf_reset_free_bits(index, new_page);
/* Reposition the cursor to the child node */
- page_cur_search(new_page, cursor->index, tuple,
+ page_cur_search(new_page, index, tuple,
PAGE_CUR_LE, page_cursor);
/* Split the child and insert tuple */
@@ -1419,7 +1404,7 @@ that mtr holds an x-latch on the tree. */
void
btr_insert_on_non_leaf_level(
/*=========================*/
- dict_tree_t* tree, /* in: tree */
+ dict_index_t* index, /* in: index */
ulint level, /* in: level, must be > 0 */
dtuple_t* tuple, /* in: the record to be inserted */
mtr_t* mtr) /* in: mtr */
@@ -1431,11 +1416,7 @@ btr_insert_on_non_leaf_level(
ut_ad(level > 0);
- /* In the following, choose just any index from the tree as the
- first parameter for btr_cur_search_to_nth_level. */
-
- btr_cur_search_to_nth_level(tree->tree_index,
- level, tuple, PAGE_CUR_LE,
+ btr_cur_search_to_nth_level(index, level, tuple, PAGE_CUR_LE,
BTR_CONT_MODIFY_TREE,
&cursor, 0, mtr);
@@ -1454,7 +1435,7 @@ static
void
btr_attach_half_pages(
/*==================*/
- dict_tree_t* tree, /* in: the index tree */
+ dict_index_t* index, /* in: the index tree */
page_t* page, /* in: page to be split */
rec_t* split_rec, /* in: first record on upper
half page */
@@ -1493,15 +1474,17 @@ btr_attach_half_pages(
lower_page = new_page;
upper_page = page;
- /* Look from the tree for the node pointer to page */
- node_ptr = btr_page_get_father_node_ptr(tree, page, mtr);
+ /* Look up the index for the node pointer to page */
+ node_ptr = btr_page_get_father_node_ptr(index, page, mtr);
/* Replace the address of the old child node (= page) with the
address of the new lower half */
- btr_node_ptr_set_child_page_no(node_ptr, rec_get_offsets
- (node_ptr, tree->tree_index,
- NULL, ULINT_UNDEFINED, &heap),
+ btr_node_ptr_set_child_page_no(node_ptr,
+ rec_get_offsets(
+ node_ptr, index,
+ NULL, ULINT_UNDEFINED,
+ &heap),
lower_page_no, mtr);
mem_heap_empty(heap);
} else {
@@ -1517,13 +1500,13 @@ btr_attach_half_pages(
/* Build the node pointer (= node key and page address) for the upper
half */
- node_ptr_upper = dict_tree_build_node_ptr(tree, split_rec,
- upper_page_no, heap, level);
+ node_ptr_upper = dict_index_build_node_ptr(index, split_rec,
+ upper_page_no, heap, level);
/* Insert it next to the pointer to the lower half. Note that this
may generate recursion leading to a split on the higher level. */
- btr_insert_on_non_leaf_level(tree, level + 1, node_ptr_upper, mtr);
+ btr_insert_on_non_leaf_level(index, level + 1, node_ptr_upper, mtr);
/* Free the memory heap */
mem_heap_free(heap);
@@ -1585,7 +1568,6 @@ btr_page_split_and_insert(
dtuple_t* tuple, /* in: tuple to insert */
mtr_t* mtr) /* in: mtr */
{
- dict_tree_t* tree;
page_t* page;
ulint page_no;
byte direction;
@@ -1611,12 +1593,11 @@ btr_page_split_and_insert(
func_start:
mem_heap_empty(heap);
offsets = NULL;
- tree = btr_cur_get_tree(cursor);
- ut_ad(mtr_memo_contains(mtr, dict_tree_get_lock(tree),
+ ut_ad(mtr_memo_contains(mtr, dict_index_get_lock(cursor->index),
MTR_MEMO_X_LOCK));
#ifdef UNIV_SYNC_DEBUG
- ut_ad(rw_lock_own(dict_tree_get_lock(tree), RW_LOCK_EX));
+ ut_ad(rw_lock_own(dict_index_get_lock(cursor->index), RW_LOCK_EX));
#endif /* UNIV_SYNC_DEBUG */
page = btr_cur_get_page(cursor);
@@ -1649,10 +1630,10 @@ func_start:
split_rec = page_get_middle_rec(page);
}
- /* 2. Allocate a new page to the tree */
- new_page = btr_page_alloc(tree, hint_page_no, direction,
+ /* 2. Allocate a new page to the index */
+ new_page = btr_page_alloc(cursor->index, hint_page_no, direction,
btr_page_get_level(page, mtr), mtr);
- btr_page_create(new_page, tree, mtr);
+ btr_page_create(new_page, cursor->index, mtr);
/* 3. Calculate the first record on the upper half-page, and the
first record (move_limit) on original page which ends up on the
@@ -1671,7 +1652,8 @@ func_start:
/* 4. Do first the modifications in the tree structure */
- btr_attach_half_pages(tree, page, first_rec, new_page, direction, mtr);
+ btr_attach_half_pages(cursor->index, page, first_rec,
+ new_page, direction, mtr);
if (split_rec == NULL) {
mem_free(buf);
@@ -1697,7 +1679,7 @@ func_start:
if (insert_will_fit && (btr_page_get_level(page, mtr) == 0)) {
- mtr_memo_release(mtr, dict_tree_get_lock(tree),
+ mtr_memo_release(mtr, dict_index_get_lock(cursor->index),
MTR_MEMO_X_LOCK);
}
@@ -1797,8 +1779,8 @@ func_start:
buf_frame_get_page_no(right_page));
#endif
- ut_ad(page_validate(left_page, tree->tree_index));
- ut_ad(page_validate(right_page, tree->tree_index));
+ ut_ad(page_validate(left_page, cursor->index));
+ ut_ad(page_validate(right_page, cursor->index));
mem_heap_free(heap);
return(rec);
@@ -1810,7 +1792,6 @@ static
void
btr_level_list_remove(
/*==================*/
- dict_tree_t* tree __attribute__((unused)), /* in: index tree */
page_t* page, /* in: page to remove */
mtr_t* mtr) /* in: mtr */
{
@@ -1820,7 +1801,7 @@ btr_level_list_remove(
ulint next_page_no;
page_t* next_page;
- ut_ad(tree && page && mtr);
+ ut_ad(page && mtr);
ut_ad(mtr_memo_contains(mtr, buf_block_align(page),
MTR_MEMO_PAGE_X_FIX));
/* Get the previous and next page numbers of page */
@@ -1867,12 +1848,11 @@ btr_set_min_rec_mark_log(
ulint comp, /* nonzero=compact record format */
mtr_t* mtr) /* in: mtr */
{
- mlog_write_initial_log_record
- (rec, comp ? MLOG_COMP_REC_MIN_MARK : MLOG_REC_MIN_MARK, mtr);
+ mlog_write_initial_log_record(
+ rec, comp ? MLOG_COMP_REC_MIN_MARK : MLOG_REC_MIN_MARK, mtr);
/* Write rec offset as a 2-byte ulint */
- mlog_catenate_ulint(mtr, ut_align_offset(rec, UNIV_PAGE_SIZE),
- MLOG_2BYTES);
+ mlog_catenate_ulint(mtr, page_offset(rec), MLOG_2BYTES);
}
/********************************************************************
@@ -1932,7 +1912,7 @@ Deletes on the upper level the node pointer to a page. */
void
btr_node_ptr_delete(
/*================*/
- dict_tree_t* tree, /* in: index tree */
+ dict_index_t* index, /* in: index tree */
page_t* page, /* in: page whose node pointer is deleted */
mtr_t* mtr) /* in: mtr */
{
@@ -1945,9 +1925,9 @@ btr_node_ptr_delete(
MTR_MEMO_PAGE_X_FIX));
/* Delete node pointer on father page */
- node_ptr = btr_page_get_father_node_ptr(tree, page, mtr);
+ node_ptr = btr_page_get_father_node_ptr(index, page, mtr);
- btr_cur_position(tree->tree_index, node_ptr, &cursor);
+ btr_cur_position(index, node_ptr, &cursor);
compressed = btr_cur_pessimistic_delete(&err, TRUE, &cursor, FALSE,
mtr);
ut_a(err == DB_SUCCESS);
@@ -1964,7 +1944,7 @@ static
void
btr_lift_page_up(
/*=============*/
- dict_tree_t* tree, /* in: index tree */
+ dict_index_t* index, /* in: index tree */
page_t* page, /* in: page which is the only on its level;
must not be empty: use
btr_discard_only_page_on_level if the last
@@ -1973,17 +1953,15 @@ btr_lift_page_up(
{
page_t* father_page;
ulint page_level;
- dict_index_t* index;
ut_ad(btr_page_get_prev(page, mtr) == FIL_NULL);
ut_ad(btr_page_get_next(page, mtr) == FIL_NULL);
ut_ad(mtr_memo_contains(mtr, buf_block_align(page),
MTR_MEMO_PAGE_X_FIX));
- father_page = buf_frame_align
- (btr_page_get_father_node_ptr(tree, page, mtr));
+ father_page = buf_frame_align(
+ btr_page_get_father_node_ptr(index, page, mtr));
page_level = btr_page_get_level(page, mtr);
- index = tree->tree_index;
btr_search_drop_page_hash_index(page);
@@ -1998,12 +1976,12 @@ btr_lift_page_up(
btr_page_set_level(father_page, page_level, mtr);
/* Free the file page */
- btr_page_free(tree, page, mtr);
+ btr_page_free(index, page, mtr);
/* We play safe and reset the free bits for the father */
ibuf_reset_free_bits(index, father_page);
ut_ad(page_validate(father_page, index));
- ut_ad(btr_check_node_ptr(tree, father_page, mtr));
+ ut_ad(btr_check_node_ptr(index, father_page, mtr));
}
/*****************************************************************
@@ -2026,7 +2004,7 @@ btr_compress(
empty */
mtr_t* mtr) /* in: mtr */
{
- dict_tree_t* tree;
+ dict_index_t* index;
ulint space;
ulint left_page_no;
ulint right_page_no;
@@ -2045,16 +2023,16 @@ btr_compress(
ulint comp;
page = btr_cur_get_page(cursor);
- tree = btr_cur_get_tree(cursor);
+ index = btr_cur_get_index(cursor);
comp = page_is_comp(page);
- ut_a((ibool)!!comp == dict_table_is_comp(cursor->index->table));
+ ut_a((ibool)!!comp == dict_table_is_comp(index->table));
- ut_ad(mtr_memo_contains(mtr, dict_tree_get_lock(tree),
+ ut_ad(mtr_memo_contains(mtr, dict_index_get_lock(index),
MTR_MEMO_X_LOCK));
ut_ad(mtr_memo_contains(mtr, buf_block_align(page),
MTR_MEMO_PAGE_X_FIX));
level = btr_page_get_level(page, mtr);
- space = dict_tree_get_space(tree);
+ space = dict_index_get_space(index);
left_page_no = btr_page_get_prev(page, mtr);
right_page_no = btr_page_get_next(page, mtr);
@@ -2064,7 +2042,7 @@ btr_compress(
left_page_no, right_page_no);
#endif
- node_ptr = btr_page_get_father_node_ptr(tree, page, mtr);
+ node_ptr = btr_page_get_father_node_ptr(index, page, mtr);
ut_ad(!comp || rec_get_status(node_ptr) == REC_STATUS_NODE_PTR);
father_page = buf_frame_align(node_ptr);
ut_a(comp == page_is_comp(father_page));
@@ -2093,7 +2071,7 @@ btr_compress(
} else {
/* The page is the only one on the level, lift the records
to the father */
- btr_lift_page_up(tree, page, mtr);
+ btr_lift_page_up(index, page, mtr);
return;
}
@@ -2102,8 +2080,8 @@ btr_compress(
data_size = page_get_data_size(page);
ut_a(page_is_comp(merge_page) == comp);
- max_ins_size_reorg = page_get_max_insert_size_after_reorganize
- (merge_page, n_recs);
+ max_ins_size_reorg = page_get_max_insert_size_after_reorganize(
+ merge_page, n_recs);
if (data_size > max_ins_size_reorg) {
/* No space for merge */
@@ -2111,7 +2089,7 @@ btr_compress(
return;
}
- ut_ad(page_validate(merge_page, cursor->index));
+ ut_ad(page_validate(merge_page, index));
max_ins_size = page_get_max_insert_size(merge_page, n_recs);
@@ -2119,11 +2097,11 @@ btr_compress(
/* We have to reorganize merge_page */
- btr_page_reorganize(merge_page, cursor->index, mtr);
+ btr_page_reorganize(merge_page, index, mtr);
max_ins_size = page_get_max_insert_size(merge_page, n_recs);
- ut_ad(page_validate(merge_page, cursor->index));
+ ut_ad(page_validate(merge_page, index));
ut_ad(page_get_max_insert_size(merge_page, n_recs)
== max_ins_size_reorg);
}
@@ -2138,10 +2116,10 @@ btr_compress(
btr_search_drop_page_hash_index(page);
/* Remove the page from the level list */
- btr_level_list_remove(tree, page, mtr);
+ btr_level_list_remove(page, mtr);
if (is_left) {
- btr_node_ptr_delete(tree, page, mtr);
+ btr_node_ptr_delete(index, page, mtr);
} else {
mem_heap_t* heap = NULL;
ulint offsets_[REC_OFFS_NORMAL_SIZE];
@@ -2149,46 +2127,48 @@ btr_compress(
/* Replace the address of the old child node (= page) with the
address of the merge page to the right */
- btr_node_ptr_set_child_page_no(node_ptr, rec_get_offsets
- (node_ptr, cursor->index,
- offsets_, ULINT_UNDEFINED,
- &heap),
+ btr_node_ptr_set_child_page_no(node_ptr,
+ rec_get_offsets(
+ node_ptr, index,
+ offsets_,
+ ULINT_UNDEFINED,
+ &heap),
right_page_no, mtr);
if (UNIV_LIKELY_NULL(heap)) {
mem_heap_free(heap);
}
- btr_node_ptr_delete(tree, merge_page, mtr);
+ btr_node_ptr_delete(index, merge_page, mtr);
}
/* Move records to the merge page */
if (is_left) {
- orig_pred = page_rec_get_prev
- (page_get_supremum_rec(merge_page));
+ orig_pred = page_rec_get_prev(
+ page_get_supremum_rec(merge_page));
page_copy_rec_list_start(merge_page, page,
page_get_supremum_rec(page),
- cursor->index, mtr);
+ index, mtr);
lock_update_merge_left(merge_page, orig_pred, page);
} else {
- orig_succ = page_rec_get_next
- (page_get_infimum_rec(merge_page));
+ orig_succ = page_rec_get_next(
+ page_get_infimum_rec(merge_page));
page_copy_rec_list_end(merge_page, page,
page_get_infimum_rec(page),
- cursor->index, mtr);
+ index, mtr);
lock_update_merge_right(orig_succ, page);
}
/* We have added new records to merge_page: update its free bits */
- ibuf_update_free_bits_if_full(cursor->index, merge_page,
+ ibuf_update_free_bits_if_full(index, merge_page,
UNIV_PAGE_SIZE, ULINT_UNDEFINED);
- ut_ad(page_validate(merge_page, cursor->index));
+ ut_ad(page_validate(merge_page, index));
/* Free the file page */
- btr_page_free(tree, page, mtr);
+ btr_page_free(index, page, mtr);
- ut_ad(btr_check_node_ptr(tree, merge_page, mtr));
+ ut_ad(btr_check_node_ptr(index, merge_page, mtr));
}
/*****************************************************************
@@ -2197,7 +2177,7 @@ static
void
btr_discard_only_page_on_level(
/*===========================*/
- dict_tree_t* tree, /* in: index tree */
+ dict_index_t* index, /* in: index tree */
page_t* page, /* in: page which is the only on its level */
mtr_t* mtr) /* in: mtr */
{
@@ -2211,7 +2191,7 @@ btr_discard_only_page_on_level(
MTR_MEMO_PAGE_X_FIX));
btr_search_drop_page_hash_index(page);
- node_ptr = btr_page_get_father_node_ptr(tree, page, mtr);
+ node_ptr = btr_page_get_father_node_ptr(index, page, mtr);
father_page = buf_frame_align(node_ptr);
page_level = btr_page_get_level(page, mtr);
@@ -2221,19 +2201,19 @@ btr_discard_only_page_on_level(
btr_page_set_level(father_page, page_level, mtr);
/* Free the file page */
- btr_page_free(tree, page, mtr);
+ btr_page_free(index, page, mtr);
- if (buf_frame_get_page_no(father_page) == dict_tree_get_page(tree)) {
+ if (buf_frame_get_page_no(father_page) == dict_index_get_page(index)) {
/* The father is the root page */
btr_page_empty(father_page, mtr);
/* We play safe and reset the free bits for the father */
- ibuf_reset_free_bits(tree->tree_index, father_page);
+ ibuf_reset_free_bits(index, father_page);
} else {
ut_ad(page_get_n_recs(father_page) == 1);
- btr_discard_only_page_on_level(tree, father_page, mtr);
+ btr_discard_only_page_on_level(index, father_page, mtr);
}
}
@@ -2249,7 +2229,7 @@ btr_discard_page(
the root page */
mtr_t* mtr) /* in: mtr */
{
- dict_tree_t* tree;
+ dict_index_t* index;
ulint space;
ulint left_page_no;
ulint right_page_no;
@@ -2258,14 +2238,14 @@ btr_discard_page(
rec_t* node_ptr;
page = btr_cur_get_page(cursor);
- tree = btr_cur_get_tree(cursor);
+ index = btr_cur_get_index(cursor);
- ut_ad(dict_tree_get_page(tree) != buf_frame_get_page_no(page));
- ut_ad(mtr_memo_contains(mtr, dict_tree_get_lock(tree),
+ ut_ad(dict_index_get_page(index) != buf_frame_get_page_no(page));
+ ut_ad(mtr_memo_contains(mtr, dict_index_get_lock(index),
MTR_MEMO_X_LOCK));
ut_ad(mtr_memo_contains(mtr, buf_block_align(page),
MTR_MEMO_PAGE_X_FIX));
- space = dict_tree_get_space(tree);
+ space = dict_index_get_space(index);
/* Decide the page which will inherit the locks */
@@ -2287,7 +2267,7 @@ btr_discard_page(
== buf_frame_get_page_no(page));
#endif /* UNIV_BTR_DEBUG */
} else {
- btr_discard_only_page_on_level(tree, page, mtr);
+ btr_discard_only_page_on_level(index, page, mtr);
return;
}
@@ -2307,22 +2287,23 @@ btr_discard_page(
btr_set_min_rec_mark(node_ptr, page_is_comp(merge_page), mtr);
}
- btr_node_ptr_delete(tree, page, mtr);
+ btr_node_ptr_delete(index, page, mtr);
/* Remove the page from the level list */
- btr_level_list_remove(tree, page, mtr);
+ btr_level_list_remove(page, mtr);
if (left_page_no != FIL_NULL) {
lock_update_discard(page_get_supremum_rec(merge_page), page);
} else {
- lock_update_discard(page_rec_get_next
- (page_get_infimum_rec(merge_page)), page);
+ lock_update_discard(page_rec_get_next(
+ page_get_infimum_rec(merge_page)),
+ page);
}
/* Free the file page */
- btr_page_free(tree, page, mtr);
+ btr_page_free(index, page, mtr);
- ut_ad(btr_check_node_ptr(tree, merge_page, mtr));
+ ut_ad(btr_check_node_ptr(index, merge_page, mtr));
}
#ifdef UNIV_BTR_PRINT
@@ -2332,13 +2313,13 @@ Prints size info of a B-tree. */
void
btr_print_size(
/*===========*/
- dict_tree_t* tree) /* in: index tree */
+ dict_index_t* index) /* in: index tree */
{
page_t* root;
fseg_header_t* seg;
mtr_t mtr;
- if (tree->type & DICT_IBUF) {
+ if (index->type & DICT_IBUF) {
fputs("Sorry, cannot print info of an ibuf tree:"
" use ibuf functions\n", stderr);
@@ -2347,14 +2328,14 @@ btr_print_size(
mtr_start(&mtr);
- root = btr_root_get(tree, &mtr);
+ root = btr_root_get(index, &mtr);
seg = root + PAGE_HEADER + PAGE_BTR_SEG_TOP;
fputs("INFO OF THE NON-LEAF PAGE SEGMENT\n", stderr);
fseg_print(seg, &mtr);
- if (!(tree->type & DICT_UNIVERSAL)) {
+ if (!(index->type & DICT_UNIVERSAL)) {
seg = root + PAGE_HEADER + PAGE_BTR_SEG_LEAF;
@@ -2371,7 +2352,7 @@ static
void
btr_print_recursive(
/*================*/
- dict_tree_t* tree, /* in: index tree */
+ dict_index_t* index, /* in: index tree */
page_t* page, /* in: index page */
ulint width, /* in: print this many entries from start
and end */
@@ -2385,7 +2366,6 @@ btr_print_recursive(
mtr_t mtr2;
rec_t* node_ptr;
page_t* child;
- dict_index_t* index;
ut_ad(mtr_memo_contains(mtr, buf_block_align(page),
MTR_MEMO_PAGE_X_FIX));
@@ -2393,7 +2373,6 @@ btr_print_recursive(
(ulong) btr_page_get_level(page, mtr),
(ulong) buf_frame_get_page_no(page));
- index = UT_LIST_GET_FIRST(tree->tree_indexes);
page_print(page, index, width, width);
n_recs = page_get_n_recs(page);
@@ -2417,7 +2396,7 @@ btr_print_recursive(
ULINT_UNDEFINED, heap);
child = btr_node_ptr_get_child(node_ptr,
*offsets, &mtr2);
- btr_print_recursive(tree, child, width,
+ btr_print_recursive(index, child, width,
heap, offsets, &mtr2);
mtr_commit(&mtr2);
}
@@ -2431,9 +2410,9 @@ btr_print_recursive(
Prints directories and other info of all nodes in the tree. */
void
-btr_print_tree(
-/*===========*/
- dict_tree_t* tree, /* in: tree */
+btr_print_index(
+/*============*/
+ dict_index_t* index, /* in: index */
ulint width) /* in: print this many entries from start
and end */
{
@@ -2449,16 +2428,16 @@ btr_print_tree(
mtr_start(&mtr);
- root = btr_root_get(tree, &mtr);
+ root = btr_root_get(index, &mtr);
- btr_print_recursive(tree, root, width, &heap, &offsets, &mtr);
+ btr_print_recursive(index, root, width, &heap, &offsets, &mtr);
if (UNIV_LIKELY_NULL(heap)) {
mem_heap_free(heap);
}
mtr_commit(&mtr);
- btr_validate_tree(tree, NULL);
+ btr_validate_index(index, NULL);
}
#endif /* UNIV_BTR_PRINT */
@@ -2470,7 +2449,7 @@ ibool
btr_check_node_ptr(
/*===============*/
/* out: TRUE */
- dict_tree_t* tree, /* in: index tree */
+ dict_index_t* index, /* in: index tree */
page_t* page, /* in: index page */
mtr_t* mtr) /* in: mtr */
{
@@ -2480,12 +2459,12 @@ btr_check_node_ptr(
ut_ad(mtr_memo_contains(mtr, buf_block_align(page),
MTR_MEMO_PAGE_X_FIX));
- if (dict_tree_get_page(tree) == buf_frame_get_page_no(page)) {
+ if (dict_index_get_page(index) == buf_frame_get_page_no(page)) {
return(TRUE);
}
- node_ptr = btr_page_get_father_node_ptr(tree, page, mtr);
+ node_ptr = btr_page_get_father_node_ptr(index, page, mtr);
if (btr_page_get_level(page, mtr) == 0) {
@@ -2494,12 +2473,12 @@ btr_check_node_ptr(
heap = mem_heap_create(256);
- node_ptr_tuple = dict_tree_build_node_ptr
- (tree, page_rec_get_next(page_get_infimum_rec(page)),
- 0, heap, btr_page_get_level(page, mtr));
+ node_ptr_tuple = dict_index_build_node_ptr(
+ index, page_rec_get_next(page_get_infimum_rec(page)), 0, heap,
+ btr_page_get_level(page, mtr));
ut_a(!cmp_dtuple_rec(node_ptr_tuple, node_ptr,
- rec_get_offsets(node_ptr, tree->tree_index,
+ rec_get_offsets(node_ptr, index,
NULL, ULINT_UNDEFINED, &heap)));
mem_heap_free(heap);
@@ -2588,8 +2567,8 @@ btr_index_rec_validate(
offsets = rec_get_offsets(rec, index, offsets, ULINT_UNDEFINED, &heap);
for (i = 0; i < n; i++) {
- dtype_t* type = dict_index_get_nth_type(index, i);
- ulint fixed_size = dtype_get_fixed_size(type);
+ ulint fixed_size = dict_col_get_fixed_size(
+ dict_index_get_nth_col(index, i));
rec_get_nth_field(rec, offsets, i, &len);
@@ -2608,8 +2587,7 @@ btr_index_rec_validate(
fprintf(stderr,
"InnoDB: field %lu len is %lu,"
" should be %lu\n",
- (ulong) i, (ulong) len,
- (ulong) dtype_get_fixed_size(type));
+ (ulong) i, (ulong) len, (ulong) fixed_size);
if (dump_on_error) {
buf_page_print(page);
@@ -2670,6 +2648,7 @@ Report an error on one page of an index tree. */
static
void
btr_validate_report1(
+/*=================*/
/* out: TRUE if ok */
dict_index_t* index, /* in: index */
ulint level, /* in: B-tree level */
@@ -2689,6 +2668,7 @@ Report an error on two pages of an index tree. */
static
void
btr_validate_report2(
+/*=================*/
/* out: TRUE if ok */
dict_index_t* index, /* in: index */
ulint level, /* in: B-tree level */
@@ -2712,7 +2692,7 @@ ibool
btr_validate_level(
/*===============*/
/* out: TRUE if ok */
- dict_tree_t* tree, /* in: index tree */
+ dict_index_t* index, /* in: index tree */
trx_t* trx, /* in: transaction or NULL */
ulint level) /* in: level number */
{
@@ -2729,7 +2709,6 @@ btr_validate_level(
page_cur_t cursor;
dtuple_t* node_ptr_tuple;
ibool ret = TRUE;
- dict_index_t* index;
mtr_t mtr;
mem_heap_t* heap = mem_heap_create(256);
ulint* offsets = NULL;
@@ -2737,14 +2716,12 @@ btr_validate_level(
mtr_start(&mtr);
- mtr_x_lock(dict_tree_get_lock(tree), &mtr);
+ mtr_x_lock(dict_index_get_lock(index), &mtr);
- page = btr_root_get(tree, &mtr);
+ page = btr_root_get(index, &mtr);
space = buf_frame_get_space_id(page);
- index = tree->tree_index;
-
while (level != btr_page_get_level(page, &mtr)) {
ut_a(btr_page_get_level(page, &mtr) > 0);
@@ -2768,7 +2745,7 @@ loop:
}
mem_heap_empty(heap);
offsets = offsets2 = NULL;
- mtr_x_lock(dict_tree_get_lock(tree), &mtr);
+ mtr_x_lock(dict_index_get_lock(index), &mtr);
/* Check ordering etc. of records */
@@ -2794,7 +2771,7 @@ loop:
ut_a((page_get_n_recs(page) > 0)
|| ((level == 0)
&& (buf_frame_get_page_no(page)
- == dict_tree_get_page(tree))));
+ == dict_index_get_page(index))));
if (right_page_no != FIL_NULL) {
rec_t* right_rec;
@@ -2824,8 +2801,8 @@ loop:
}
rec = page_rec_get_prev(page_get_supremum_rec(page));
- right_rec = page_rec_get_next(page_get_infimum_rec
- (right_page));
+ right_rec = page_rec_get_next(page_get_infimum_rec(
+ right_page));
offsets = rec_get_offsets(rec, index,
offsets, ULINT_UNDEFINED, &heap);
offsets2 = rec_get_offsets(right_rec, index,
@@ -2847,8 +2824,8 @@ loop:
rec_print(stderr, rec, index);
putc('\n', stderr);
fputs("InnoDB: record ", stderr);
- rec = page_rec_get_next
- (page_get_infimum_rec(right_page));
+ rec = page_rec_get_next(
+ page_get_infimum_rec(right_page));
rec_print(stderr, rec, index);
putc('\n', stderr);
@@ -2857,25 +2834,26 @@ loop:
}
if (level > 0 && left_page_no == FIL_NULL) {
- ut_a(REC_INFO_MIN_REC_FLAG & rec_get_info_bits
- (page_rec_get_next(page_get_infimum_rec(page)),
- page_is_comp(page)));
+ ut_a(REC_INFO_MIN_REC_FLAG & rec_get_info_bits(
+ page_rec_get_next(page_get_infimum_rec(page)),
+ page_is_comp(page)));
}
- if (buf_frame_get_page_no(page) != dict_tree_get_page(tree)) {
+ if (buf_frame_get_page_no(page) != dict_index_get_page(index)) {
/* Check father node pointers */
- node_ptr = btr_page_get_father_node_ptr(tree, page, &mtr);
+ node_ptr = btr_page_get_father_node_ptr(index, page, &mtr);
father_page = buf_frame_align(node_ptr);
offsets = rec_get_offsets(node_ptr, index,
offsets, ULINT_UNDEFINED, &heap);
if (btr_node_ptr_get_child_page_no(node_ptr, offsets)
!= buf_frame_get_page_no(page)
- || node_ptr != btr_page_get_father_for_rec
- (tree, page,
- page_rec_get_prev(page_get_supremum_rec(page)), &mtr)) {
+ || node_ptr != btr_page_get_father_for_rec(
+ index, page,
+ page_rec_get_prev(page_get_supremum_rec(page)),
+ &mtr)) {
btr_validate_report1(index, level, page);
fputs("InnoDB: node pointer to the page is wrong\n",
@@ -2893,9 +2871,10 @@ loop:
(node_ptr, offsets));
fputs("InnoDB: record on page ", stderr);
- rec = btr_page_get_father_for_rec
- (tree, page, page_rec_get_prev
- (page_get_supremum_rec(page)), &mtr);
+ rec = btr_page_get_father_for_rec(
+ index, page,
+ page_rec_get_prev(page_get_supremum_rec(page)),
+ &mtr);
rec_print(stderr, rec, index);
putc('\n', stderr);
ret = FALSE;
@@ -2908,15 +2887,15 @@ loop:
offsets, ULINT_UNDEFINED,
&heap);
- node_ptr_tuple = dict_tree_build_node_ptr
- (tree,
- page_rec_get_next(page_get_infimum_rec(page)),
- 0, heap, btr_page_get_level(page, &mtr));
+ node_ptr_tuple = dict_index_build_node_ptr(
+ index,
+ page_rec_get_next(page_get_infimum_rec(page)),
+ 0, heap, btr_page_get_level(page, &mtr));
if (cmp_dtuple_rec(node_ptr_tuple, node_ptr,
offsets)) {
- rec_t* first_rec = page_rec_get_next
- (page_get_infimum_rec(page));
+ rec_t* first_rec = page_rec_get_next(
+ page_get_infimum_rec(page));
btr_validate_report1(index, level, page);
@@ -2937,18 +2916,18 @@ loop:
}
if (left_page_no == FIL_NULL) {
- ut_a(node_ptr == page_rec_get_next
- (page_get_infimum_rec(father_page)));
+ ut_a(node_ptr == page_rec_get_next(
+ page_get_infimum_rec(father_page)));
ut_a(btr_page_get_prev(father_page, &mtr) == FIL_NULL);
}
if (right_page_no == FIL_NULL) {
- ut_a(node_ptr == page_rec_get_prev
- (page_get_supremum_rec(father_page)));
+ ut_a(node_ptr == page_rec_get_prev(
+ page_get_supremum_rec(father_page)));
ut_a(btr_page_get_next(father_page, &mtr) == FIL_NULL);
} else {
- right_node_ptr = btr_page_get_father_node_ptr
- (tree, right_page, &mtr);
+ right_node_ptr = btr_page_get_father_node_ptr(
+ index, right_page, &mtr);
if (page_rec_get_next(node_ptr)
!= page_get_supremum_rec(father_page)) {
@@ -2967,12 +2946,12 @@ loop:
buf_page_print(right_page);
}
} else {
- right_father_page = buf_frame_align
- (right_node_ptr);
+ right_father_page = buf_frame_align(
+ right_node_ptr);
- if (right_node_ptr != page_rec_get_next
- (page_get_infimum_rec
- (right_father_page))) {
+ if (right_node_ptr != page_rec_get_next(
+ page_get_infimum_rec(
+ right_father_page))) {
ret = FALSE;
fputs("InnoDB: node pointer 2 to"
" the right page is wrong\n",
@@ -3029,10 +3008,10 @@ node_ptr_fails:
Checks the consistency of an index tree. */
ibool
-btr_validate_tree(
-/*==============*/
+btr_validate_index(
+/*===============*/
/* out: TRUE if ok */
- dict_tree_t* tree, /* in: tree */
+ dict_index_t* index, /* in: index */
trx_t* trx) /* in: transaction or NULL */
{
mtr_t mtr;
@@ -3041,13 +3020,13 @@ btr_validate_tree(
ulint n;
mtr_start(&mtr);
- mtr_x_lock(dict_tree_get_lock(tree), &mtr);
+ mtr_x_lock(dict_index_get_lock(index), &mtr);
- root = btr_root_get(tree, &mtr);
+ root = btr_root_get(index, &mtr);
n = btr_page_get_level(root, &mtr);
for (i = 0; i <= n && !trx_is_interrupted(trx); i++) {
- if (!btr_validate_level(tree, trx, n - i)) {
+ if (!btr_validate_level(index, trx, n - i)) {
mtr_commit(&mtr);
diff --git a/storage/innobase/btr/btr0cur.c b/storage/innobase/btr/btr0cur.c
index 8fbc25c9e79..975d5252a2f 100644
--- a/storage/innobase/btr/btr0cur.c
+++ b/storage/innobase/btr/btr0cur.c
@@ -272,7 +272,6 @@ btr_cur_search_to_nth_level(
RW_S_LATCH, or 0 */
mtr_t* mtr) /* in: mtr */
{
- dict_tree_t* tree;
page_cur_t* page_cursor;
page_t* page;
page_t* guess;
@@ -303,7 +302,7 @@ btr_cur_search_to_nth_level(
ending to upper levels */
ut_ad(level == 0 || mode == PAGE_CUR_LE);
- ut_ad(dict_tree_check_search_tuple(index->tree, tuple));
+ ut_ad(dict_index_check_search_tuple(index, tuple));
ut_ad(!(index->type & DICT_IBUF) || ibuf_inside());
ut_ad(dtuple_check_typed(tuple));
@@ -374,23 +373,21 @@ btr_cur_search_to_nth_level(
savepoint = mtr_set_savepoint(mtr);
- tree = index->tree;
-
if (latch_mode == BTR_MODIFY_TREE) {
- mtr_x_lock(dict_tree_get_lock(tree), mtr);
+ mtr_x_lock(dict_index_get_lock(index), mtr);
} else if (latch_mode == BTR_CONT_MODIFY_TREE) {
/* Do nothing */
- ut_ad(mtr_memo_contains(mtr, dict_tree_get_lock(tree),
+ ut_ad(mtr_memo_contains(mtr, dict_index_get_lock(index),
MTR_MEMO_X_LOCK));
} else {
- mtr_s_lock(dict_tree_get_lock(tree), mtr);
+ mtr_s_lock(dict_index_get_lock(index), mtr);
}
page_cursor = btr_cur_get_page_cur(cursor);
- space = dict_tree_get_space(tree);
- page_no = dict_tree_get_page(tree);
+ space = dict_index_get_space(index);
+ page_no = dict_index_get_page(index);
up_match = 0;
up_bytes = 0;
@@ -478,7 +475,7 @@ retry_page_get:
buf_page_dbg_add_level(page, SYNC_TREE_NODE);
}
#endif
- ut_ad(0 == ut_dulint_cmp(tree->id,
+ ut_ad(0 == ut_dulint_cmp(index->id,
btr_page_get_index_id(page)));
if (height == ULINT_UNDEFINED) {
@@ -507,9 +504,9 @@ retry_page_get:
/* Release the tree s-latch */
- mtr_release_s_latch_at_savepoint
- (mtr, savepoint,
- dict_tree_get_lock(tree));
+ mtr_release_s_latch_at_savepoint(
+ mtr, savepoint,
+ dict_index_get_lock(index));
}
page_mode = mode;
@@ -525,8 +522,8 @@ retry_page_get:
/* If this is the desired level, leave the loop */
- ut_ad(height == btr_page_get_level
- (page_cur_get_page(page_cursor), mtr));
+ ut_ad(height == btr_page_get_level(
+ page_cur_get_page(page_cursor), mtr));
if (level == height) {
@@ -598,7 +595,6 @@ btr_cur_open_at_index_side(
mtr_t* mtr) /* in: mtr */
{
page_cur_t* page_cursor;
- dict_tree_t* tree;
page_t* page;
ulint page_no;
ulint space;
@@ -615,24 +611,22 @@ btr_cur_open_at_index_side(
estimate = latch_mode & BTR_ESTIMATE;
latch_mode = latch_mode & ~BTR_ESTIMATE;
- tree = index->tree;
-
/* Store the position of the tree latch we push to mtr so that we
know how to release it when we have latched the leaf node */
savepoint = mtr_set_savepoint(mtr);
if (latch_mode == BTR_MODIFY_TREE) {
- mtr_x_lock(dict_tree_get_lock(tree), mtr);
+ mtr_x_lock(dict_index_get_lock(index), mtr);
} else {
- mtr_s_lock(dict_tree_get_lock(tree), mtr);
+ mtr_s_lock(dict_index_get_lock(index), mtr);
}
page_cursor = btr_cur_get_page_cur(cursor);
cursor->index = index;
- space = dict_tree_get_space(tree);
- page_no = dict_tree_get_page(tree);
+ space = dict_index_get_space(index);
+ page_no = dict_index_get_page(index);
height = ULINT_UNDEFINED;
@@ -641,7 +635,7 @@ btr_cur_open_at_index_side(
BUF_GET,
__FILE__, __LINE__,
mtr);
- ut_ad(0 == ut_dulint_cmp(tree->id,
+ ut_ad(0 == ut_dulint_cmp(index->id,
btr_page_get_index_id(page)));
buf_block_align(page)->check_index_page_at_flush = TRUE;
@@ -668,9 +662,9 @@ btr_cur_open_at_index_side(
/* Release the tree s-latch */
- mtr_release_s_latch_at_savepoint
- (mtr, savepoint,
- dict_tree_get_lock(tree));
+ mtr_release_s_latch_at_savepoint(
+ mtr, savepoint,
+ dict_index_get_lock(index));
}
}
@@ -727,7 +721,6 @@ btr_cur_open_at_rnd_pos(
mtr_t* mtr) /* in: mtr */
{
page_cur_t* page_cursor;
- dict_tree_t* tree;
page_t* page;
ulint page_no;
ulint space;
@@ -738,19 +731,17 @@ btr_cur_open_at_rnd_pos(
ulint* offsets = offsets_;
*offsets_ = (sizeof offsets_) / sizeof *offsets_;
- tree = index->tree;
-
if (latch_mode == BTR_MODIFY_TREE) {
- mtr_x_lock(dict_tree_get_lock(tree), mtr);
+ mtr_x_lock(dict_index_get_lock(index), mtr);
} else {
- mtr_s_lock(dict_tree_get_lock(tree), mtr);
+ mtr_s_lock(dict_index_get_lock(index), mtr);
}
page_cursor = btr_cur_get_page_cur(cursor);
cursor->index = index;
- space = dict_tree_get_space(tree);
- page_no = dict_tree_get_page(tree);
+ space = dict_index_get_space(index);
+ page_no = dict_index_get_page(index);
height = ULINT_UNDEFINED;
@@ -759,7 +750,7 @@ btr_cur_open_at_rnd_pos(
BUF_GET,
__FILE__, __LINE__,
mtr);
- ut_ad(0 == ut_dulint_cmp(tree->id,
+ ut_ad(0 == ut_dulint_cmp(index->id,
btr_page_get_index_id(page)));
if (height == ULINT_UNDEFINED) {
@@ -1017,7 +1008,7 @@ calculate_sizes_again:
type = index->type;
if ((type & DICT_CLUSTERED)
- && (dict_tree_get_space_reserve(index->tree) + rec_size > max_size)
+ && (dict_index_get_space_reserve() + rec_size > max_size)
&& (page_get_n_recs(page) >= 2)
&& (0 == level)
&& (btr_page_get_split_rec_to_right(cursor, &dummy_rec)
@@ -1156,7 +1147,7 @@ btr_cur_pessimistic_insert(
page = btr_cur_get_page(cursor);
ut_ad(mtr_memo_contains(mtr,
- dict_tree_get_lock(btr_cur_get_tree(cursor)),
+ dict_index_get_lock(btr_cur_get_index(cursor)),
MTR_MEMO_X_LOCK));
ut_ad(mtr_memo_contains(mtr, buf_block_align(page),
MTR_MEMO_PAGE_X_FIX));
@@ -1218,8 +1209,7 @@ btr_cur_pessimistic_insert(
}
}
- if (dict_tree_get_page(index->tree)
- == buf_frame_get_page_no(page)) {
+ if (dict_index_get_page(index) == buf_frame_get_page_no(page)) {
/* The page is the root page */
*rec = btr_root_raise_and_insert(cursor, entry, mtr);
@@ -1292,10 +1282,10 @@ btr_cur_upd_lock_and_undo(
ulint offsets_[REC_OFFS_NORMAL_SIZE];
*offsets_ = (sizeof offsets_) / sizeof *offsets_;
- err = lock_clust_rec_modify_check_and_lock
- (flags, rec, index,
- rec_get_offsets(rec, index, offsets_,
- ULINT_UNDEFINED, &heap), thr);
+ err = lock_clust_rec_modify_check_and_lock(
+ flags, rec, index,
+ rec_get_offsets(rec, index, offsets_,
+ ULINT_UNDEFINED, &heap), thr);
if (UNIV_LIKELY_NULL(heap)) {
mem_heap_free(heap);
}
@@ -1328,7 +1318,7 @@ btr_cur_update_in_place_log(
mtr_t* mtr) /* in: mtr */
{
byte* log_ptr;
- page_t* page = ut_align_down(rec, UNIV_PAGE_SIZE);
+ page_t* page = page_align(rec);
ut_ad(flags < 256);
ut_ad(!!page_is_comp(page) == dict_table_is_comp(index->table));
@@ -1355,7 +1345,7 @@ btr_cur_update_in_place_log(
log_ptr = row_upd_write_sys_vals_to_log(index, trx, roll_ptr, log_ptr,
mtr);
- mach_write_to_2(log_ptr, ut_align_offset(rec, UNIV_PAGE_SIZE));
+ mach_write_to_2(log_ptr, page_offset(rec));
log_ptr += 2;
row_upd_index_write_log(update, log_ptr, mtr);
@@ -1514,11 +1504,8 @@ btr_cur_update_in_place(
row_upd_rec_sys_fields(rec, index, offsets, trx, roll_ptr);
}
- /* FIXME: in a mixed tree, all records may not have enough ordering
- fields for btr search: */
-
- was_delete_marked = rec_get_deleted_flag
- (rec, page_is_comp(buf_block_get_frame(block)));
+ was_delete_marked = rec_get_deleted_flag(
+ rec, page_is_comp(buf_block_get_frame(block)));
row_upd_rec_in_place(rec, offsets, update);
@@ -1529,8 +1516,8 @@ btr_cur_update_in_place(
btr_cur_update_in_place_log(flags, rec, index, update, trx, roll_ptr,
mtr);
if (was_delete_marked
- && !rec_get_deleted_flag(rec, page_is_comp
- (buf_block_get_frame(block)))) {
+ && !rec_get_deleted_flag(rec, page_is_comp(
+ buf_block_get_frame(block)))) {
/* The new updated record owns its possible externally
stored fields */
@@ -1801,7 +1788,6 @@ btr_cur_pessimistic_update(
big_rec_t* dummy_big_rec;
dict_index_t* index;
page_t* page;
- dict_tree_t* tree;
rec_t* rec;
page_cur_t* page_cursor;
dtuple_t* new_entry;
@@ -1825,9 +1811,8 @@ btr_cur_pessimistic_update(
page = btr_cur_get_page(cursor);
rec = btr_cur_get_rec(cursor);
index = cursor->index;
- tree = index->tree;
- ut_ad(mtr_memo_contains(mtr, dict_tree_get_lock(tree),
+ ut_ad(mtr_memo_contains(mtr, dict_index_get_lock(index),
MTR_MEMO_X_LOCK));
ut_ad(mtr_memo_contains(mtr, buf_block_align(page),
MTR_MEMO_PAGE_X_FIX));
@@ -1912,8 +1897,8 @@ btr_cur_pessimistic_update(
n_ext_vect = btr_push_update_extern_fields(ext_vect, offsets, update);
if (UNIV_UNLIKELY(rec_get_converted_size(index, new_entry)
- >= ut_min(page_get_free_space_of_empty
- (page_is_comp(page)) / 2,
+ >= ut_min(page_get_free_space_of_empty(
+ page_is_comp(page)) / 2,
REC_MAX_DATA_SIZE))) {
big_rec_vec = dtuple_convert_big_rec(index, new_entry,
@@ -2064,7 +2049,7 @@ btr_cur_del_mark_set_clust_rec_log(
log_ptr = row_upd_write_sys_vals_to_log(index, trx, roll_ptr, log_ptr,
mtr);
- mach_write_to_2(log_ptr, ut_align_offset(rec, UNIV_PAGE_SIZE));
+ mach_write_to_2(log_ptr, page_offset(rec));
log_ptr += 2;
mlog_close(mtr, log_ptr);
@@ -2129,10 +2114,10 @@ btr_cur_parse_del_mark_set_clust_rec(
ulint offsets_[REC_OFFS_NORMAL_SIZE];
*offsets_ = (sizeof offsets_) / sizeof *offsets_;
- row_upd_rec_sys_fields_in_recovery
- (rec, rec_get_offsets(rec, index, offsets_,
- ULINT_UNDEFINED, &heap),
- pos, trx_id, roll_ptr);
+ row_upd_rec_sys_fields_in_recovery(
+ rec, rec_get_offsets(rec, index, offsets_,
+ ULINT_UNDEFINED, &heap),
+ pos, trx_id, roll_ptr);
if (UNIV_LIKELY_NULL(heap)) {
mem_heap_free(heap);
}
@@ -2261,12 +2246,12 @@ btr_cur_del_mark_set_sec_rec_log(
return;
}
- log_ptr = mlog_write_initial_log_record_fast
- (rec, MLOG_REC_SEC_DELETE_MARK, log_ptr, mtr);
+ log_ptr = mlog_write_initial_log_record_fast(
+ rec, MLOG_REC_SEC_DELETE_MARK, log_ptr, mtr);
mach_write_to_1(log_ptr, val);
log_ptr++;
- mach_write_to_2(log_ptr, ut_align_offset(rec, UNIV_PAGE_SIZE));
+ mach_write_to_2(log_ptr, page_offset(rec));
log_ptr += 2;
mlog_close(mtr, log_ptr);
@@ -2404,7 +2389,7 @@ btr_cur_compress(
mtr_t* mtr) /* in: mtr */
{
ut_ad(mtr_memo_contains(mtr,
- dict_tree_get_lock(btr_cur_get_tree(cursor)),
+ dict_index_get_lock(btr_cur_get_index(cursor)),
MTR_MEMO_X_LOCK));
ut_ad(mtr_memo_contains(mtr, buf_block_align(btr_cur_get_rec(cursor)),
MTR_MEMO_PAGE_X_FIX));
@@ -2430,7 +2415,7 @@ btr_cur_compress_if_useful(
mtr_t* mtr) /* in: mtr */
{
ut_ad(mtr_memo_contains(mtr,
- dict_tree_get_lock(btr_cur_get_tree(cursor)),
+ dict_index_get_lock(btr_cur_get_index(cursor)),
MTR_MEMO_X_LOCK));
ut_ad(mtr_memo_contains(mtr, buf_block_align(btr_cur_get_rec(cursor)),
MTR_MEMO_PAGE_X_FIX));
@@ -2483,8 +2468,8 @@ btr_cur_optimistic_delete(
ULINT_UNDEFINED, &heap);
no_compress_needed = !rec_offs_any_extern(offsets)
- && btr_cur_can_delete_without_compress
- (cursor, rec_offs_size(offsets), mtr);
+ && btr_cur_can_delete_without_compress(
+ cursor, rec_offs_size(offsets), mtr);
if (no_compress_needed) {
@@ -2492,8 +2477,8 @@ btr_cur_optimistic_delete(
btr_search_update_hash_on_delete(cursor);
- max_ins_size = page_get_max_insert_size_after_reorganize
- (page, 1);
+ max_ins_size = page_get_max_insert_size_after_reorganize(
+ page, 1);
page_cur_delete_rec(btr_cur_get_page_cur(cursor),
cursor->index, offsets, mtr);
@@ -2537,7 +2522,7 @@ btr_cur_pessimistic_delete(
mtr_t* mtr) /* in: mtr */
{
page_t* page;
- dict_tree_t* tree;
+ dict_index_t* index;
rec_t* rec;
dtuple_t* node_ptr;
ulint n_extents = 0;
@@ -2549,9 +2534,9 @@ btr_cur_pessimistic_delete(
ulint* offsets;
page = btr_cur_get_page(cursor);
- tree = btr_cur_get_tree(cursor);
+ index = btr_cur_get_index(cursor);
- ut_ad(mtr_memo_contains(mtr, dict_tree_get_lock(tree),
+ ut_ad(mtr_memo_contains(mtr, dict_index_get_lock(index),
MTR_MEMO_X_LOCK));
ut_ad(mtr_memo_contains(mtr, buf_block_align(page),
MTR_MEMO_PAGE_X_FIX));
@@ -2563,7 +2548,7 @@ btr_cur_pessimistic_delete(
n_extents = cursor->tree_height / 32 + 1;
success = fsp_reserve_free_extents(&n_reserved,
- cursor->index->space,
+ index->space,
n_extents,
FSP_CLEANING, mtr);
if (!success) {
@@ -2576,8 +2561,7 @@ btr_cur_pessimistic_delete(
heap = mem_heap_create(1024);
rec = btr_cur_get_rec(cursor);
- offsets = rec_get_offsets(rec, cursor->index,
- NULL, ULINT_UNDEFINED, &heap);
+ offsets = rec_get_offsets(rec, index, NULL, ULINT_UNDEFINED, &heap);
/* Free externally stored fields if the record is neither
a node pointer nor in two-byte format.
@@ -2585,13 +2569,13 @@ btr_cur_pessimistic_delete(
if (page_is_comp(page)
? !rec_get_node_ptr_flag(rec)
: !rec_get_1byte_offs_flag(rec)) {
- btr_rec_free_externally_stored_fields(cursor->index,
+ btr_rec_free_externally_stored_fields(index,
rec, offsets,
in_rollback, mtr);
}
if (UNIV_UNLIKELY(page_get_n_recs(page) < 2)
- && UNIV_UNLIKELY(dict_tree_get_page(btr_cur_get_tree(cursor))
+ && UNIV_UNLIKELY(dict_index_get_page(btr_cur_get_index(cursor))
!= buf_frame_get_page_no(page))) {
/* If there is only one record, drop the whole page in
@@ -2609,8 +2593,8 @@ btr_cur_pessimistic_delete(
level = btr_page_get_level(page, mtr);
if (level > 0
- && UNIV_UNLIKELY(rec == page_rec_get_next
- (page_get_infimum_rec(page)))) {
+ && UNIV_UNLIKELY(rec == page_rec_get_next(
+ page_get_infimum_rec(page)))) {
rec_t* next_rec = page_rec_get_next(rec);
@@ -2628,23 +2612,22 @@ btr_cur_pessimistic_delete(
so that it is equal to the new leftmost node pointer
on the page */
- btr_node_ptr_delete(tree, page, mtr);
+ btr_node_ptr_delete(index, page, mtr);
- node_ptr = dict_tree_build_node_ptr
- (tree, next_rec, buf_frame_get_page_no(page),
- heap, level);
+ node_ptr = dict_index_build_node_ptr(
+ index, next_rec, buf_frame_get_page_no(page),
+ heap, level);
- btr_insert_on_non_leaf_level(tree,
+ btr_insert_on_non_leaf_level(index,
level + 1, node_ptr, mtr);
}
}
btr_search_update_hash_on_delete(cursor);
- page_cur_delete_rec(btr_cur_get_page_cur(cursor), cursor->index,
- offsets, mtr);
+ page_cur_delete_rec(btr_cur_get_page_cur(cursor), index, offsets, mtr);
- ut_ad(btr_check_node_ptr(tree, page, mtr));
+ ut_ad(btr_check_node_ptr(index, page, mtr));
*err = DB_SUCCESS;
@@ -2656,8 +2639,7 @@ return_after_reservations:
}
if (n_extents > 0) {
- fil_space_release_free_extents(cursor->index->space,
- n_reserved);
+ fil_space_release_free_extents(index->space, n_reserved);
}
return(ret);
@@ -2939,8 +2921,8 @@ btr_estimate_number_of_different_key_vals(
}
total_external_size
- += btr_rec_get_externally_stored_len
- (rec, offsets_rec);
+ += btr_rec_get_externally_stored_len(
+ rec, offsets_rec);
rec = next_rec;
/* Initialize offsets_rec for the next round
@@ -2974,8 +2956,8 @@ btr_estimate_number_of_different_key_vals(
offsets_rec = rec_get_offsets(rec, index, offsets_rec,
ULINT_UNDEFINED, &heap);
- total_external_size += btr_rec_get_externally_stored_len
- (rec, offsets_rec);
+ total_external_size += btr_rec_get_externally_stored_len(
+ rec, offsets_rec);
mtr_commit(&mtr);
}
@@ -3137,8 +3119,8 @@ btr_cur_mark_extern_inherited_fields(
}
if (!is_updated) {
- btr_cur_set_ownership_of_extern_field
- (rec, offsets, i, FALSE, mtr);
+ btr_cur_set_ownership_of_extern_field(
+ rec, offsets, i, FALSE, mtr);
}
}
}
@@ -3291,8 +3273,8 @@ btr_push_update_extern_fields(
if (upd_get_nth_field(update, i)->extern_storage) {
- ext_vect[n_pushed] = upd_get_nth_field
- (update, i)->field_no;
+ ext_vect[n_pushed] = upd_get_nth_field(
+ update, i)->field_no;
n_pushed++;
}
@@ -3389,7 +3371,7 @@ btr_store_big_rec_extern_fields(
mtr_t mtr;
ut_ad(rec_offs_validate(rec, index, offsets));
- ut_ad(mtr_memo_contains(local_mtr, dict_tree_get_lock(index->tree),
+ ut_ad(mtr_memo_contains(local_mtr, dict_index_get_lock(index),
MTR_MEMO_X_LOCK));
ut_ad(mtr_memo_contains(local_mtr, buf_block_align(rec),
MTR_MEMO_PAGE_X_FIX));
@@ -3422,7 +3404,7 @@ btr_store_big_rec_extern_fields(
hint_page_no = prev_page_no + 1;
}
- page = btr_page_alloc(index->tree, hint_page_no,
+ page = btr_page_alloc(index, hint_page_no,
FSP_NO_DIR, 0, &mtr);
if (page == NULL) {
@@ -3509,10 +3491,10 @@ btr_store_big_rec_extern_fields(
/* Set the bit denoting that this field
in rec is stored externally */
- rec_set_nth_field_extern_bit
- (rec, index,
- big_rec_vec->fields[i].field_no,
- TRUE, &mtr);
+ rec_set_nth_field_extern_bit(
+ rec, index,
+ big_rec_vec->fields[i].field_no,
+ TRUE, &mtr);
}
prev_page_no = page_no;
@@ -3563,7 +3545,7 @@ btr_free_externally_stored_field(
mtr_t mtr;
ut_a(local_len >= BTR_EXTERN_FIELD_REF_SIZE);
- ut_ad(mtr_memo_contains(local_mtr, dict_tree_get_lock(index->tree),
+ ut_ad(mtr_memo_contains(local_mtr, dict_index_get_lock(index),
MTR_MEMO_X_LOCK));
ut_ad(mtr_memo_contains(local_mtr, buf_block_align(data),
MTR_MEMO_PAGE_X_FIX));
@@ -3635,7 +3617,7 @@ btr_free_externally_stored_field(
because we did not store it on the page (we save the space
overhead from an index page header. */
- btr_page_free_low(index->tree, page, 0, &mtr);
+ btr_page_free_low(index, page, 0, &mtr);
mlog_write_ulint(data + local_len + BTR_EXTERN_PAGE_NO,
next_page_no,
diff --git a/storage/innobase/btr/btr0pcur.c b/storage/innobase/btr/btr0pcur.c
index a8d8b2f072a..65b3c90c809 100644
--- a/storage/innobase/btr/btr0pcur.c
+++ b/storage/innobase/btr/btr0pcur.c
@@ -76,20 +76,20 @@ btr_pcur_store_position(
{
page_cur_t* page_cursor;
rec_t* rec;
- dict_tree_t* tree;
+ dict_index_t* index;
page_t* page;
ulint offs;
ut_a(cursor->pos_state == BTR_PCUR_IS_POSITIONED);
ut_ad(cursor->latch_mode != BTR_NO_LATCHES);
- tree = btr_cur_get_tree(btr_pcur_get_btr_cur(cursor));
+ index = btr_cur_get_index(btr_pcur_get_btr_cur(cursor));
page_cursor = btr_pcur_get_page_cur(cursor);
rec = page_cur_get_rec(page_cursor);
- page = ut_align_down(rec, UNIV_PAGE_SIZE);
- offs = ut_align_offset(rec, UNIV_PAGE_SIZE);
+ page = page_align(rec);
+ offs = page_offset(rec);
ut_ad(mtr_memo_contains(mtr, buf_block_align(page),
MTR_MEMO_PAGE_S_FIX)
@@ -133,13 +133,13 @@ btr_pcur_store_position(
}
cursor->old_stored = BTR_PCUR_OLD_STORED;
- cursor->old_rec = dict_tree_copy_rec_order_prefix
- (tree, rec, &cursor->old_n_fields,
- &cursor->old_rec_buf, &cursor->buf_size);
+ cursor->old_rec = dict_index_copy_rec_order_prefix(
+ index, rec, &cursor->old_n_fields,
+ &cursor->old_rec_buf, &cursor->buf_size);
cursor->block_when_stored = buf_block_align(page);
- cursor->modify_clock = buf_block_get_modify_clock
- (cursor->block_when_stored);
+ cursor->modify_clock = buf_block_get_modify_clock(
+ cursor->block_when_stored);
}
/******************************************************************
@@ -197,13 +197,15 @@ btr_pcur_restore_position(
btr_pcur_t* cursor, /* in: detached persistent cursor */
mtr_t* mtr) /* in: mtr */
{
- dict_tree_t* tree;
+ dict_index_t* index;
page_t* page;
dtuple_t* tuple;
ulint mode;
ulint old_mode;
mem_heap_t* heap;
+ index = btr_cur_get_index(btr_pcur_get_btr_cur(cursor));
+
if (UNIV_UNLIKELY(cursor->old_stored != BTR_PCUR_OLD_STORED)
|| UNIV_UNLIKELY(cursor->pos_state != BTR_PCUR_WAS_POSITIONED
&& cursor->pos_state != BTR_PCUR_IS_POSITIONED)) {
@@ -215,17 +217,16 @@ btr_pcur_restore_position(
ut_error;
}
- if (UNIV_UNLIKELY
- (cursor->rel_pos == BTR_PCUR_AFTER_LAST_IN_TREE
- || cursor->rel_pos == BTR_PCUR_BEFORE_FIRST_IN_TREE)) {
+ if (UNIV_UNLIKELY(
+ cursor->rel_pos == BTR_PCUR_AFTER_LAST_IN_TREE
+ || cursor->rel_pos == BTR_PCUR_BEFORE_FIRST_IN_TREE)) {
/* In these cases we do not try an optimistic restoration,
but always do a search */
- btr_cur_open_at_index_side
- (cursor->rel_pos == BTR_PCUR_BEFORE_FIRST_IN_TREE,
- btr_pcur_get_btr_cur(cursor)->index, latch_mode,
- btr_pcur_get_btr_cur(cursor), mtr);
+ btr_cur_open_at_index_side(
+ cursor->rel_pos == BTR_PCUR_BEFORE_FIRST_IN_TREE,
+ index, latch_mode, btr_pcur_get_btr_cur(cursor), mtr);
cursor->block_when_stored
= buf_block_align(btr_pcur_get_page(cursor));
@@ -242,10 +243,10 @@ btr_pcur_restore_position(
|| UNIV_LIKELY(latch_mode == BTR_MODIFY_LEAF)) {
/* Try optimistic restoration */
- if (UNIV_LIKELY
- (buf_page_optimistic_get(latch_mode,
- cursor->block_when_stored, page,
- cursor->modify_clock, mtr))) {
+ if (UNIV_LIKELY(buf_page_optimistic_get(
+ latch_mode,
+ cursor->block_when_stored, page,
+ cursor->modify_clock, mtr))) {
cursor->pos_state = BTR_PCUR_IS_POSITIONED;
#ifdef UNIV_SYNC_DEBUG
buf_page_dbg_add_level(page, SYNC_TREE_NODE);
@@ -255,20 +256,18 @@ btr_pcur_restore_position(
rec_t* rec;
ulint* offsets1;
ulint* offsets2;
- dict_index_t* index;
#endif /* UNIV_DEBUG */
cursor->latch_mode = latch_mode;
#ifdef UNIV_DEBUG
rec = btr_pcur_get_rec(cursor);
- index = btr_pcur_get_btr_cur(cursor)->index;
heap = mem_heap_create(256);
- offsets1 = rec_get_offsets
- (cursor->old_rec, index, NULL,
- cursor->old_n_fields, &heap);
- offsets2 = rec_get_offsets
- (rec, index, NULL,
- cursor->old_n_fields, &heap);
+ offsets1 = rec_get_offsets(
+ cursor->old_rec, index, NULL,
+ cursor->old_n_fields, &heap);
+ offsets2 = rec_get_offsets(
+ rec, index, NULL,
+ cursor->old_n_fields, &heap);
ut_ad(!cmp_rec_rec(cursor->old_rec,
rec, offsets1, offsets2,
@@ -286,9 +285,8 @@ btr_pcur_restore_position(
heap = mem_heap_create(256);
- tree = btr_cur_get_tree(btr_pcur_get_btr_cur(cursor));
- tuple = dict_tree_build_data_tuple(tree, cursor->old_rec,
- cursor->old_n_fields, heap);
+ tuple = dict_index_build_data_tuple(index, cursor->old_rec,
+ cursor->old_n_fields, heap);
/* Save the old search mode of the cursor */
old_mode = cursor->search_mode;
@@ -302,8 +300,8 @@ btr_pcur_restore_position(
mode = PAGE_CUR_L;
}
- btr_pcur_open_with_no_init(btr_pcur_get_btr_cur(cursor)->index, tuple,
- mode, latch_mode, cursor, 0, mtr);
+ btr_pcur_open_with_no_init(index, tuple, mode, latch_mode,
+ cursor, 0, mtr);
/* Restore the old search mode */
cursor->search_mode = old_mode;
@@ -311,19 +309,18 @@ btr_pcur_restore_position(
if (cursor->rel_pos == BTR_PCUR_ON
&& btr_pcur_is_on_user_rec(cursor, mtr)
&& 0 == cmp_dtuple_rec(tuple, btr_pcur_get_rec(cursor),
- rec_get_offsets
- (btr_pcur_get_rec(cursor),
- btr_pcur_get_btr_cur(cursor)->index,
- NULL, ULINT_UNDEFINED, &heap))) {
+ rec_get_offsets(
+ btr_pcur_get_rec(cursor), index,
+ NULL, ULINT_UNDEFINED, &heap))) {
/* We have to store the NEW value for the modify clock, since
the cursor can now be on a different page! But we can retain
the value of old_rec */
- cursor->block_when_stored = buf_block_align
- (btr_pcur_get_page(cursor));
- cursor->modify_clock = buf_block_get_modify_clock
- (cursor->block_when_stored);
+ cursor->block_when_stored = buf_block_align(
+ btr_pcur_get_page(cursor));
+ cursor->modify_clock = buf_block_get_modify_clock(
+ cursor->block_when_stored);
cursor->old_stored = BTR_PCUR_OLD_STORED;
mem_heap_free(heap);
diff --git a/storage/innobase/btr/btr0sea.c b/storage/innobase/btr/btr0sea.c
index bb089c4c417..2fe3606a390 100644
--- a/storage/innobase/btr/btr0sea.c
+++ b/storage/innobase/btr/btr0sea.c
@@ -74,7 +74,7 @@ btr_search_build_page_hash_index(
ulint n_fields,/* in: hash this many full fields */
ulint n_bytes,/* in: hash this many bytes from the next
field */
- ulint side); /* in: hash for searches from this side */
+ ibool left_side);/* in: hash for searches from left side? */
/*********************************************************************
This function should be called before reserving any btr search mutex, if
@@ -157,10 +157,10 @@ btr_search_info_create(
info = mem_heap_alloc(heap, sizeof(btr_search_t));
+#ifdef UNIV_DEBUG
info->magic_n = BTR_SEARCH_MAGIC_N;
+#endif /* UNIV_DEBUG */
- info->last_search = NULL;
- info->n_direction = 0;
info->root_guess = NULL;
info->hash_analysis = 0;
@@ -179,7 +179,7 @@ btr_search_info_create(
info->n_fields = 1;
info->n_bytes = 0;
- info->side = BTR_SEARCH_LEFT_SIDE;
+ info->left_side = TRUE;
return(info);
}
@@ -224,7 +224,7 @@ btr_search_info_update_hash(
hash prefix */
if (info->n_fields >= n_unique && cursor->up_match >= n_unique) {
-
+increment_potential:
info->n_hash_potential++;
return;
@@ -233,8 +233,7 @@ btr_search_info_update_hash(
cmp = ut_pair_cmp(info->n_fields, info->n_bytes,
cursor->low_match, cursor->low_bytes);
- if ((info->side == BTR_SEARCH_LEFT_SIDE && cmp <= 0)
- || (info->side == BTR_SEARCH_RIGHT_SIDE && cmp > 0)) {
+ if (info->left_side ? cmp <= 0 : cmp > 0) {
goto set_new_recomm;
}
@@ -242,16 +241,11 @@ btr_search_info_update_hash(
cmp = ut_pair_cmp(info->n_fields, info->n_bytes,
cursor->up_match, cursor->up_bytes);
- if ((info->side == BTR_SEARCH_LEFT_SIDE && cmp > 0)
- || (info->side == BTR_SEARCH_RIGHT_SIDE && cmp <= 0)) {
+ if (info->left_side ? cmp <= 0 : cmp > 0) {
- goto set_new_recomm;
+ goto increment_potential;
}
- info->n_hash_potential++;
-
- return;
-
set_new_recomm:
/* We have to set a new recommendation; skip the hash analysis
for a while to avoid unnecessary CPU time usage when there is no
@@ -269,7 +263,7 @@ set_new_recomm:
info->n_fields = 1;
info->n_bytes = 0;
- info->side = BTR_SEARCH_LEFT_SIDE;
+ info->left_side = TRUE;
} else if (cmp > 0) {
info->n_hash_potential = 1;
@@ -288,7 +282,7 @@ set_new_recomm:
info->n_bytes = cursor->low_bytes + 1;
}
- info->side = BTR_SEARCH_LEFT_SIDE;
+ info->left_side = TRUE;
} else {
info->n_hash_potential = 1;
@@ -306,7 +300,7 @@ set_new_recomm:
info->n_bytes = cursor->up_bytes + 1;
}
- info->side = BTR_SEARCH_RIGHT_SIDE;
+ info->left_side = FALSE;
}
}
@@ -322,7 +316,8 @@ btr_search_update_block_hash_info(
the block is recommended */
btr_search_t* info, /* in: search info */
buf_block_t* block, /* in: buffer block */
- btr_cur_t* cursor) /* in: cursor */
+ btr_cur_t* cursor __attribute__((unused)))
+ /* in: cursor */
{
#ifdef UNIV_SYNC_DEBUG
ut_ad(!rw_lock_own(&btr_search_latch, RW_LOCK_SHARED));
@@ -335,18 +330,18 @@ btr_search_update_block_hash_info(
info->last_hash_succ = FALSE;
ut_a(block->magic_n == BUF_BLOCK_MAGIC_N);
- ut_a(info->magic_n == BTR_SEARCH_MAGIC_N);
+ ut_ad(info->magic_n == BTR_SEARCH_MAGIC_N);
if ((block->n_hash_helps > 0)
&& (info->n_hash_potential > 0)
&& (block->n_fields == info->n_fields)
&& (block->n_bytes == info->n_bytes)
- && (block->side == info->side)) {
+ && (block->left_side == info->left_side)) {
if ((block->is_hashed)
&& (block->curr_n_fields == info->n_fields)
&& (block->curr_n_bytes == info->n_bytes)
- && (block->curr_side == info->side)) {
+ && (block->curr_left_side == info->left_side)) {
/* The search would presumably have succeeded using
the hash index */
@@ -359,12 +354,14 @@ btr_search_update_block_hash_info(
block->n_hash_helps = 1;
block->n_fields = info->n_fields;
block->n_bytes = info->n_bytes;
- block->side = info->side;
+ block->left_side = info->left_side;
}
+#ifdef UNIV_DEBUG
if (cursor->index->table->does_not_fit_in_memory) {
block->n_hash_helps = 0;
}
+#endif /* UNIV_DEBUG */
if ((block->n_hash_helps > page_get_n_recs(block->frame)
/ BTR_SEARCH_PAGE_BUILD_LIMIT)
@@ -375,7 +372,7 @@ btr_search_update_block_hash_info(
> 2 * page_get_n_recs(block->frame))
|| (block->n_fields != block->curr_n_fields)
|| (block->n_bytes != block->curr_n_bytes)
- || (block->side != block->curr_side)) {
+ || (block->left_side != block->curr_left_side)) {
/* Build a new hash index on the page */
@@ -404,7 +401,7 @@ btr_search_update_hash_ref(
{
ulint fold;
rec_t* rec;
- dulint tree_id;
+ dulint index_id;
ut_ad(cursor->flag == BTR_CUR_HASH_FAIL);
#ifdef UNIV_SYNC_DEBUG
@@ -419,7 +416,7 @@ btr_search_update_hash_ref(
&& (info->n_hash_potential > 0)
&& (block->curr_n_fields == info->n_fields)
&& (block->curr_n_bytes == info->n_bytes)
- && (block->curr_side == info->side)) {
+ && (block->curr_left_side == info->left_side)) {
mem_heap_t* heap = NULL;
ulint offsets_[REC_OFFS_NORMAL_SIZE];
*offsets_ = (sizeof offsets_) / sizeof *offsets_;
@@ -431,12 +428,12 @@ btr_search_update_hash_ref(
return;
}
- tree_id = ((cursor->index)->tree)->id;
+ index_id = cursor->index->id;
fold = rec_fold(rec,
rec_get_offsets(rec, cursor->index, offsets_,
ULINT_UNDEFINED, &heap),
block->curr_n_fields,
- block->curr_n_bytes, tree_id);
+ block->curr_n_bytes, index_id);
if (UNIV_LIKELY_NULL(heap)) {
mem_heap_free(heap);
}
@@ -509,7 +506,7 @@ btr_search_info_update_slow(
params = mem_alloc(3 * sizeof(ulint));
params[0] = block->n_fields;
params[1] = block->n_bytes;
- params[2] = block->side;
+ params[2] = block->left_side;
/* Make sure the compiler cannot deduce the values and do
optimizations */
@@ -618,8 +615,8 @@ btr_search_check_guess(
prev_rec = page_rec_get_prev(rec);
if (page_rec_is_infimum(prev_rec)) {
- success = btr_page_get_prev
- (buf_frame_align(prev_rec), mtr) == FIL_NULL;
+ success = btr_page_get_prev(
+ buf_frame_align(prev_rec), mtr) == FIL_NULL;
goto exit_func;
}
@@ -643,8 +640,9 @@ btr_search_check_guess(
next_rec = page_rec_get_next(rec);
if (page_rec_is_supremum(next_rec)) {
- if (btr_page_get_next
- (buf_frame_align(next_rec), mtr) == FIL_NULL) {
+ if (btr_page_get_next(
+ buf_frame_align(next_rec), mtr)
+ == FIL_NULL) {
cursor->up_match = 0;
success = TRUE;
@@ -702,7 +700,7 @@ btr_search_guess_on_hash(
page_t* page;
ulint fold;
ulint tuple_n_fields;
- dulint tree_id;
+ dulint index_id;
ibool can_only_compare_to_cursor_rec = TRUE;
#ifdef notdefined
btr_cur_t cursor2;
@@ -736,12 +734,12 @@ btr_search_guess_on_hash(
return(FALSE);
}
- tree_id = (index->tree)->id;
+ index_id = index->id;
#ifdef UNIV_SEARCH_PERF_STAT
info->n_hash_succ++;
#endif
- fold = dtuple_fold(tuple, cursor->n_fields, cursor->n_bytes, tree_id);
+ fold = dtuple_fold(tuple, cursor->n_fields, cursor->n_bytes, index_id);
cursor->fold = fold;
cursor->flag = BTR_CUR_HASH;
@@ -763,10 +761,11 @@ btr_search_guess_on_hash(
if (UNIV_LIKELY(!has_search_latch)) {
- if (UNIV_UNLIKELY
- (!buf_page_get_known_nowait(latch_mode, page,
- BUF_MAKE_YOUNG,
- __FILE__, __LINE__, mtr))) {
+ if (UNIV_UNLIKELY(
+ !buf_page_get_known_nowait(latch_mode, page,
+ BUF_MAKE_YOUNG,
+ __FILE__, __LINE__,
+ mtr))) {
goto failure_unlock;
}
@@ -801,7 +800,8 @@ btr_search_guess_on_hash(
is positioned on. We cannot look at the next of the previous
record to determine if our guess for the cursor position is
right. */
- if (UNIV_EXPECT(ut_dulint_cmp(tree_id, btr_page_get_index_id(page)), 0)
+ if (UNIV_EXPECT(
+ ut_dulint_cmp(index_id, btr_page_get_index_id(page)), 0)
|| !btr_search_check_guess(cursor,
can_only_compare_to_cursor_rec,
tuple, mode, mtr)) {
@@ -904,7 +904,7 @@ btr_search_drop_page_hash_index(
rec_t* rec;
ulint fold;
ulint prev_fold;
- dulint tree_id;
+ dulint index_id;
ulint n_cached;
ulint n_recs;
ulint* folds;
@@ -961,9 +961,9 @@ retry:
rec = page_get_infimum_rec(page);
rec = page_rec_get_next(rec);
- tree_id = btr_page_get_index_id(page);
+ index_id = btr_page_get_index_id(page);
- ut_a(0 == ut_dulint_cmp(tree_id, index->id));
+ ut_a(0 == ut_dulint_cmp(index_id, index->id));
prev_fold = 0;
@@ -971,12 +971,10 @@ retry:
offsets = NULL;
while (!page_rec_is_supremum(rec)) {
- /* FIXME: in a mixed tree, not all records may have enough
- ordering fields: */
offsets = rec_get_offsets(rec, index, offsets,
n_fields + (n_bytes > 0), &heap);
ut_a(rec_offs_n_fields(offsets) == n_fields + (n_bytes > 0));
- fold = rec_fold(rec, offsets, n_fields, n_bytes, tree_id);
+ fold = rec_fold(rec, offsets, n_fields, n_bytes, index_id);
if (fold == prev_fold && prev_fold != 0) {
@@ -1101,7 +1099,7 @@ btr_search_build_page_hash_index(
ulint n_fields,/* in: hash this many full fields */
ulint n_bytes,/* in: hash this many bytes from the next
field */
- ulint side) /* in: hash for searches from this side */
+ ibool left_side)/* in: hash for searches from left side? */
{
hash_table_t* table;
buf_block_t* block;
@@ -1109,7 +1107,7 @@ btr_search_build_page_hash_index(
rec_t* next_rec;
ulint fold;
ulint next_fold;
- dulint tree_id;
+ dulint index_id;
ulint n_cached;
ulint n_recs;
ulint* folds;
@@ -1135,7 +1133,7 @@ btr_search_build_page_hash_index(
if (block->is_hashed && ((block->curr_n_fields != n_fields)
|| (block->curr_n_bytes != n_bytes)
- || (block->curr_side != side))) {
+ || (block->curr_left_side != left_side))) {
rw_lock_s_unlock(&btr_search_latch);
@@ -1172,7 +1170,7 @@ btr_search_build_page_hash_index(
n_cached = 0;
- tree_id = btr_page_get_index_id(page);
+ index_id = btr_page_get_index_id(page);
rec = page_get_infimum_rec(page);
rec = page_rec_get_next(rec);
@@ -1188,11 +1186,9 @@ btr_search_build_page_hash_index(
}
}
- /* FIXME: in a mixed tree, all records may not have enough ordering
- fields: */
- fold = rec_fold(rec, offsets, n_fields, n_bytes, tree_id);
+ fold = rec_fold(rec, offsets, n_fields, n_bytes, index_id);
- if (side == BTR_SEARCH_LEFT_SIDE) {
+ if (left_side) {
folds[n_cached] = fold;
recs[n_cached] = rec;
@@ -1204,7 +1200,7 @@ btr_search_build_page_hash_index(
if (page_rec_is_supremum(next_rec)) {
- if (side == BTR_SEARCH_RIGHT_SIDE) {
+ if (!left_side) {
folds[n_cached] = fold;
recs[n_cached] = rec;
@@ -1217,12 +1213,12 @@ btr_search_build_page_hash_index(
offsets = rec_get_offsets(next_rec, index, offsets,
n_fields + (n_bytes > 0), &heap);
next_fold = rec_fold(next_rec, offsets, n_fields,
- n_bytes, tree_id);
+ n_bytes, index_id);
if (fold != next_fold) {
/* Insert an entry into the hash index */
- if (side == BTR_SEARCH_LEFT_SIDE) {
+ if (left_side) {
folds[n_cached] = next_fold;
recs[n_cached] = next_rec;
@@ -1244,7 +1240,7 @@ btr_search_build_page_hash_index(
if (block->is_hashed && ((block->curr_n_fields != n_fields)
|| (block->curr_n_bytes != n_bytes)
- || (block->curr_side != side))) {
+ || (block->curr_left_side != left_side))) {
goto exit_func;
}
@@ -1253,7 +1249,7 @@ btr_search_build_page_hash_index(
block->curr_n_fields = n_fields;
block->curr_n_bytes = n_bytes;
- block->curr_side = side;
+ block->curr_left_side = left_side;
block->index = index;
for (i = 0; i < n_cached; i++) {
@@ -1292,7 +1288,7 @@ btr_search_move_or_delete_hash_entries(
buf_block_t* new_block;
ulint n_fields;
ulint n_bytes;
- ulint side;
+ ibool left_side;
block = buf_block_align(page);
new_block = buf_block_align(new_page);
@@ -1320,22 +1316,23 @@ btr_search_move_or_delete_hash_entries(
n_fields = block->curr_n_fields;
n_bytes = block->curr_n_bytes;
- side = block->curr_side;
+ left_side = block->curr_left_side;
new_block->n_fields = block->curr_n_fields;
new_block->n_bytes = block->curr_n_bytes;
- new_block->side = block->curr_side;
+ new_block->left_side = left_side;
rw_lock_s_unlock(&btr_search_latch);
ut_a(n_fields + n_bytes > 0);
btr_search_build_page_hash_index(index, new_page, n_fields,
- n_bytes, side);
+ n_bytes, left_side);
+#if 1 /* TODO: safe to remove? */
ut_a(n_fields == block->curr_n_fields);
ut_a(n_bytes == block->curr_n_bytes);
- ut_a(side == block->curr_side);
-
+ ut_a(left_side == block->curr_left_side);
+#endif
return;
}
@@ -1356,7 +1353,7 @@ btr_search_update_hash_on_delete(
buf_block_t* block;
rec_t* rec;
ulint fold;
- dulint tree_id;
+ dulint index_id;
ibool found;
ulint offsets_[REC_OFFS_NORMAL_SIZE];
mem_heap_t* heap = NULL;
@@ -1380,10 +1377,10 @@ btr_search_update_hash_on_delete(
table = btr_search_sys->hash_index;
- tree_id = cursor->index->tree->id;
+ index_id = cursor->index->id;
fold = rec_fold(rec, rec_get_offsets(rec, cursor->index, offsets_,
ULINT_UNDEFINED, &heap),
- block->curr_n_fields, block->curr_n_bytes, tree_id);
+ block->curr_n_fields, block->curr_n_bytes, index_id);
if (UNIV_LIKELY_NULL(heap)) {
mem_heap_free(heap);
}
@@ -1429,7 +1426,7 @@ btr_search_update_hash_node_on_insert(
if ((cursor->flag == BTR_CUR_HASH)
&& (cursor->n_fields == block->curr_n_fields)
&& (cursor->n_bytes == block->curr_n_bytes)
- && (block->curr_side == BTR_SEARCH_RIGHT_SIDE)) {
+ && !block->curr_left_side) {
table = btr_search_sys->hash_index;
@@ -1460,13 +1457,13 @@ btr_search_update_hash_on_insert(
rec_t* rec;
rec_t* ins_rec;
rec_t* next_rec;
- dulint tree_id;
+ dulint index_id;
ulint fold;
ulint ins_fold;
ulint next_fold = 0; /* remove warning (??? bug ???) */
ulint n_fields;
ulint n_bytes;
- ulint side;
+ ibool left_side;
ibool locked = FALSE;
mem_heap_t* heap = NULL;
ulint offsets_[REC_OFFS_NORMAL_SIZE];
@@ -1492,32 +1489,32 @@ btr_search_update_hash_on_insert(
ut_a(block->index == cursor->index);
- tree_id = ((cursor->index)->tree)->id;
+ index_id = cursor->index->id;
n_fields = block->curr_n_fields;
n_bytes = block->curr_n_bytes;
- side = block->curr_side;
+ left_side = block->curr_left_side;
ins_rec = page_rec_get_next(rec);
next_rec = page_rec_get_next(ins_rec);
offsets = rec_get_offsets(ins_rec, cursor->index, offsets,
ULINT_UNDEFINED, &heap);
- ins_fold = rec_fold(ins_rec, offsets, n_fields, n_bytes, tree_id);
+ ins_fold = rec_fold(ins_rec, offsets, n_fields, n_bytes, index_id);
if (!page_rec_is_supremum(next_rec)) {
offsets = rec_get_offsets(next_rec, cursor->index, offsets,
n_fields + (n_bytes > 0), &heap);
next_fold = rec_fold(next_rec, offsets, n_fields,
- n_bytes, tree_id);
+ n_bytes, index_id);
}
if (!page_rec_is_infimum(rec)) {
offsets = rec_get_offsets(rec, cursor->index, offsets,
n_fields + (n_bytes > 0), &heap);
- fold = rec_fold(rec, offsets, n_fields, n_bytes, tree_id);
+ fold = rec_fold(rec, offsets, n_fields, n_bytes, index_id);
} else {
- if (side == BTR_SEARCH_LEFT_SIDE) {
+ if (left_side) {
rw_lock_x_lock(&btr_search_latch);
@@ -1538,7 +1535,7 @@ btr_search_update_hash_on_insert(
locked = TRUE;
}
- if (side == BTR_SEARCH_RIGHT_SIDE) {
+ if (!left_side) {
ha_insert_for_fold(table, fold, rec);
} else {
ha_insert_for_fold(table, ins_fold, ins_rec);
@@ -1548,7 +1545,7 @@ btr_search_update_hash_on_insert(
check_next_rec:
if (page_rec_is_supremum(next_rec)) {
- if (side == BTR_SEARCH_RIGHT_SIDE) {
+ if (!left_side) {
if (!locked) {
rw_lock_x_lock(&btr_search_latch);
@@ -1571,7 +1568,7 @@ check_next_rec:
locked = TRUE;
}
- if (side == BTR_SEARCH_RIGHT_SIDE) {
+ if (!left_side) {
ha_insert_for_fold(table, ins_fold, ins_rec);
/*
@@ -1659,17 +1656,17 @@ btr_search_validate(void)
" node fold %lu, rec fold %lu\n",
(ulong) buf_frame_get_page_no(page),
node->data,
- (ulong) ut_dulint_get_high
- (btr_page_get_index_id(page)),
- (ulong) ut_dulint_get_low
- (btr_page_get_index_id(page)),
+ (ulong) ut_dulint_get_high(
+ btr_page_get_index_id(page)),
+ (ulong) ut_dulint_get_low(
+ btr_page_get_index_id(page)),
(ulong) node->fold,
(ulong) rec_fold((rec_t*)(node->data),
offsets,
block->curr_n_fields,
block->curr_n_bytes,
- btr_page_get_index_id
- (page)));
+ btr_page_get_index_id(
+ page)));
fputs("InnoDB: Record ", stderr);
rec_print_new(stderr, (rec_t*)node->data,
@@ -1681,7 +1678,7 @@ btr_search_validate(void)
(void*) page, (ulong) block->is_hashed,
(ulong) block->curr_n_fields,
(ulong) block->curr_n_bytes,
- (ulong) block->curr_side);
+ (ulong) block->curr_left_side);
if (n_page_dumps < 20) {
buf_page_print(page);
diff --git a/storage/innobase/buf/buf0buf.c b/storage/innobase/buf/buf0buf.c
index 4e8cd97c9a8..222acc015a6 100644
--- a/storage/innobase/buf/buf0buf.c
+++ b/storage/innobase/buf/buf0buf.c
@@ -350,9 +350,9 @@ buf_page_is_corrupted(
if (srv_use_checksums) {
old_checksum = buf_calc_page_old_checksum(read_buf);
- old_checksum_field = mach_read_from_4
- (read_buf + UNIV_PAGE_SIZE
- - FIL_PAGE_END_LSN_OLD_CHKSUM);
+ old_checksum_field = mach_read_from_4(
+ read_buf + UNIV_PAGE_SIZE
+ - FIL_PAGE_END_LSN_OLD_CHKSUM);
/* There are 2 valid formulas for old_checksum_field:
@@ -459,8 +459,8 @@ buf_page_print(
if (dict_sys != NULL) {
- index = dict_index_find_on_id_low
- (btr_page_get_index_id(read_buf));
+ index = dict_index_find_on_id_low(
+ btr_page_get_index_id(read_buf));
if (index) {
fputs("InnoDB: (", stderr);
dict_index_name_print(stderr, NULL, index);
@@ -598,8 +598,8 @@ buf_pool_init(
/* Allocate the virtual address space window, i.e., the
buffer pool frames */
- buf_pool->frame_mem = os_awe_allocate_virtual_mem_window
- (UNIV_PAGE_SIZE * (n_frames + 1));
+ buf_pool->frame_mem = os_awe_allocate_virtual_mem_window(
+ UNIV_PAGE_SIZE * (n_frames + 1));
/* Allocate the physical memory for AWE and the AWE info array
for buf_pool */
@@ -625,8 +625,8 @@ buf_pool_init(
}
/*----------------------------------------*/
} else {
- buf_pool->frame_mem = os_mem_alloc_large
- (UNIV_PAGE_SIZE * (n_frames + 1), TRUE, FALSE);
+ buf_pool->frame_mem = os_mem_alloc_large(
+ UNIV_PAGE_SIZE * (n_frames + 1), TRUE, FALSE);
}
if (buf_pool->frame_mem == NULL) {
@@ -821,10 +821,10 @@ buf_awe_map_page_to_frame(
} else {
/* We can map block to the frame of bck */
- os_awe_map_physical_mem_to_window
- (bck->frame,
- UNIV_PAGE_SIZE / OS_AWE_X86_PAGE_SIZE,
- block->awe_info);
+ os_awe_map_physical_mem_to_window(
+ bck->frame,
+ UNIV_PAGE_SIZE / OS_AWE_X86_PAGE_SIZE,
+ block->awe_info);
block->frame = bck->frame;
@@ -840,10 +840,10 @@ buf_awe_map_page_to_frame(
bck);
if (add_to_mapped_list) {
- UT_LIST_ADD_FIRST
- (awe_LRU_free_mapped,
- buf_pool->awe_LRU_free_mapped,
- block);
+ UT_LIST_ADD_FIRST(
+ awe_LRU_free_mapped,
+ buf_pool->awe_LRU_free_mapped,
+ block);
}
buf_pool->n_pages_awe_remapped++;
@@ -1583,7 +1583,7 @@ buf_page_init_for_backup_restore(
block->is_hashed = FALSE;
block->n_fields = 1;
block->n_bytes = 0;
- block->side = BTR_SEARCH_LEFT_SIDE;
+ block->left_side = TRUE;
block->file_page_was_freed = FALSE;
}
@@ -1650,7 +1650,7 @@ buf_page_init(
block->is_hashed = FALSE;
block->n_fields = 1;
block->n_bytes = 0;
- block->side = BTR_SEARCH_LEFT_SIDE;
+ block->left_side = TRUE;
block->file_page_was_freed = FALSE;
}
@@ -1710,8 +1710,8 @@ buf_page_init_for_read(
mutex_enter(&(buf_pool->mutex));
- if (fil_tablespace_deleted_or_being_deleted_in_mem
- (space, tablespace_version)) {
+ if (fil_tablespace_deleted_or_being_deleted_in_mem(
+ space, tablespace_version)) {
*err = DB_TABLESPACE_DELETED;
}
@@ -1891,10 +1891,10 @@ buf_page_io_complete(
/* If this page is not uninitialized and not in the
doublewrite buffer, then the page number and space id
should be the same as in block. */
- ulint read_page_no = mach_read_from_4
- (block->frame + FIL_PAGE_OFFSET);
- ulint read_space_id = mach_read_from_4
- (block->frame + FIL_PAGE_ARCH_LOG_NO_OR_SPACE_ID);
+ ulint read_page_no = mach_read_from_4(
+ block->frame + FIL_PAGE_OFFSET);
+ ulint read_space_id = mach_read_from_4(
+ block->frame + FIL_PAGE_ARCH_LOG_NO_OR_SPACE_ID);
if (!block->space
&& trx_doublewrite_page_inside(block->offset)) {
@@ -1980,9 +1980,9 @@ buf_page_io_complete(
}
if (!recv_no_ibuf_operations) {
- ibuf_merge_or_delete_for_page
- (block->frame, block->space,
- block->offset, TRUE);
+ ibuf_merge_or_delete_for_page(
+ block->frame, block->space, block->offset,
+ TRUE);
}
}
@@ -2110,8 +2110,9 @@ buf_validate(void)
if (block->flush_type == BUF_FLUSH_LRU) {
n_lru_flush++;
- ut_a(rw_lock_is_locked
- (&block->lock, RW_LOCK_SHARED));
+ ut_a(rw_lock_is_locked(
+ &block->lock,
+ RW_LOCK_SHARED));
} else if (block->flush_type
== BUF_FLUSH_LIST) {
n_list_flush++;
diff --git a/storage/innobase/buf/buf0flu.c b/storage/innobase/buf/buf0flu.c
index 9274b67a555..8ef8c3b9358 100644
--- a/storage/innobase/buf/buf0flu.c
+++ b/storage/innobase/buf/buf0flu.c
@@ -890,8 +890,8 @@ buf_flush_batch(
old_page_count = page_count;
/* Try to flush also all the neighbors */
- page_count += buf_flush_try_neighbors
- (space, offset, flush_type);
+ page_count += buf_flush_try_neighbors(
+ space, offset, flush_type);
/* fprintf(stderr,
"Flush type %lu, page no %lu, neighb %lu\n",
flush_type, offset,
diff --git a/storage/innobase/buf/buf0lru.c b/storage/innobase/buf/buf0lru.c
index f0264f2e323..4ebe94c40ec 100644
--- a/storage/innobase/buf/buf0lru.c
+++ b/storage/innobase/buf/buf0lru.c
@@ -542,16 +542,16 @@ buf_LRU_old_adjust_len(void)
if (old_len < new_len - BUF_LRU_OLD_TOLERANCE) {
- buf_pool->LRU_old = UT_LIST_GET_PREV
- (LRU, buf_pool->LRU_old);
+ buf_pool->LRU_old = UT_LIST_GET_PREV(
+ LRU, buf_pool->LRU_old);
(buf_pool->LRU_old)->old = TRUE;
buf_pool->LRU_old_len++;
} else if (old_len > new_len + BUF_LRU_OLD_TOLERANCE) {
(buf_pool->LRU_old)->old = FALSE;
- buf_pool->LRU_old = UT_LIST_GET_NEXT
- (LRU, buf_pool->LRU_old);
+ buf_pool->LRU_old = UT_LIST_GET_NEXT(
+ LRU, buf_pool->LRU_old);
buf_pool->LRU_old_len--;
} else {
ut_a(buf_pool->LRU_old); /* Check that we did not
diff --git a/storage/innobase/buf/buf0rea.c b/storage/innobase/buf/buf0rea.c
index cf7aa97191f..fdec0206990 100644
--- a/storage/innobase/buf/buf0rea.c
+++ b/storage/innobase/buf/buf0rea.c
@@ -257,10 +257,10 @@ buf_read_ahead_random(
mode: hence FALSE as the first parameter */
if (!ibuf_bitmap_page(i)) {
- count += buf_read_page_low
- (&err, FALSE,
- ibuf_mode | OS_AIO_SIMULATED_WAKE_LATER,
- space, tablespace_version, i);
+ count += buf_read_page_low(
+ &err, FALSE,
+ ibuf_mode | OS_AIO_SIMULATED_WAKE_LATER,
+ space, tablespace_version, i);
if (err == DB_TABLESPACE_DELETED) {
ut_print_timestamp(stderr);
fprintf(stderr,
@@ -549,10 +549,10 @@ buf_read_ahead_linear(
aio mode: hence FALSE as the first parameter */
if (!ibuf_bitmap_page(i)) {
- count += buf_read_page_low
- (&err, FALSE,
- ibuf_mode | OS_AIO_SIMULATED_WAKE_LATER,
- space, tablespace_version, i);
+ count += buf_read_page_low(
+ &err, FALSE,
+ ibuf_mode | OS_AIO_SIMULATED_WAKE_LATER,
+ space, tablespace_version, i);
if (err == DB_TABLESPACE_DELETED) {
ut_print_timestamp(stderr);
fprintf(stderr,
diff --git a/storage/innobase/data/data0data.c b/storage/innobase/data/data0data.c
index 804d02e8f59..fc4494d991a 100644
--- a/storage/innobase/data/data0data.c
+++ b/storage/innobase/data/data0data.c
@@ -540,8 +540,8 @@ dtuple_convert_big_rec(
n_fields = 0;
while (rec_get_converted_size(index, entry)
- >= ut_min(page_get_free_space_of_empty
- (dict_table_is_comp(index->table)) / 2,
+ >= ut_min(page_get_free_space_of_empty(
+ dict_table_is_comp(index->table)) / 2,
REC_MAX_DATA_SIZE)) {
longest = 0;
@@ -610,8 +610,8 @@ dtuple_convert_big_rec(
vector->fields[n_fields].len = dfield->len
- DICT_MAX_INDEX_COL_LEN;
- vector->fields[n_fields].data = mem_heap_alloc
- (heap, vector->fields[n_fields].len);
+ vector->fields[n_fields].data = mem_heap_alloc(
+ heap, vector->fields[n_fields].len);
/* Copy data (from the end of field) to big rec vector */
diff --git a/storage/innobase/data/data0type.c b/storage/innobase/data/data0type.c
index 43fc8c55e35..77779d185cf 100644
--- a/storage/innobase/data/data0type.c
+++ b/storage/innobase/data/data0type.c
@@ -40,9 +40,6 @@ charset-collation code for them. */
ulint data_mysql_default_charset_coll = 99999999;
-dtype_t dtype_binary_val = {DATA_BINARY, 0, 0, 0, 0, 0};
-dtype_t* dtype_binary = &dtype_binary_val;
-
/*************************************************************************
Determine how many bytes the first n characters of the given string occupy.
If the string is shorter than n characters, returns the number of bytes
@@ -53,7 +50,11 @@ dtype_get_at_most_n_mbchars(
/*========================*/
/* out: length of the prefix,
in bytes */
- const dtype_t* dtype, /* in: data type */
+ ulint prtype, /* in: precise type */
+ ulint mbminlen, /* in: minimum length of a
+ multi-byte character */
+ ulint mbmaxlen, /* in: maximum length of a
+ multi-byte character */
ulint prefix_len, /* in: length of the requested
prefix, in characters, multiplied by
dtype_get_mbmaxlen(dtype) */
@@ -63,12 +64,12 @@ dtype_get_at_most_n_mbchars(
{
#ifndef UNIV_HOTBACKUP
ut_a(data_len != UNIV_SQL_NULL);
- ut_ad(!dtype->mbmaxlen || !(prefix_len % dtype->mbmaxlen));
+ ut_ad(!mbmaxlen || !(prefix_len % mbmaxlen));
- if (dtype->mbminlen != dtype->mbmaxlen) {
- ut_a(!(prefix_len % dtype->mbmaxlen));
- return(innobase_get_at_most_n_mbchars
- (dtype_get_charset_coll(dtype->prtype),
+ if (mbminlen != mbmaxlen) {
+ ut_a(!(prefix_len % mbmaxlen));
+ return(innobase_get_at_most_n_mbchars(
+ dtype_get_charset_coll(prtype),
prefix_len, data_len, str));
}
@@ -270,8 +271,6 @@ dtype_print(
} else if (prtype == DATA_TRX_ID) {
fputs("DATA_TRX_ID", stderr);
len = DATA_TRX_ID_LEN;
- } else if (prtype == DATA_MIX_ID) {
- fputs("DATA_MIX_ID", stderr);
} else if (prtype == DATA_ENGLISH) {
fputs("DATA_ENGLISH", stderr);
} else {
@@ -291,38 +290,5 @@ dtype_print(
}
}
- fprintf(stderr, " len %lu prec %lu", (ulong) len, (ulong) type->prec);
-}
-
-/***************************************************************************
-Returns the maximum size of a data type. Note: types in system tables may be
-incomplete and return incorrect information. */
-
-ulint
-dtype_get_max_size(
-/*===============*/
- /* out: maximum size (ULINT_MAX for
- unbounded types) */
- const dtype_t* type) /* in: type */
-{
- switch (type->mtype) {
- case DATA_SYS:
- case DATA_CHAR:
- case DATA_FIXBINARY:
- case DATA_INT:
- case DATA_FLOAT:
- case DATA_DOUBLE:
- case DATA_MYSQL:
- case DATA_VARCHAR:
- case DATA_BINARY:
- case DATA_DECIMAL:
- case DATA_VARMYSQL:
- return(type->len);
- case DATA_BLOB:
- return(ULINT_MAX);
- default:
- ut_error;
- }
-
- return(ULINT_MAX);
+ fprintf(stderr, " len %lu", (ulong) len);
}
diff --git a/storage/innobase/dict/dict0boot.c b/storage/innobase/dict/dict0boot.c
index 0515adb9a8f..08515d8fb13 100644
--- a/storage/innobase/dict/dict0boot.c
+++ b/storage/innobase/dict/dict0boot.c
@@ -58,8 +58,7 @@ dict_hdr_get_new_id(
dulint id;
mtr_t mtr;
- ut_ad((type == DICT_HDR_TABLE_ID) || (type == DICT_HDR_INDEX_ID)
- || (type == DICT_HDR_MIX_ID));
+ ut_ad((type == DICT_HDR_TABLE_ID) || (type == DICT_HDR_INDEX_ID));
mtr_start(&mtr);
@@ -141,6 +140,7 @@ dict_hdr_create(
mlog_write_dulint(dict_header + DICT_HDR_INDEX_ID,
ut_dulint_create(0, DICT_HDR_FIRST_ID), mtr);
+ /* Obsolete, but we must initialize it to 0 anyway. */
mlog_write_dulint(dict_header + DICT_HDR_MIX_ID,
ut_dulint_create(0, DICT_HDR_FIRST_ID), mtr);
@@ -214,7 +214,6 @@ dict_boot(void)
dict_index_t* index;
dict_hdr_t* dict_hdr;
mtr_t mtr;
- ibool success;
mtr_start(&mtr);
@@ -236,25 +235,25 @@ dict_boot(void)
..._MARGIN, it will immediately be updated to the disk-based
header. */
- dict_sys->row_id = ut_dulint_add
- (ut_dulint_align_up(mtr_read_dulint
- (dict_hdr + DICT_HDR_ROW_ID, &mtr),
- DICT_HDR_ROW_ID_WRITE_MARGIN),
- DICT_HDR_ROW_ID_WRITE_MARGIN);
+ dict_sys->row_id = ut_dulint_add(
+ ut_dulint_align_up(mtr_read_dulint(dict_hdr + DICT_HDR_ROW_ID,
+ &mtr),
+ DICT_HDR_ROW_ID_WRITE_MARGIN),
+ DICT_HDR_ROW_ID_WRITE_MARGIN);
/* Insert into the dictionary cache the descriptions of the basic
system tables */
/*-------------------------*/
table = dict_mem_table_create("SYS_TABLES", DICT_HDR_SPACE, 8, 0);
- dict_mem_table_add_col(table, "NAME", DATA_BINARY, 0, 0, 0);
- dict_mem_table_add_col(table, "ID", DATA_BINARY, 0, 0, 0);
- dict_mem_table_add_col(table, "N_COLS", DATA_INT, 0, 4, 0);
- dict_mem_table_add_col(table, "TYPE", DATA_INT, 0, 4, 0);
- dict_mem_table_add_col(table, "MIX_ID", DATA_BINARY, 0, 0, 0);
- dict_mem_table_add_col(table, "MIX_LEN", DATA_INT, 0, 4, 0);
- dict_mem_table_add_col(table, "CLUSTER_NAME", DATA_BINARY, 0, 0, 0);
- dict_mem_table_add_col(table, "SPACE", DATA_INT, 0, 4, 0);
+ dict_mem_table_add_col(table, "NAME", DATA_BINARY, 0, 0);
+ dict_mem_table_add_col(table, "ID", DATA_BINARY, 0, 0);
+ dict_mem_table_add_col(table, "N_COLS", DATA_INT, 0, 4);
+ dict_mem_table_add_col(table, "TYPE", DATA_INT, 0, 4);
+ dict_mem_table_add_col(table, "MIX_ID", DATA_BINARY, 0, 0);
+ dict_mem_table_add_col(table, "MIX_LEN", DATA_INT, 0, 4);
+ dict_mem_table_add_col(table, "CLUSTER_NAME", DATA_BINARY, 0, 0);
+ dict_mem_table_add_col(table, "SPACE", DATA_INT, 0, 4);
table->id = DICT_TABLES_ID;
@@ -269,31 +268,30 @@ dict_boot(void)
index->id = DICT_TABLES_ID;
- success = dict_index_add_to_cache(table, index, mtr_read_ulint
- (dict_hdr + DICT_HDR_TABLES,
- MLOG_4BYTES, &mtr));
- ut_a(success);
+ dict_index_add_to_cache(table, index,
+ mtr_read_ulint(dict_hdr + DICT_HDR_TABLES,
+ MLOG_4BYTES, &mtr));
+
/*-------------------------*/
index = dict_mem_index_create("SYS_TABLES", "ID_IND",
DICT_HDR_SPACE, DICT_UNIQUE, 1);
dict_mem_index_add_field(index, "ID", 0);
index->id = DICT_TABLE_IDS_ID;
- success = dict_index_add_to_cache(table, index,
- mtr_read_ulint
- (dict_hdr + DICT_HDR_TABLE_IDS,
- MLOG_4BYTES, &mtr));
- ut_a(success);
+ dict_index_add_to_cache(table, index,
+ mtr_read_ulint(dict_hdr + DICT_HDR_TABLE_IDS,
+ MLOG_4BYTES, &mtr));
+
/*-------------------------*/
table = dict_mem_table_create("SYS_COLUMNS", DICT_HDR_SPACE, 7, 0);
- dict_mem_table_add_col(table, "TABLE_ID", DATA_BINARY,0,0,0);
- dict_mem_table_add_col(table, "POS", DATA_INT, 0, 4, 0);
- dict_mem_table_add_col(table, "NAME", DATA_BINARY, 0, 0, 0);
- dict_mem_table_add_col(table, "MTYPE", DATA_INT, 0, 4, 0);
- dict_mem_table_add_col(table, "PRTYPE", DATA_INT, 0, 4, 0);
- dict_mem_table_add_col(table, "LEN", DATA_INT, 0, 4, 0);
- dict_mem_table_add_col(table, "PREC", DATA_INT, 0, 4, 0);
+ dict_mem_table_add_col(table, "TABLE_ID", DATA_BINARY, 0, 0);
+ dict_mem_table_add_col(table, "POS", DATA_INT, 0, 4);
+ dict_mem_table_add_col(table, "NAME", DATA_BINARY, 0, 0);
+ dict_mem_table_add_col(table, "MTYPE", DATA_INT, 0, 4);
+ dict_mem_table_add_col(table, "PRTYPE", DATA_INT, 0, 4);
+ dict_mem_table_add_col(table, "LEN", DATA_INT, 0, 4);
+ dict_mem_table_add_col(table, "PREC", DATA_INT, 0, 4);
table->id = DICT_COLUMNS_ID;
@@ -308,20 +306,20 @@ dict_boot(void)
dict_mem_index_add_field(index, "POS", 0);
index->id = DICT_COLUMNS_ID;
- success = dict_index_add_to_cache(table, index, mtr_read_ulint
- (dict_hdr + DICT_HDR_COLUMNS,
- MLOG_4BYTES, &mtr));
- ut_a(success);
+ dict_index_add_to_cache(table, index,
+ mtr_read_ulint(dict_hdr + DICT_HDR_COLUMNS,
+ MLOG_4BYTES, &mtr));
+
/*-------------------------*/
table = dict_mem_table_create("SYS_INDEXES", DICT_HDR_SPACE, 7, 0);
- dict_mem_table_add_col(table, "TABLE_ID", DATA_BINARY, 0,0,0);
- dict_mem_table_add_col(table, "ID", DATA_BINARY, 0, 0, 0);
- dict_mem_table_add_col(table, "NAME", DATA_BINARY, 0, 0, 0);
- dict_mem_table_add_col(table, "N_FIELDS", DATA_INT, 0, 4, 0);
- dict_mem_table_add_col(table, "TYPE", DATA_INT, 0, 4, 0);
- dict_mem_table_add_col(table, "SPACE", DATA_INT, 0, 4, 0);
- dict_mem_table_add_col(table, "PAGE_NO", DATA_INT, 0, 4, 0);
+ dict_mem_table_add_col(table, "TABLE_ID", DATA_BINARY, 0, 0);
+ dict_mem_table_add_col(table, "ID", DATA_BINARY, 0, 0);
+ dict_mem_table_add_col(table, "NAME", DATA_BINARY, 0, 0);
+ dict_mem_table_add_col(table, "N_FIELDS", DATA_INT, 0, 4);
+ dict_mem_table_add_col(table, "TYPE", DATA_INT, 0, 4);
+ dict_mem_table_add_col(table, "SPACE", DATA_INT, 0, 4);
+ dict_mem_table_add_col(table, "PAGE_NO", DATA_INT, 0, 4);
/* The '+ 2' below comes from the 2 system fields */
#if DICT_SYS_INDEXES_PAGE_NO_FIELD != 6 + 2
@@ -346,16 +344,16 @@ dict_boot(void)
dict_mem_index_add_field(index, "ID", 0);
index->id = DICT_INDEXES_ID;
- success = dict_index_add_to_cache(table, index, mtr_read_ulint
- (dict_hdr + DICT_HDR_INDEXES,
- MLOG_4BYTES, &mtr));
- ut_a(success);
+ dict_index_add_to_cache(table, index,
+ mtr_read_ulint(dict_hdr + DICT_HDR_INDEXES,
+ MLOG_4BYTES, &mtr));
+
/*-------------------------*/
table = dict_mem_table_create("SYS_FIELDS", DICT_HDR_SPACE, 3, 0);
- dict_mem_table_add_col(table, "INDEX_ID", DATA_BINARY, 0,0,0);
- dict_mem_table_add_col(table, "POS", DATA_INT, 0, 4, 0);
- dict_mem_table_add_col(table, "COL_NAME", DATA_BINARY, 0,0,0);
+ dict_mem_table_add_col(table, "INDEX_ID", DATA_BINARY, 0, 0);
+ dict_mem_table_add_col(table, "POS", DATA_INT, 0, 4);
+ dict_mem_table_add_col(table, "COL_NAME", DATA_BINARY, 0, 0);
table->id = DICT_FIELDS_ID;
dict_table_add_to_cache(table);
@@ -369,10 +367,9 @@ dict_boot(void)
dict_mem_index_add_field(index, "POS", 0);
index->id = DICT_FIELDS_ID;
- success = dict_index_add_to_cache(table, index, mtr_read_ulint
- (dict_hdr + DICT_HDR_FIELDS,
- MLOG_4BYTES, &mtr));
- ut_a(success);
+ dict_index_add_to_cache(table, index,
+ mtr_read_ulint(dict_hdr + DICT_HDR_FIELDS,
+ MLOG_4BYTES, &mtr));
mtr_commit(&mtr);
/*-------------------------*/
diff --git a/storage/innobase/dict/dict0crea.c b/storage/innobase/dict/dict0crea.c
index c912ea0fd1a..75422b929b1 100644
--- a/storage/innobase/dict/dict0crea.c
+++ b/storage/innobase/dict/dict0crea.c
@@ -78,14 +78,14 @@ dict_create_sys_tables_tuple(
mach_write_to_4(ptr, DICT_TABLE_ORDINARY);
dfield_set_data(dfield, ptr, 4);
- /* 6: MIX_ID ---------------------------*/
+ /* 6: MIX_ID (obsolete) ---------------------------*/
dfield = dtuple_get_nth_field(entry, 4);
ptr = mem_heap_alloc(heap, 8);
memset(ptr, 0, 8);
dfield_set_data(dfield, ptr, 8);
- /* 7: MIX_LEN --------------------------*/
+ /* 7: MIX_LEN (obsolete) --------------------------*/
dfield = dtuple_get_nth_field(entry, 5);
@@ -124,11 +124,12 @@ dict_create_sys_columns_tuple(
mem_heap_t* heap) /* in: memory heap from which the memory for
the built tuple is allocated */
{
- dict_table_t* sys_columns;
- dtuple_t* entry;
- dict_col_t* column;
- dfield_t* dfield;
- byte* ptr;
+ dict_table_t* sys_columns;
+ dtuple_t* entry;
+ const dict_col_t* column;
+ dfield_t* dfield;
+ byte* ptr;
+ const char* col_name;
ut_ad(table && heap);
@@ -155,33 +156,34 @@ dict_create_sys_columns_tuple(
/* 4: NAME ---------------------------*/
dfield = dtuple_get_nth_field(entry, 2);
- dfield_set_data(dfield, column->name, ut_strlen(column->name));
+ col_name = dict_table_get_col_name(table, i);
+ dfield_set_data(dfield, col_name, ut_strlen(col_name));
/* 5: MTYPE --------------------------*/
dfield = dtuple_get_nth_field(entry, 3);
ptr = mem_heap_alloc(heap, 4);
- mach_write_to_4(ptr, (column->type).mtype);
+ mach_write_to_4(ptr, column->mtype);
dfield_set_data(dfield, ptr, 4);
/* 6: PRTYPE -------------------------*/
dfield = dtuple_get_nth_field(entry, 4);
ptr = mem_heap_alloc(heap, 4);
- mach_write_to_4(ptr, (column->type).prtype);
+ mach_write_to_4(ptr, column->prtype);
dfield_set_data(dfield, ptr, 4);
/* 7: LEN ----------------------------*/
dfield = dtuple_get_nth_field(entry, 5);
ptr = mem_heap_alloc(heap, 4);
- mach_write_to_4(ptr, (column->type).len);
+ mach_write_to_4(ptr, column->len);
dfield_set_data(dfield, ptr, 4);
/* 8: PREC ---------------------------*/
dfield = dtuple_get_nth_field(entry, 6);
ptr = mem_heap_alloc(heap, 4);
- mach_write_to_4(ptr, (column->type).prec);
+ mach_write_to_4(ptr, 0/* unused */);
dfield_set_data(dfield, ptr, 4);
/*---------------------------------*/
@@ -222,8 +224,7 @@ dict_build_table_def_step(
row_len = 0;
for (i = 0; i < table->n_def; i++) {
- row_len += dtype_get_min_size(dict_col_get_type
- (&table->cols[i]));
+ row_len += dict_col_get_min_size(&table->cols[i]);
}
if (row_len > BTR_PAGE_MAX_REC_SIZE) {
return(DB_TOO_BIG_RECORD);
@@ -238,7 +239,7 @@ dict_build_table_def_step(
- page 3 will contain the root of the clustered index of the
table we create here. */
- table->space = 0; /* reset to zero for the call below */
+ ulint space = 0; /* reset to zero for the call below */
if (table->dir_path_of_temp_table) {
/* We place tables created with CREATE TEMPORARY
@@ -251,9 +252,11 @@ dict_build_table_def_step(
is_path = FALSE;
}
- error = fil_create_new_single_table_tablespace
- (&table->space, path_or_name, is_path,
- FIL_IBD_FILE_INITIAL_SIZE);
+ error = fil_create_new_single_table_tablespace(
+ &space, path_or_name, is_path,
+ FIL_IBD_FILE_INITIAL_SIZE);
+ table->space = space;
+
if (error != DB_SUCCESS) {
return(error);
@@ -768,8 +771,8 @@ dict_truncate_index_tree(
appropriate field in the SYS_INDEXES record: this mini-transaction
marks the B-tree totally truncated */
- comp = page_is_comp(btr_page_get
- (space, root_page_no, RW_X_LATCH, mtr));
+ comp = page_is_comp(btr_page_get(space, root_page_no, RW_X_LATCH,
+ mtr));
btr_free_root(space, root_page_no, mtr);
/* We will temporarily write FIL_NULL to the PAGE_NO field
@@ -798,7 +801,7 @@ dict_truncate_index_tree(
root_page_no = btr_create(type, space, index_id, comp, mtr);
if (index) {
- index->tree->page = root_page_no;
+ index->page = root_page_no;
} else {
ut_print_timestamp(stderr);
fprintf(stderr,
@@ -1004,7 +1007,6 @@ dict_create_index_step(
que_thr_t* thr) /* in: query thread */
{
ind_node_t* node;
- ibool success;
ulint err = DB_ERROR;
trx_t* trx;
@@ -1088,10 +1090,8 @@ dict_create_index_step(
if (node->state == INDEX_ADD_TO_CACHE) {
- success = dict_index_add_to_cache(node->table, node->index,
- node->page_no);
-
- ut_a(success);
+ dict_index_add_to_cache(node->table, node->index,
+ node->page_no);
err = DB_SUCCESS;
}
@@ -1328,13 +1328,14 @@ dict_create_add_foreign_field_to_dictionary(
pars_info_add_str_literal(info, "ref_col_name",
foreign->referenced_col_names[field_nr]);
- return(dict_foreign_eval_sql
- (info, "PROCEDURE P () IS\n"
- "BEGIN\n"
- "INSERT INTO SYS_FOREIGN_COLS VALUES"
- "(:id, :pos, :for_col_name, :ref_col_name);\n"
- "END;\n",
- table, foreign, trx));
+ return(dict_foreign_eval_sql(
+ info,
+ "PROCEDURE P () IS\n"
+ "BEGIN\n"
+ "INSERT INTO SYS_FOREIGN_COLS VALUES"
+ "(:id, :pos, :for_col_name, :ref_col_name);\n"
+ "END;\n",
+ table, foreign, trx));
}
/************************************************************************
@@ -1393,8 +1394,8 @@ dict_create_add_foreign_to_dictionary(
}
for (i = 0; i < foreign->n_fields; i++) {
- error = dict_create_add_foreign_field_to_dictionary
- (i, table, foreign, trx);
+ error = dict_create_add_foreign_field_to_dictionary(
+ i, table, foreign, trx);
if (error != DB_SUCCESS) {
@@ -1450,8 +1451,8 @@ dict_create_add_foreigns_to_dictionary(
foreign;
foreign = UT_LIST_GET_NEXT(foreign_list, foreign)) {
- error = dict_create_add_foreign_to_dictionary
- (&number, table, foreign, trx);
+ error = dict_create_add_foreign_to_dictionary(&number, table,
+ foreign, trx);
if (error != DB_SUCCESS) {
diff --git a/storage/innobase/dict/dict0dict.c b/storage/innobase/dict/dict0dict.c
index f98898a44a0..44a374fe550 100644
--- a/storage/innobase/dict/dict0dict.c
+++ b/storage/innobase/dict/dict0dict.c
@@ -48,8 +48,6 @@ rw_lock_t dict_operation_lock; /* table create, drop, etc. reserve
creating a table or index object */
#define DICT_POOL_PER_TABLE_HASH 512 /* buffer pool max size per table
hash table fixed size in bytes */
-#define DICT_POOL_PER_COL_HASH 128 /* buffer pool max size per column
- hash table fixed size in bytes */
#define DICT_POOL_PER_VARYING 4 /* buffer pool max size per data
dictionary varying size in bytes */
@@ -130,32 +128,6 @@ innobase_get_charset(
#endif /* !UNIV_HOTBACKUP */
/**************************************************************************
-Adds a column to the data dictionary hash table. */
-static
-void
-dict_col_add_to_cache(
-/*==================*/
- dict_table_t* table, /* in: table */
- dict_col_t* col); /* in: column */
-/**************************************************************************
-Repositions a column in the data dictionary hash table when the table name
-changes. */
-static
-void
-dict_col_reposition_in_cache(
-/*=========================*/
- dict_table_t* table, /* in: table */
- dict_col_t* col, /* in: column */
- const char* new_name); /* in: new table name */
-/**************************************************************************
-Removes a column from the data dictionary hash table. */
-static
-void
-dict_col_remove_from_cache(
-/*=======================*/
- dict_table_t* table, /* in: table */
- dict_col_t* col); /* in: column */
-/**************************************************************************
Removes an index from the dictionary cache. */
static
void
@@ -171,16 +143,16 @@ dict_index_copy(
/*============*/
dict_index_t* index1, /* in: index to copy to */
dict_index_t* index2, /* in: index to copy from */
+ dict_table_t* table, /* in: table */
ulint start, /* in: first position to copy */
ulint end); /* in: last position to copy */
/***********************************************************************
-Tries to find column names for the index in the column hash table and
-sets the col field of the index. */
+Tries to find column names for the index and sets the col field of the
+index. */
static
-ibool
+void
dict_index_find_cols(
/*=================*/
- /* out: TRUE if success */
dict_table_t* table, /* in: table */
dict_index_t* index); /* in: index */
/***********************************************************************
@@ -220,7 +192,8 @@ static
void
dict_col_print_low(
/*===============*/
- dict_col_t* col); /* in: column */
+ const dict_table_t* table, /* in: table */
+ const dict_col_t* col); /* in: column */
/**************************************************************************
Prints an index data. */
static
@@ -352,15 +325,27 @@ dict_table_decrement_handle_count(
mutex_exit(&(dict_sys->mutex));
}
+/*************************************************************************
+Gets the column data type. */
+
+void
+dict_col_copy_type_noninline(
+/*=========================*/
+ const dict_col_t* col, /* in: column */
+ dtype_t* type) /* out: data type */
+{
+ dict_col_copy_type(col, type);
+}
+
/************************************************************************
Gets the nth column of a table. */
-dict_col_t*
+const dict_col_t*
dict_table_get_nth_col_noninline(
/*=============================*/
- /* out: pointer to column object */
- dict_table_t* table, /* in: table */
- ulint pos) /* in: position of column */
+ /* out: pointer to column object */
+ const dict_table_t* table, /* in: table */
+ ulint pos) /* in: position of column */
{
return(dict_table_get_nth_col(table, pos));
}
@@ -402,6 +387,35 @@ dict_table_get_index_noninline(
return(dict_table_get_index(table, name));
}
+/**************************************************************************
+Returns a column's name. */
+
+const char*
+dict_table_get_col_name(
+/*====================*/
+ /* out: column name. NOTE: not
+ guaranteed to stay valid if table is
+ modified in any way (columns added,
+ etc.). */
+ const dict_table_t* table, /* in: table */
+ ulint col_nr) /* in: column number */
+{
+ ulint i;
+ const char* s;
+
+ ut_ad(table);
+ ut_ad(col_nr < table->n_def);
+ ut_ad(table->magic_n == DICT_TABLE_MAGIC_N);
+
+ s = table->col_names;
+
+ for (i = 0; i < col_nr; i++) {
+ s += strlen(s) + 1;
+ }
+
+ return(s);
+}
+
/************************************************************************
Initializes the autoinc counter. It is not an error to initialize an already
initialized counter. */
@@ -544,10 +558,10 @@ dict_index_get_nth_col_pos(
dict_index_t* index, /* in: index */
ulint n) /* in: column number */
{
- dict_field_t* field;
- dict_col_t* col;
- ulint pos;
- ulint n_fields;
+ const dict_field_t* field;
+ const dict_col_t* col;
+ ulint pos;
+ ulint n_fields;
ut_ad(index);
ut_ad(index->magic_n == DICT_INDEX_MAGIC_N);
@@ -556,7 +570,7 @@ dict_index_get_nth_col_pos(
if (index->type & DICT_CLUSTERED) {
- return(col->clust_pos);
+ return(dict_col_get_clust_pos(col, index));
}
n_fields = dict_index_get_n_fields(index);
@@ -584,10 +598,10 @@ dict_index_contains_col_or_prefix(
dict_index_t* index, /* in: index */
ulint n) /* in: column number */
{
- dict_field_t* field;
- dict_col_t* col;
- ulint pos;
- ulint n_fields;
+ const dict_field_t* field;
+ const dict_col_t* col;
+ ulint pos;
+ ulint n_fields;
ut_ad(index);
ut_ad(index->magic_n == DICT_INDEX_MAGIC_N);
@@ -731,11 +745,11 @@ dict_table_col_in_clustered_key(
dict_table_t* table, /* in: table */
ulint n) /* in: column number */
{
- dict_index_t* index;
- dict_field_t* field;
- dict_col_t* col;
- ulint pos;
- ulint n_fields;
+ dict_index_t* index;
+ const dict_field_t* field;
+ const dict_col_t* col;
+ ulint pos;
+ ulint n_fields;
ut_ad(table);
@@ -774,9 +788,6 @@ dict_init(void)
dict_sys->table_id_hash = hash_create(buf_pool_get_max_size()
/ (DICT_POOL_PER_TABLE_HASH
* UNIV_WORD_SIZE));
- dict_sys->col_hash = hash_create(buf_pool_get_max_size()
- / (DICT_POOL_PER_COL_HASH
- * UNIV_WORD_SIZE));
dict_sys->size = 0;
UT_LIST_INIT(dict_sys->table_LRU);
@@ -884,52 +895,49 @@ dict_table_add_to_cache(
dict_mem_table_add_col(table, "DB_ROW_ID", DATA_SYS,
DATA_ROW_ID | DATA_NOT_NULL,
- DATA_ROW_ID_LEN, 0);
+ DATA_ROW_ID_LEN);
#if DATA_ROW_ID != 0
#error "DATA_ROW_ID != 0"
#endif
dict_mem_table_add_col(table, "DB_TRX_ID", DATA_SYS,
DATA_TRX_ID | DATA_NOT_NULL,
- DATA_TRX_ID_LEN, 0);
+ DATA_TRX_ID_LEN);
#if DATA_TRX_ID != 1
#error "DATA_TRX_ID != 1"
#endif
dict_mem_table_add_col(table, "DB_ROLL_PTR", DATA_SYS,
DATA_ROLL_PTR | DATA_NOT_NULL,
- DATA_ROLL_PTR_LEN, 0);
+ DATA_ROLL_PTR_LEN);
#if DATA_ROLL_PTR != 2
#error "DATA_ROLL_PTR != 2"
#endif
- dict_mem_table_add_col(table, "DB_MIX_ID", DATA_SYS,
- DATA_MIX_ID | DATA_NOT_NULL,
- DATA_MIX_ID_LEN, 0);
-#if DATA_MIX_ID != 3
-#error "DATA_MIX_ID != 3"
-#endif
/* This check reminds that if a new system column is added to
the program, it should be dealt with here */
-#if DATA_N_SYS_COLS != 4
-#error "DATA_N_SYS_COLS != 4"
+#if DATA_N_SYS_COLS != 3
+#error "DATA_N_SYS_COLS != 3"
#endif
+ /* The lower limit for what we consider a "big" row */
+#define BIG_ROW_SIZE 1024
+
row_len = 0;
for (i = 0; i < table->n_def; i++) {
- ulint col_len = dtype_get_max_size
- (dict_col_get_type(dict_table_get_nth_col(table, i)));
+ ulint col_len = dict_col_get_max_size(
+ dict_table_get_nth_col(table, i));
+
+ row_len += col_len;
/* If we have a single unbounded field, or several gigantic
- fields, mark the maximum row size as ULINT_MAX. */
- if (ut_max(col_len, row_len) >= (ULINT_MAX / 2)) {
- row_len = ULINT_MAX;
+ fields, mark the maximum row size as BIG_ROW_SIZE. */
+ if (row_len >= BIG_ROW_SIZE || col_len >= BIG_ROW_SIZE) {
+ row_len = BIG_ROW_SIZE;
break;
}
-
- row_len += col_len;
}
- table->max_row_size = row_len;
+ table->big_rows = row_len >= BIG_ROW_SIZE;
/* Look for a table with the same name: error if such exists */
{
@@ -947,11 +955,6 @@ dict_table_add_to_cache(
ut_a(table2 == NULL);
}
- /* Add the columns to the column hash table */
- for (i = 0; i < table->n_cols; i++) {
- dict_col_add_to_cache(table, dict_table_get_nth_col(table, i));
- }
-
/* Add table to hash table of tables */
HASH_INSERT(dict_table_t, name_hash, dict_sys->table_hash, fold,
table);
@@ -985,7 +988,7 @@ dict_index_find_on_id_low(
index = dict_table_get_first_index(table);
while (index) {
- if (0 == ut_dulint_cmp(id, index->tree->id)) {
+ if (0 == ut_dulint_cmp(id, index->id)) {
/* Found */
return(index);
@@ -1019,7 +1022,6 @@ dict_table_rename_in_cache(
ulint old_size;
char* old_name;
ibool success;
- ulint i;
ut_ad(table);
#ifdef UNIV_SYNC_DEBUG
@@ -1056,8 +1058,8 @@ dict_table_rename_in_cache(
table->name, table->dir_path_of_temp_table);
success = FALSE;
} else {
- success = fil_rename_tablespace
- (table->name, table->space, new_name);
+ success = fil_rename_tablespace(
+ table->name, table->space, new_name);
}
if (!success) {
@@ -1066,15 +1068,6 @@ dict_table_rename_in_cache(
}
}
- /* Reposition the columns in the column hash table; they are hashed
- according to the pair (table name, column name) */
-
- for (i = 0; i < table->n_cols; i++) {
- dict_col_reposition_in_cache(table,
- dict_table_get_nth_col(table, i),
- new_name);
- }
-
/* Remove table from the hash tables of tables */
HASH_DELETE(dict_table_t, name_hash, dict_sys->table_hash,
ut_fold_string(table->name), table);
@@ -1167,10 +1160,10 @@ dict_table_rename_in_cache(
/* This is a generated >= 4.0.18 format id */
if (strlen(table->name) > strlen(old_name)) {
- foreign->id = mem_heap_alloc
- (foreign->heap,
- strlen(table->name)
- + strlen(old_id) + 1);
+ foreign->id = mem_heap_alloc(
+ foreign->heap,
+ strlen(table->name)
+ + strlen(old_id) + 1);
}
/* Replace the prefix 'databasename/tablename'
@@ -1186,9 +1179,9 @@ dict_table_rename_in_cache(
if (dict_get_db_name_len(table->name)
> dict_get_db_name_len(foreign->id)) {
- foreign->id = mem_heap_alloc
- (foreign->heap,
- db_len + strlen(old_id) + 1);
+ foreign->id = mem_heap_alloc(
+ foreign->heap,
+ db_len + strlen(old_id) + 1);
}
/* Replace the database prefix in id with the
@@ -1214,8 +1207,8 @@ dict_table_rename_in_cache(
/* Allocate a longer name buffer;
TODO: store buf len to save memory */
- foreign->referenced_table_name = mem_heap_alloc
- (foreign->heap, strlen(table->name) + 1);
+ foreign->referenced_table_name = mem_heap_alloc(
+ foreign->heap, strlen(table->name) + 1);
}
strcpy(foreign->referenced_table_name, table->name);
@@ -1264,7 +1257,6 @@ dict_table_remove_from_cache(
dict_foreign_t* foreign;
dict_index_t* index;
ulint size;
- ulint i;
ut_ad(table);
#ifdef UNIV_SYNC_DEBUG
@@ -1305,12 +1297,6 @@ dict_table_remove_from_cache(
index = UT_LIST_GET_LAST(table->indexes);
}
- /* Remove the columns of the table from the cache */
- for (i = 0; i < table->n_cols; i++) {
- dict_col_remove_from_cache(table,
- dict_table_get_nth_col(table, i));
- }
-
/* Remove table from the hash tables of tables */
HASH_DELETE(dict_table_t, name_hash, dict_sys->table_hash,
ut_fold_string(table->name), table);
@@ -1329,90 +1315,16 @@ dict_table_remove_from_cache(
dict_mem_table_free(table);
}
-/**************************************************************************
-Adds a column to the data dictionary hash table. */
-static
-void
-dict_col_add_to_cache(
-/*==================*/
- dict_table_t* table, /* in: table */
- dict_col_t* col) /* in: column */
-{
- ulint fold;
-
- ut_ad(table && col);
-#ifdef UNIV_SYNC_DEBUG
- ut_ad(mutex_own(&(dict_sys->mutex)));
-#endif /* UNIV_SYNC_DEBUG */
- ut_ad(table->magic_n == DICT_TABLE_MAGIC_N);
-
- fold = ut_fold_ulint_pair(ut_fold_string(table->name),
- ut_fold_string(col->name));
-
- /* Look for a column with same table name and column name: error */
- {
- dict_col_t* col2;
- HASH_SEARCH(hash, dict_sys->col_hash, fold, col2,
- (ut_strcmp(col->name, col2->name) == 0)
- && (ut_strcmp((col2->table)->name, table->name)
- == 0));
- ut_a(col2 == NULL);
- }
-
- HASH_INSERT(dict_col_t, hash, dict_sys->col_hash, fold, col);
-}
-
-/**************************************************************************
-Removes a column from the data dictionary hash table. */
-static
-void
-dict_col_remove_from_cache(
-/*=======================*/
- dict_table_t* table, /* in: table */
- dict_col_t* col) /* in: column */
-{
- ulint fold;
-
- ut_ad(table && col);
-#ifdef UNIV_SYNC_DEBUG
- ut_ad(mutex_own(&(dict_sys->mutex)));
-#endif /* UNIV_SYNC_DEBUG */
- ut_ad(table->magic_n == DICT_TABLE_MAGIC_N);
-
- fold = ut_fold_ulint_pair(ut_fold_string(table->name),
- ut_fold_string(col->name));
-
- HASH_DELETE(dict_col_t, hash, dict_sys->col_hash, fold, col);
-}
+/*************************************************************************
+Gets the column position in the clustered index. */
-/**************************************************************************
-Repositions a column in the data dictionary hash table when the table name
-changes. */
-static
-void
-dict_col_reposition_in_cache(
-/*=========================*/
- dict_table_t* table, /* in: table */
- dict_col_t* col, /* in: column */
- const char* new_name) /* in: new table name */
+ulint
+dict_col_get_clust_pos_noninline(
+/*=============================*/
+ const dict_col_t* col, /* in: table column */
+ const dict_index_t* clust_index) /* in: clustered index */
{
- ulint fold;
-
- ut_ad(table && col);
-#ifdef UNIV_SYNC_DEBUG
- ut_ad(mutex_own(&(dict_sys->mutex)));
-#endif /* UNIV_SYNC_DEBUG */
- ut_ad(table->magic_n == DICT_TABLE_MAGIC_N);
-
- fold = ut_fold_ulint_pair(ut_fold_string(table->name),
- ut_fold_string(col->name));
-
- HASH_DELETE(dict_col_t, hash, dict_sys->col_hash, fold, col);
-
- fold = ut_fold_ulint_pair(ut_fold_string(new_name),
- ut_fold_string(col->name));
-
- HASH_INSERT(dict_col_t, hash, dict_sys->col_hash, fold, col);
+ return(dict_col_get_clust_pos(col, clust_index));
}
/********************************************************************
@@ -1427,12 +1339,12 @@ dict_col_name_is_reserved(
{
/* This check reminds that if a new system column is added to
the program, it should be dealt with here. */
-#if DATA_N_SYS_COLS != 4
-#error "DATA_N_SYS_COLS != 4"
+#if DATA_N_SYS_COLS != 3
+#error "DATA_N_SYS_COLS != 3"
#endif
static const char* reserved_names[] = {
- "DB_ROW_ID", "DB_TRX_ID", "DB_ROLL_PTR", "DB_MIX_ID"
+ "DB_ROW_ID", "DB_TRX_ID", "DB_ROLL_PTR"
};
ulint i;
@@ -1450,20 +1362,16 @@ dict_col_name_is_reserved(
/**************************************************************************
Adds an index to the dictionary cache. */
-ibool
+void
dict_index_add_to_cache(
/*====================*/
- /* out: TRUE if success */
dict_table_t* table, /* in: table on which the index is */
dict_index_t* index, /* in, own: index; NOTE! The index memory
object is freed in this function! */
ulint page_no)/* in: root page number of the index */
{
dict_index_t* new_index;
- dict_tree_t* tree;
- dict_field_t* field;
ulint n_ord;
- ibool success;
ulint i;
ut_ad(index);
@@ -1491,13 +1399,7 @@ dict_index_add_to_cache(
ut_a(!(index->type & DICT_CLUSTERED)
|| UT_LIST_GET_LEN(table->indexes) == 0);
- success = dict_index_find_cols(table, index);
-
- if (!success) {
- dict_mem_index_free(index);
-
- return(FALSE);
- }
+ dict_index_find_cols(table, index);
/* Build the cache internal representation of the index,
containing also the added system fields */
@@ -1531,23 +1433,18 @@ dict_index_add_to_cache(
for (i = 0; i < n_ord; i++) {
- field = dict_index_get_nth_field(new_index, i);
-
- dict_field_get_col(field)->ord_part++;
+ dict_index_get_nth_field(new_index, i)->col->ord_part = 1;
}
- /* Create an index tree memory object for the index */
- tree = dict_tree_create(new_index, page_no);
- ut_ad(tree);
-
- new_index->tree = tree;
+ new_index->page = page_no;
+ rw_lock_create(&new_index->lock, SYNC_INDEX_TREE);
if (!UNIV_UNLIKELY(new_index->type & DICT_UNIVERSAL)) {
- new_index->stat_n_diff_key_vals = mem_heap_alloc
- (new_index->heap,
- (1 + dict_index_get_n_unique(new_index))
- * sizeof(ib_longlong));
+ new_index->stat_n_diff_key_vals = mem_heap_alloc(
+ new_index->heap,
+ (1 + dict_index_get_n_unique(new_index))
+ * sizeof(ib_longlong));
/* Give some sensible values to stat_n_... in case we do
not calculate statistics quickly enough */
@@ -1557,14 +1454,9 @@ dict_index_add_to_cache(
}
}
- /* Add the index to the list of indexes stored in the tree */
- tree->tree_index = new_index;
-
dict_sys->size += mem_heap_get_size(new_index->heap);
dict_mem_index_free(index);
-
- return(TRUE);
}
/**************************************************************************
@@ -1576,9 +1468,7 @@ dict_index_remove_from_cache(
dict_table_t* table, /* in: table */
dict_index_t* index) /* in, own: index */
{
- dict_field_t* field;
ulint size;
- ulint i;
ut_ad(table && index);
ut_ad(table->magic_n == DICT_TABLE_MAGIC_N);
@@ -1587,17 +1477,7 @@ dict_index_remove_from_cache(
ut_ad(mutex_own(&(dict_sys->mutex)));
#endif /* UNIV_SYNC_DEBUG */
- ut_ad(index->tree->tree_index);
- dict_tree_free(index->tree);
-
- /* Decrement the ord_part counts in columns which are ordering */
- for (i = 0; i < dict_index_get_n_unique(index); i++) {
-
- field = dict_index_get_nth_field(index, i);
-
- ut_ad(dict_field_get_col(field)->ord_part > 0);
- (dict_field_get_col(field)->ord_part)--;
- }
+ rw_lock_free(&index->lock);
/* Remove the index from the list of indexes of the table */
UT_LIST_REMOVE(indexes, table->indexes, index);
@@ -1612,19 +1492,15 @@ dict_index_remove_from_cache(
}
/***********************************************************************
-Tries to find column names for the index in the column hash table and
-sets the col field of the index. */
+Tries to find column names for the index and sets the col field of the
+index. */
static
-ibool
+void
dict_index_find_cols(
/*=================*/
- /* out: TRUE if success */
dict_table_t* table, /* in: table */
dict_index_t* index) /* in: index */
{
- dict_col_t* col;
- dict_field_t* field;
- ulint fold;
ulint i;
ut_ad(table && index);
@@ -1634,24 +1510,25 @@ dict_index_find_cols(
#endif /* UNIV_SYNC_DEBUG */
for (i = 0; i < index->n_fields; i++) {
- field = dict_index_get_nth_field(index, i);
+ ulint j;
+ dict_field_t* field = dict_index_get_nth_field(index, i);
- fold = ut_fold_ulint_pair(ut_fold_string(table->name),
- ut_fold_string(field->name));
+ for (j = 0; j < table->n_cols; j++) {
+ if (!strcmp(dict_table_get_col_name(table, j),
+ field->name)) {
+ field->col = (dict_col_t*)
+ dict_table_get_nth_col(table, j);
- HASH_SEARCH(hash, dict_sys->col_hash, fold, col,
- (ut_strcmp(col->name, field->name) == 0)
- && (ut_strcmp((col->table)->name, table->name)
- == 0));
- if (col == NULL) {
-
- return(FALSE);
- } else {
- field->col = col;
+ goto found;
+ }
}
- }
- return(TRUE);
+ /* It is an error not to find a matching column. */
+ ut_error;
+
+ found:
+ ;
+ }
}
/***********************************************************************
@@ -1661,17 +1538,21 @@ void
dict_index_add_col(
/*===============*/
dict_index_t* index, /* in: index */
+ dict_table_t* table, /* in: table */
dict_col_t* col, /* in: column */
ulint prefix_len) /* in: column prefix length */
{
dict_field_t* field;
+ const char* col_name;
- dict_mem_index_add_field(index, col->name, prefix_len);
+ col_name = dict_table_get_col_name(table, dict_col_get_no(col));
+
+ dict_mem_index_add_field(index, col_name, prefix_len);
field = dict_index_get_nth_field(index, index->n_def - 1);
field->col = col;
- field->fixed_len = dtype_get_fixed_size(&col->type);
+ field->fixed_len = dict_col_get_fixed_size(col);
if (prefix_len && field->fixed_len > prefix_len) {
field->fixed_len = prefix_len;
@@ -1685,7 +1566,7 @@ dict_index_add_col(
field->fixed_len = 0;
}
- if (!(dtype_get_prtype(&col->type) & DATA_NOT_NULL)) {
+ if (!(col->prtype & DATA_NOT_NULL)) {
index->n_nullable++;
}
}
@@ -1698,6 +1579,7 @@ dict_index_copy(
/*============*/
dict_index_t* index1, /* in: index to copy to */
dict_index_t* index2, /* in: index to copy from */
+ dict_table_t* table, /* in: table */
ulint start, /* in: first position to copy */
ulint end) /* in: last position to copy */
{
@@ -1709,7 +1591,8 @@ dict_index_copy(
for (i = start; i < end; i++) {
field = dict_index_get_nth_field(index2, i);
- dict_index_add_col(index1, field->col, field->prefix_len);
+ dict_index_add_col(index1, table, field->col,
+ field->prefix_len);
}
}
@@ -1723,8 +1606,6 @@ dict_index_copy_types(
dict_index_t* index, /* in: index */
ulint n_fields) /* in: number of field types to copy */
{
- dtype_t* dfield_type;
- dtype_t* type;
ulint i;
if (UNIV_UNLIKELY(index->type & DICT_UNIVERSAL)) {
@@ -1734,10 +1615,15 @@ dict_index_copy_types(
}
for (i = 0; i < n_fields; i++) {
+ dict_field_t* ifield;
+ dtype_t* dfield_type;
+
+ ifield = dict_index_get_nth_field(index, i);
dfield_type = dfield_get_type(dtuple_get_nth_field(tuple, i));
- type = dict_col_get_type(dict_field_get_col
- (dict_index_get_nth_field(index, i)));
- *dfield_type = *type;
+ dict_col_copy_type(dict_field_get_col(ifield), dfield_type);
+ if (UNIV_UNLIKELY(ifield->prefix_len)) {
+ dfield_type->len = ifield->prefix_len;
+ }
}
}
@@ -1751,15 +1637,13 @@ dict_table_copy_types(
dict_table_t* table) /* in: index */
{
dtype_t* dfield_type;
- dtype_t* type;
ulint i;
for (i = 0; i < dtuple_get_n_fields(tuple); i++) {
dfield_type = dfield_get_type(dtuple_get_nth_field(tuple, i));
- type = dict_col_get_type(dict_table_get_nth_col(table, i));
-
- *dfield_type = *type;
+ dict_col_copy_type(dict_table_get_nth_col(table, i),
+ dfield_type);
}
}
@@ -1778,7 +1662,6 @@ dict_index_build_internal_clust(
{
dict_index_t* new_index;
dict_field_t* field;
- dict_col_t* col;
ulint fixed_size;
ulint trx_id_pos;
ulint i;
@@ -1805,12 +1688,12 @@ dict_index_build_internal_clust(
new_index->id = index->id;
/* Copy the fields of index */
- dict_index_copy(new_index, index, 0, index->n_fields);
+ dict_index_copy(new_index, index, table, 0, index->n_fields);
if (UNIV_UNLIKELY(index->type & DICT_UNIVERSAL)) {
/* No fixed number of fields determines an entry uniquely */
- new_index->n_uniq = ULINT_MAX;
+ new_index->n_uniq = REC_MAX_N_FIELDS;
} else if (index->type & DICT_UNIQUE) {
/* Only the fields defined so far are needed to identify
@@ -1840,24 +1723,26 @@ dict_index_build_internal_clust(
#endif
if (!(index->type & DICT_UNIQUE)) {
- dict_index_add_col(new_index,
- dict_table_get_sys_col
- (table, DATA_ROW_ID), 0);
+ dict_index_add_col(new_index, table, (dict_col_t*)
+ dict_table_get_sys_col(
+ table, DATA_ROW_ID),
+ 0);
trx_id_pos++;
}
- dict_index_add_col(new_index,
- dict_table_get_sys_col
- (table, DATA_TRX_ID), 0);
+ dict_index_add_col(new_index, table, (dict_col_t*)
+ dict_table_get_sys_col(table, DATA_TRX_ID),
+ 0);
- dict_index_add_col(new_index,
- dict_table_get_sys_col
- (table, DATA_ROLL_PTR), 0);
+ dict_index_add_col(new_index, table, (dict_col_t*)
+ dict_table_get_sys_col(table,
+ DATA_ROLL_PTR),
+ 0);
for (i = 0; i < trx_id_pos; i++) {
- fixed_size = dtype_get_fixed_size
- (dict_index_get_nth_type(new_index, i));
+ fixed_size = dict_col_get_fixed_size(
+ dict_index_get_nth_col(new_index, i));
if (fixed_size == 0) {
new_index->trx_id_offset = 0;
@@ -1897,13 +1782,14 @@ dict_index_build_internal_clust(
/* Add to new_index non-system columns of table not yet included
there */
- for (i = 0; i < table->n_cols - DATA_N_SYS_COLS; i++) {
+ for (i = 0; i + DATA_N_SYS_COLS < (ulint) table->n_cols; i++) {
- col = dict_table_get_nth_col(table, i);
- ut_ad(col->type.mtype != DATA_SYS);
+ dict_col_t* col = (dict_col_t*)
+ dict_table_get_nth_col(table, i);
+ ut_ad(col->mtype != DATA_SYS);
if (!indexed[col->ind]) {
- dict_index_add_col(new_index, col, 0);
+ dict_index_add_col(new_index, table, col, 0);
}
}
@@ -1912,18 +1798,6 @@ dict_index_build_internal_clust(
ut_ad((index->type & DICT_IBUF)
|| (UT_LIST_GET_LEN(table->indexes) == 0));
- /* Store to the column structs the position of the table columns
- in the clustered index */
-
- for (i = 0; i < new_index->n_def; i++) {
- field = dict_index_get_nth_field(new_index, i);
-
- if (field->prefix_len == 0) {
-
- field->col->clust_pos = i;
- }
- }
-
new_index->cached = TRUE;
return(new_index);
@@ -1963,9 +1837,9 @@ dict_index_build_internal_non_clust(
ut_ad(!(clust_index->type & DICT_UNIVERSAL));
/* Create a new index */
- new_index = dict_mem_index_create
- (table->name, index->name, index->space, index->type,
- index->n_fields + 1 + clust_index->n_uniq);
+ new_index = dict_mem_index_create(
+ table->name, index->name, index->space, index->type,
+ index->n_fields + 1 + clust_index->n_uniq);
/* Copy other relevant data from the old index
struct to the new struct: it inherits the values */
@@ -1975,7 +1849,7 @@ dict_index_build_internal_non_clust(
new_index->id = index->id;
/* Copy fields from index to new_index */
- dict_index_copy(new_index, index, 0, index->n_fields);
+ dict_index_copy(new_index, index, table, 0, index->n_fields);
/* Remember the table columns already contained in new_index */
indexed = mem_alloc(table->n_cols * sizeof *indexed);
@@ -2003,7 +1877,7 @@ dict_index_build_internal_non_clust(
field = dict_index_get_nth_field(clust_index, i);
if (!indexed[field->col->ind]) {
- dict_index_add_col(new_index, field->col,
+ dict_index_add_col(new_index, table, field->col,
field->prefix_len);
}
}
@@ -2146,6 +2020,7 @@ dict_foreign_find_index(
only has an effect if types_idx != NULL */
{
dict_index_t* index;
+ dict_field_t* field;
const char* col_name;
ulint i;
@@ -2155,10 +2030,12 @@ dict_foreign_find_index(
if (dict_index_get_n_fields(index) >= n_cols) {
for (i = 0; i < n_cols; i++) {
- col_name = dict_index_get_nth_field(index, i)
- ->col->name;
- if (dict_index_get_nth_field(index, i)
- ->prefix_len != 0) {
+ field = dict_index_get_nth_field(index, i);
+
+ col_name = dict_table_get_col_name(
+ table, dict_col_get_no(field->col));
+
+ if (field->prefix_len != 0) {
/* We do not accept column prefix
indexes here */
@@ -2170,10 +2047,11 @@ dict_foreign_find_index(
break;
}
- if (types_idx && !cmp_types_are_equal
- (dict_index_get_nth_type(index, i),
- dict_index_get_nth_type(types_idx, i),
- check_charsets)) {
+ if (types_idx && !cmp_cols_are_equal(
+ dict_index_get_nth_col(index, i),
+ dict_index_get_nth_col(types_idx,
+ i),
+ check_charsets)) {
break;
}
@@ -2260,11 +2138,11 @@ dict_foreign_add_to_cache(
ut_ad(mutex_own(&(dict_sys->mutex)));
#endif /* UNIV_SYNC_DEBUG */
- for_table = dict_table_check_if_in_cache_low
- (foreign->foreign_table_name);
+ for_table = dict_table_check_if_in_cache_low(
+ foreign->foreign_table_name);
- ref_table = dict_table_check_if_in_cache_low
- (foreign->referenced_table_name);
+ ref_table = dict_table_check_if_in_cache_low(
+ foreign->referenced_table_name);
ut_a(for_table || ref_table);
if (for_table) {
@@ -2283,21 +2161,21 @@ dict_foreign_add_to_cache(
}
if (for_in_cache->referenced_table == NULL && ref_table) {
- index = dict_foreign_find_index
- (ref_table,
- (const char**) for_in_cache->referenced_col_names,
- for_in_cache->n_fields,
- for_in_cache->foreign_index, check_charsets);
+ index = dict_foreign_find_index(
+ ref_table,
+ (const char**) for_in_cache->referenced_col_names,
+ for_in_cache->n_fields, for_in_cache->foreign_index,
+ check_charsets);
if (index == NULL) {
- dict_foreign_error_report
- (ef, for_in_cache,
- "there is no index in referenced table"
- " which would contain\n"
- "the columns as the first columns,"
- " or the data types in the\n"
- "referenced table do not match"
- " the ones in table.");
+ dict_foreign_error_report(
+ ef, for_in_cache,
+ "there is no index in referenced table"
+ " which would contain\n"
+ "the columns as the first columns,"
+ " or the data types in the\n"
+ "referenced table do not match"
+ " the ones in table.");
if (for_in_cache == foreign) {
mem_heap_free(foreign->heap);
@@ -2315,28 +2193,28 @@ dict_foreign_add_to_cache(
}
if (for_in_cache->foreign_table == NULL && for_table) {
- index = dict_foreign_find_index
- (for_table,
- (const char**) for_in_cache->foreign_col_names,
- for_in_cache->n_fields,
- for_in_cache->referenced_index, check_charsets);
+ index = dict_foreign_find_index(
+ for_table,
+ (const char**) for_in_cache->foreign_col_names,
+ for_in_cache->n_fields,
+ for_in_cache->referenced_index, check_charsets);
if (index == NULL) {
- dict_foreign_error_report
- (ef, for_in_cache,
- "there is no index in the table"
- " which would contain\n"
- "the columns as the first columns,"
- " or the data types in the\n"
- "table do not match"
- " the ones in the referenced table.");
+ dict_foreign_error_report(
+ ef, for_in_cache,
+ "there is no index in the table"
+ " which would contain\n"
+ "the columns as the first columns,"
+ " or the data types in the\n"
+ "table do not match"
+ " the ones in the referenced table.");
if (for_in_cache == foreign) {
if (added_to_referenced_list) {
- UT_LIST_REMOVE
- (referenced_list,
- ref_table->referenced_list,
- for_in_cache);
+ UT_LIST_REMOVE(
+ referenced_list,
+ ref_table->referenced_list,
+ for_in_cache);
}
mem_heap_free(foreign->heap);
@@ -2560,17 +2438,16 @@ static
const char*
dict_scan_col(
/*==========*/
- /* out: scanned to */
- struct charset_info_st* cs,/* in: the character set of ptr */
- const char* ptr, /* in: scanned to */
- ibool* success,/* out: TRUE if success */
- dict_table_t* table, /* in: table in which the column is */
- dict_col_t** column, /* out: pointer to column if success */
- mem_heap_t* heap, /* in: heap where to allocate the name */
- const char** name) /* out,own: the column name; NULL if no name
- was scannable */
+ /* out: scanned to */
+ struct charset_info_st* cs, /* in: the character set of ptr */
+ const char* ptr, /* in: scanned to */
+ ibool* success,/* out: TRUE if success */
+ dict_table_t* table, /* in: table in which the column is */
+ const dict_col_t** column, /* out: pointer to column if success */
+ mem_heap_t* heap, /* in: heap where to allocate */
+ const char** name) /* out,own: the column name;
+ NULL if no name was scannable */
{
- dict_col_t* col;
ulint i;
*success = FALSE;
@@ -2588,14 +2465,15 @@ dict_scan_col(
} else {
for (i = 0; i < dict_table_get_n_cols(table); i++) {
- col = dict_table_get_nth_col(table, i);
+ const char* col_name = dict_table_get_col_name(
+ table, i);
- if (0 == innobase_strcasecmp(col->name, *name)) {
+ if (0 == innobase_strcasecmp(col_name, *name)) {
/* Found */
*success = TRUE;
- *column = col;
- strcpy((char*) *name, col->name);
+ *column = dict_table_get_nth_col(table, i);
+ strcpy((char*) *name, col_name);
break;
}
@@ -2933,7 +2811,7 @@ dict_create_foreign_constraints_low(
ibool is_on_delete;
ulint n_on_deletes;
ulint n_on_updates;
- dict_col_t* columns[500];
+ const dict_col_t*columns[500];
const char* column_names[500];
const char* referenced_table_name;
@@ -2997,8 +2875,8 @@ dict_create_foreign_constraints_low(
if (table_to_alter == NULL) {
highest_id_so_far = 0;
} else {
- highest_id_so_far = dict_table_get_highest_foreign_id
- (table_to_alter);
+ highest_id_so_far = dict_table_get_highest_foreign_id(
+ table_to_alter);
}
/* Scan for foreign key declarations in a loop */
@@ -3054,8 +2932,8 @@ loop:
/* The following call adds the foreign key constraints
to the data dictionary system tables on disk */
- error = dict_create_add_foreigns_to_dictionary
- (highest_id_so_far, table, trx);
+ error = dict_create_add_foreigns_to_dictionary(
+ highest_id_so_far, table, trx);
return(error);
}
@@ -3085,8 +2963,8 @@ loop:
ptr = dict_skip_word(cs, ptr, &success);
if (!success) {
- dict_foreign_report_syntax_err
- (name, start_of_latest_foreign, ptr);
+ dict_foreign_report_syntax_err(
+ name, start_of_latest_foreign, ptr);
return(DB_CANNOT_ADD_CONSTRAINT);
}
@@ -3129,8 +3007,8 @@ col_loop1:
ptr = dict_accept(cs, ptr, ")", &success);
if (!success) {
- dict_foreign_report_syntax_err
- (name, start_of_latest_foreign, ptr);
+ dict_foreign_report_syntax_err(
+ name, start_of_latest_foreign, ptr);
return(DB_CANNOT_ADD_CONSTRAINT);
}
@@ -3157,8 +3035,8 @@ col_loop1:
ptr = dict_accept(cs, ptr, "REFERENCES", &success);
if (!success || !my_isspace(cs, *ptr)) {
- dict_foreign_report_syntax_err
- (name, start_of_latest_foreign, ptr);
+ dict_foreign_report_syntax_err(
+ name, start_of_latest_foreign, ptr);
return(DB_CANNOT_ADD_CONSTRAINT);
}
@@ -3176,8 +3054,8 @@ col_loop1:
db_len = dict_get_db_name_len(table->name);
- foreign->id = mem_heap_alloc
- (foreign->heap, db_len + strlen(constraint_name) + 2);
+ foreign->id = mem_heap_alloc(
+ foreign->heap, db_len + strlen(constraint_name) + 2);
ut_memcpy(foreign->id, table->name, db_len);
foreign->id[db_len] = '/';
@@ -3192,8 +3070,10 @@ col_loop1:
foreign->foreign_col_names = mem_heap_alloc(foreign->heap,
i * sizeof(void*));
for (i = 0; i < foreign->n_fields; i++) {
- foreign->foreign_col_names[i] = mem_heap_strdup
- (foreign->heap, columns[i]->name);
+ foreign->foreign_col_names[i] = mem_heap_strdup(
+ foreign->heap,
+ dict_table_get_col_name(table,
+ dict_col_get_no(columns[i])));
}
ptr = dict_scan_table_name(cs, ptr, &referenced_table, name,
@@ -3282,8 +3162,8 @@ scan_on_conditions:
if (!success) {
dict_foreign_free(foreign);
- dict_foreign_report_syntax_err
- (name, start_of_latest_foreign, ptr);
+ dict_foreign_report_syntax_err(
+ name, start_of_latest_foreign, ptr);
return(DB_CANNOT_ADD_CONSTRAINT);
}
@@ -3319,8 +3199,8 @@ scan_on_conditions:
if (!success) {
dict_foreign_free(foreign);
- dict_foreign_report_syntax_err
- (name, start_of_latest_foreign, ptr);
+ dict_foreign_report_syntax_err(
+ name, start_of_latest_foreign, ptr);
return(DB_CANNOT_ADD_CONSTRAINT);
}
@@ -3353,8 +3233,7 @@ scan_on_conditions:
}
for (j = 0; j < foreign->n_fields; j++) {
- if ((dict_index_get_nth_type
- (foreign->foreign_index, j)->prtype)
+ if ((dict_index_get_nth_col(foreign->foreign_index, j)->prtype)
& DATA_NOT_NULL) {
/* It is not sensible to define SET NULL
@@ -3519,9 +3398,9 @@ dict_create_foreign_constraints(
str = dict_strip_comments(sql_string);
heap = mem_heap_create(10000);
- err = dict_create_foreign_constraints_low
- (trx, heap, innobase_get_charset(trx->mysql_thd),
- str, name, reject_fks);
+ err = dict_create_foreign_constraints_low(
+ trx, heap, innobase_get_charset(trx->mysql_thd), str, name,
+ reject_fks);
mem_heap_free(heap);
mem_free(str);
@@ -3710,68 +3589,18 @@ found:
return(index);
}
-/**************************************************************************
-Creates an index tree struct. */
-
-dict_tree_t*
-dict_tree_create(
-/*=============*/
- /* out, own: created tree */
- dict_index_t* index, /* in: the index for which to create: in the
- case of a mixed tree, this should be the
- index of the cluster object */
- ulint page_no)/* in: root page number of the index */
-{
- dict_tree_t* tree;
-
- tree = mem_alloc(sizeof(dict_tree_t));
-
- /* Inherit info from the index */
-
- tree->type = index->type;
- tree->space = index->space;
- tree->page = page_no;
-
- tree->id = index->id;
-
- tree->tree_index = NULL;
-
- tree->magic_n = DICT_TREE_MAGIC_N;
-
- rw_lock_create(&tree->lock, SYNC_INDEX_TREE);
-
- return(tree);
-}
-
-/**************************************************************************
-Frees an index tree struct. */
-
-void
-dict_tree_free(
-/*===========*/
- dict_tree_t* tree) /* in, own: index tree */
-{
- ut_a(tree);
- ut_ad(tree->magic_n == DICT_TREE_MAGIC_N);
-
- rw_lock_free(&(tree->lock));
- mem_free(tree);
-}
-
#ifdef UNIV_DEBUG
/**************************************************************************
Checks that a tuple has n_fields_cmp value in a sensible range, so that
no comparison can occur with the page number field in a node pointer. */
ibool
-dict_tree_check_search_tuple(
-/*=========================*/
+dict_index_check_search_tuple(
+/*==========================*/
/* out: TRUE if ok */
- dict_tree_t* tree, /* in: index tree */
+ dict_index_t* index, /* in: index tree */
dtuple_t* tuple) /* in: tuple used in a search */
{
- dict_index_t* index = tree->tree_index;
-
ut_a(index);
ut_a(dtuple_get_n_fields_cmp(tuple)
<= dict_index_get_n_unique_in_tree(index));
@@ -3783,10 +3612,10 @@ dict_tree_check_search_tuple(
Builds a node pointer out of a physical record and a page number. */
dtuple_t*
-dict_tree_build_node_ptr(
-/*=====================*/
+dict_index_build_node_ptr(
+/*======================*/
/* out, own: node pointer */
- dict_tree_t* tree, /* in: index tree */
+ dict_index_t* index, /* in: index tree */
rec_t* rec, /* in: record for which to build node
pointer */
ulint page_no,/* in: page number to put in node pointer */
@@ -3795,20 +3624,17 @@ dict_tree_build_node_ptr(
level */
{
dtuple_t* tuple;
- dict_index_t* ind;
dfield_t* field;
byte* buf;
ulint n_unique;
- ind = tree->tree_index;
-
- if (UNIV_UNLIKELY(tree->type & DICT_UNIVERSAL)) {
+ if (UNIV_UNLIKELY(index->type & DICT_UNIVERSAL)) {
/* In a universal index tree, we take the whole record as
- the node pointer if the reord is on the leaf level,
+ the node pointer if the record is on the leaf level,
on non-leaf levels we remove the last field, which
contains the page number of the child page */
- ut_a(!dict_table_is_comp(ind->table));
+ ut_a(!dict_table_is_comp(index->table));
n_unique = rec_get_n_fields_old(rec);
if (level > 0) {
@@ -3816,7 +3642,7 @@ dict_tree_build_node_ptr(
n_unique--;
}
} else {
- n_unique = dict_index_get_n_unique_in_tree(ind);
+ n_unique = dict_index_get_n_unique_in_tree(index);
}
tuple = dtuple_create(heap, n_unique + 1);
@@ -3829,7 +3655,7 @@ dict_tree_build_node_ptr(
dtuple_set_n_fields_cmp(tuple, n_unique);
- dict_index_copy_types(tuple, ind, n_unique);
+ dict_index_copy_types(tuple, index, n_unique);
buf = mem_heap_alloc(heap, 4);
@@ -3838,9 +3664,9 @@ dict_tree_build_node_ptr(
field = dtuple_get_nth_field(tuple, n_unique);
dfield_set_data(field, buf, 4);
- dtype_set(dfield_get_type(field), DATA_SYS_CHILD, DATA_NOT_NULL, 4, 0);
+ dtype_set(dfield_get_type(field), DATA_SYS_CHILD, DATA_NOT_NULL, 4);
- rec_copy_prefix_to_dtuple(tuple, rec, ind, n_unique, heap);
+ rec_copy_prefix_to_dtuple(tuple, rec, index, n_unique, heap);
dtuple_set_info_bits(tuple, dtuple_get_info_bits(tuple)
| REC_STATUS_NODE_PTR);
@@ -3854,23 +3680,21 @@ Copies an initial segment of a physical record, long enough to specify an
index entry uniquely. */
rec_t*
-dict_tree_copy_rec_order_prefix(
-/*============================*/
+dict_index_copy_rec_order_prefix(
+/*=============================*/
/* out: pointer to the prefix record */
- dict_tree_t* tree, /* in: index tree */
+ dict_index_t* index, /* in: index tree */
rec_t* rec, /* in: record for which to copy prefix */
ulint* n_fields,/* out: number of fields copied */
byte** buf, /* in/out: memory buffer for the copied prefix,
or NULL */
ulint* buf_size)/* in/out: buffer size */
{
- dict_index_t* index;
ulint n;
UNIV_PREFETCH_R(rec);
- index = tree->tree_index;
- if (UNIV_UNLIKELY(tree->type & DICT_UNIVERSAL)) {
+ if (UNIV_UNLIKELY(index->type & DICT_UNIVERSAL)) {
ut_a(!dict_table_is_comp(index->table));
n = rec_get_n_fields_old(rec);
} else {
@@ -3885,27 +3709,24 @@ dict_tree_copy_rec_order_prefix(
Builds a typed data tuple out of a physical record. */
dtuple_t*
-dict_tree_build_data_tuple(
-/*=======================*/
+dict_index_build_data_tuple(
+/*========================*/
/* out, own: data tuple */
- dict_tree_t* tree, /* in: index tree */
+ dict_index_t* index, /* in: index tree */
rec_t* rec, /* in: record for which to build data tuple */
ulint n_fields,/* in: number of data fields */
mem_heap_t* heap) /* in: memory heap where tuple created */
{
dtuple_t* tuple;
- dict_index_t* ind;
-
- ind = tree->tree_index;
- ut_ad(dict_table_is_comp(ind->table)
+ ut_ad(dict_table_is_comp(index->table)
|| n_fields <= rec_get_n_fields_old(rec));
tuple = dtuple_create(heap, n_fields);
- dict_index_copy_types(tuple, ind, n_fields);
+ dict_index_copy_types(tuple, index, n_fields);
- rec_copy_prefix_to_dtuple(tuple, rec, ind, n_fields, heap);
+ rec_copy_prefix_to_dtuple(tuple, rec, index, n_fields, heap);
ut_ad(dtuple_check_typed(tuple));
@@ -3927,15 +3748,17 @@ dict_index_calc_min_rec_len(
ulint nullable = 0;
sum = REC_N_NEW_EXTRA_BYTES;
for (i = 0; i < dict_index_get_n_fields(index); i++) {
- dtype_t*t = dict_index_get_nth_type(index, i);
- ulint size = dtype_get_fixed_size(t);
+ const dict_col_t* col
+ = dict_index_get_nth_col(index, i);
+ ulint size = dict_col_get_fixed_size(col);
sum += size;
if (!size) {
- size = dtype_get_len(t);
+ size = col->len;
sum += size < 128 ? 1 : 2;
}
- if (!(dtype_get_prtype(t) & DATA_NOT_NULL))
+ if (!(col->prtype & DATA_NOT_NULL)) {
nullable++;
+ }
}
/* round the NULL flags up to full bytes */
@@ -3945,7 +3768,8 @@ dict_index_calc_min_rec_len(
}
for (i = 0; i < dict_index_get_n_fields(index); i++) {
- sum += dtype_get_fixed_size(dict_index_get_nth_type(index, i));
+ sum += dict_col_get_fixed_size(
+ dict_index_get_nth_col(index, i));
}
if (sum > 127) {
@@ -4030,8 +3854,8 @@ dict_update_statistics_low(
index = dict_table_get_first_index(table);
- table->stat_n_rows = index->stat_n_diff_key_vals
- [dict_index_get_n_unique(index)];
+ table->stat_n_rows = index->stat_n_diff_key_vals[
+ dict_index_get_n_unique(index)];
table->stat_clustered_index_size = index->stat_index_size;
@@ -4162,8 +3986,8 @@ dict_table_print_low(
(ulong) UT_LIST_GET_LEN(table->indexes),
(ulong) table->stat_n_rows);
- for (i = 0; i < table->n_cols - 1; i++) {
- dict_col_print_low(dict_table_get_nth_col(table, i));
+ for (i = 0; i + 1 < (ulint) table->n_cols; i++) {
+ dict_col_print_low(table, dict_table_get_nth_col(table, i));
fputs("; ", stderr);
}
@@ -4197,18 +4021,20 @@ static
void
dict_col_print_low(
/*===============*/
- dict_col_t* col) /* in: column */
+ const dict_table_t* table, /* in: table */
+ const dict_col_t* col) /* in: column */
{
- dtype_t* type;
+ dtype_t type;
#ifdef UNIV_SYNC_DEBUG
ut_ad(mutex_own(&(dict_sys->mutex)));
#endif /* UNIV_SYNC_DEBUG */
- type = dict_col_get_type(col);
- fprintf(stderr, "%s: ", col->name);
+ dict_col_copy_type(col, &type);
+ fprintf(stderr, "%s: ", dict_table_get_col_name(table,
+ dict_col_get_no(col)));
- dtype_print(type);
+ dtype_print(&type);
}
/**************************************************************************
@@ -4219,7 +4045,6 @@ dict_index_print_low(
/*=================*/
dict_index_t* index) /* in: index */
{
- dict_tree_t* tree;
ib_longlong n_vals;
ulint i;
@@ -4227,11 +4052,9 @@ dict_index_print_low(
ut_ad(mutex_own(&(dict_sys->mutex)));
#endif /* UNIV_SYNC_DEBUG */
- tree = index->tree;
-
if (index->n_user_defined_cols > 0) {
- n_vals = index->stat_n_diff_key_vals
- [index->n_user_defined_cols];
+ n_vals = index->stat_n_diff_key_vals[
+ index->n_user_defined_cols];
} else {
n_vals = index->stat_n_diff_key_vals[1];
}
@@ -4243,13 +4066,13 @@ dict_index_print_low(
" leaf pages %lu, size pages %lu\n"
" FIELDS: ",
index->name,
- (ulong) ut_dulint_get_high(tree->id),
- (ulong) ut_dulint_get_low(tree->id),
+ (ulong) ut_dulint_get_high(index->id),
+ (ulong) ut_dulint_get_low(index->id),
(ulong) index->n_user_defined_cols,
(ulong) index->n_fields,
(ulong) index->n_uniq,
(ulong) index->type,
- (ulong) tree->page,
+ (ulong) index->page,
(ulong) n_vals,
(ulong) index->stat_n_leaf_pages,
(ulong) index->stat_index_size);
@@ -4261,9 +4084,9 @@ dict_index_print_low(
putc('\n', stderr);
#ifdef UNIV_BTR_PRINT
- btr_print_size(tree);
+ btr_print_size(index);
- btr_print_tree(tree, 7);
+ btr_print_index(index, 7);
#endif /* UNIV_BTR_PRINT */
}
@@ -4335,8 +4158,9 @@ dict_print_info_on_foreign_key_in_create_format(
if (dict_tables_have_same_db(foreign->foreign_table_name,
foreign->referenced_table_name)) {
/* Do not print the database name of the referenced table */
- ut_print_name(file, trx, TRUE, dict_remove_db_name
- (foreign->referenced_table_name));
+ ut_print_name(file, trx, TRUE,
+ dict_remove_db_name(
+ foreign->referenced_table_name));
} else {
/* Look for the '/' in the table name */
@@ -4420,8 +4244,8 @@ dict_print_info_on_foreign_keys(
while (foreign != NULL) {
if (create_table_format) {
- dict_print_info_on_foreign_key_in_create_format
- (file, trx, foreign, TRUE);
+ dict_print_info_on_foreign_key_in_create_format(
+ file, trx, foreign, TRUE);
} else {
ulint i;
fputs("; (", file);
@@ -4444,9 +4268,9 @@ dict_print_info_on_foreign_keys(
if (i) {
putc(' ', file);
}
- ut_print_name(file, trx, FALSE,
- foreign->referenced_col_names
- [i]);
+ ut_print_name(
+ file, trx, FALSE,
+ foreign->referenced_col_names[i]);
}
putc(')', file);
diff --git a/storage/innobase/dict/dict0load.c b/storage/innobase/dict/dict0load.c
index bc393140a6f..518e32ec4dc 100644
--- a/storage/innobase/dict/dict0load.c
+++ b/storage/innobase/dict/dict0load.c
@@ -26,6 +26,25 @@ Created 4/24/1996 Heikki Tuuri
#include "srv0start.h"
#include "srv0srv.h"
+/********************************************************************
+Returns TRUE if index's i'th column's name is 'name' .*/
+static
+ibool
+name_of_col_is(
+/*===========*/
+ /* out: */
+ dict_table_t* table, /* in: table */
+ dict_index_t* index, /* in: index */
+ ulint i, /* in: */
+ const char* name) /* in: name to compare to */
+{
+ ulint tmp = dict_col_get_no(dict_field_get_col(
+ dict_index_get_nth_field(
+ index, i)));
+
+ return(strcmp(name, dict_table_get_col_name(table, tmp)) == 0);
+}
+
/************************************************************************
Finds the first table name in the given database. */
@@ -331,7 +350,6 @@ dict_load_columns(
ulint mtype;
ulint prtype;
ulint col_len;
- ulint prec;
ulint i;
mtr_t mtr;
@@ -356,7 +374,7 @@ dict_load_columns(
btr_pcur_open_on_user_rec(sys_index, tuple, PAGE_CUR_GE,
BTR_SEARCH_LEAF, &pcur, &mtr);
- for (i = 0; i < table->n_cols - DATA_N_SYS_COLS; i++) {
+ for (i = 0; i + DATA_N_SYS_COLS < (ulint) table->n_cols; i++) {
rec = btr_pcur_get_rec(&pcur);
@@ -372,8 +390,7 @@ dict_load_columns(
ut_ad(len == 4);
ut_a(i == mach_read_from_4(field));
- ut_a(!strcmp("NAME", dict_field_get_col
- (dict_index_get_nth_field(sys_index, 4))->name));
+ ut_a(name_of_col_is(sys_columns, sys_index, 4, "NAME"));
field = rec_get_nth_field_old(rec, 4, &len);
name = mem_heap_strdupl(heap, (char*) field, len);
@@ -392,30 +409,25 @@ dict_load_columns(
/* Use the binary collation for
string columns of binary type. */
- prtype = dtype_form_prtype
- (prtype,
- DATA_MYSQL_BINARY_CHARSET_COLL);
+ prtype = dtype_form_prtype(
+ prtype,
+ DATA_MYSQL_BINARY_CHARSET_COLL);
} else {
/* Use the default charset for
other than binary columns. */
- prtype = dtype_form_prtype
- (prtype,
- data_mysql_default_charset_coll);
+ prtype = dtype_form_prtype(
+ prtype,
+ data_mysql_default_charset_coll);
}
}
field = rec_get_nth_field_old(rec, 7, &len);
col_len = mach_read_from_4(field);
- ut_a(!strcmp("PREC", dict_field_get_col
- (dict_index_get_nth_field(sys_index, 8))->name));
-
- field = rec_get_nth_field_old(rec, 8, &len);
- prec = mach_read_from_4(field);
+ ut_a(name_of_col_is(sys_columns, sys_index, 8, "PREC"));
- dict_mem_table_add_col(table, name, mtype, prtype, col_len,
- prec);
+ dict_mem_table_add_col(table, name, mtype, prtype, col_len);
btr_pcur_move_to_next_user_rec(&pcur, &mtr);
}
@@ -526,13 +538,13 @@ dict_load_fields(
prefix_len = 0;
}
- ut_a(!strcmp("COL_NAME", dict_field_get_col
- (dict_index_get_nth_field(sys_index, 4))->name));
+ ut_a(name_of_col_is(sys_fields, sys_index, 4, "COL_NAME"));
field = rec_get_nth_field_old(rec, 4, &len);
- dict_mem_index_add_field(index, mem_heap_strdupl
- (heap, (char*) field, len),
+ dict_mem_index_add_field(index,
+ mem_heap_strdupl(heap,
+ (char*) field, len),
prefix_len);
btr_pcur_move_to_next_user_rec(&pcur, &mtr);
@@ -631,8 +643,7 @@ dict_load_indexes(
ut_ad(len == 8);
id = mach_read_from_8(field);
- ut_a(!strcmp("NAME", dict_field_get_col
- (dict_index_get_nth_field(sys_index, 4))->name));
+ ut_a(name_of_col_is(sys_indexes, sys_index, 4, "NAME"));
field = rec_get_nth_field_old(rec, 4, &name_len);
name_buf = mem_heap_strdupl(heap, (char*) field, name_len);
@@ -646,8 +657,7 @@ dict_load_indexes(
field = rec_get_nth_field_old(rec, 7, &len);
space = mach_read_from_4(field);
- ut_a(!strcmp("PAGE_NO", dict_field_get_col
- (dict_index_get_nth_field(sys_index, 8))->name));
+ ut_a(name_of_col_is(sys_indexes, sys_index, 8, "PAGE_NO"));
field = rec_get_nth_field_old(rec, 8, &len);
page_no = mach_read_from_4(field);
@@ -785,8 +795,7 @@ err_exit:
goto err_exit;
}
- ut_a(!strcmp("SPACE", dict_field_get_col
- (dict_index_get_nth_field(sys_index, 9))->name));
+ ut_a(name_of_col_is(sys_tables, sys_index, 9, "SPACE"));
field = rec_get_nth_field_old(rec, 9, &len);
space = mach_read_from_4(field);
@@ -819,8 +828,7 @@ err_exit:
}
}
- ut_a(!strcmp("N_COLS", dict_field_get_col
- (dict_index_get_nth_field(sys_index, 4))->name));
+ ut_a(name_of_col_is(sys_tables, sys_index, 4, "N_COLS"));
field = rec_get_nth_field_old(rec, 4, &len);
n_cols = mach_read_from_4(field);
@@ -837,8 +845,7 @@ err_exit:
table->ibd_file_missing = ibd_file_missing;
- ut_a(!strcmp("ID", dict_field_get_col
- (dict_index_get_nth_field(sys_index, 3))->name));
+ ut_a(name_of_col_is(sys_tables, sys_index, 3, "ID"));
field = rec_get_nth_field_old(rec, 3, &len);
table->id = mach_read_from_8(field);
@@ -925,8 +932,8 @@ dict_load_table_on_id(
/*---------------------------------------------------*/
/* Get the secondary index based on ID for table SYS_TABLES */
sys_tables = dict_sys->sys_tables;
- sys_table_ids = dict_table_get_next_index
- (dict_table_get_first_index(sys_tables));
+ sys_table_ids = dict_table_get_next_index(
+ dict_table_get_first_index(sys_tables));
ut_a(!dict_table_is_comp(sys_tables));
heap = mem_heap_create(256);
@@ -1032,11 +1039,11 @@ dict_load_foreign_cols(
ut_ad(mutex_own(&(dict_sys->mutex)));
#endif /* UNIV_SYNC_DEBUG */
- foreign->foreign_col_names = mem_heap_alloc
- (foreign->heap, foreign->n_fields * sizeof(void*));
+ foreign->foreign_col_names = mem_heap_alloc(
+ foreign->heap, foreign->n_fields * sizeof(void*));
- foreign->referenced_col_names = mem_heap_alloc
- (foreign->heap, foreign->n_fields * sizeof(void*));
+ foreign->referenced_col_names = mem_heap_alloc(
+ foreign->heap, foreign->n_fields * sizeof(void*));
mtr_start(&mtr);
sys_foreign_cols = dict_table_get_low("SYS_FOREIGN_COLS");
@@ -1067,12 +1074,12 @@ dict_load_foreign_cols(
ut_a(i == mach_read_from_4(field));
field = rec_get_nth_field_old(rec, 4, &len);
- foreign->foreign_col_names[i] = mem_heap_strdupl
- (foreign->heap, (char*) field, len);
+ foreign->foreign_col_names[i] = mem_heap_strdupl(
+ foreign->heap, (char*) field, len);
field = rec_get_nth_field_old(rec, 5, &len);
- foreign->referenced_col_names[i] = mem_heap_strdupl
- (foreign->heap, (char*) field, len);
+ foreign->referenced_col_names[i] = mem_heap_strdupl(
+ foreign->heap, (char*) field, len);
btr_pcur_move_to_next_user_rec(&pcur, &mtr);
}
@@ -1165,8 +1172,8 @@ dict_load_foreign(
foreign = dict_mem_foreign_create();
- foreign->n_fields = mach_read_from_4
- (rec_get_nth_field_old(rec, 5, &len));
+ foreign->n_fields = mach_read_from_4(
+ rec_get_nth_field_old(rec, 5, &len));
ut_a(len == 4);
@@ -1178,12 +1185,12 @@ dict_load_foreign(
foreign->id = mem_heap_strdup(foreign->heap, id);
field = rec_get_nth_field_old(rec, 3, &len);
- foreign->foreign_table_name = mem_heap_strdupl
- (foreign->heap, (char*) field, len);
+ foreign->foreign_table_name = mem_heap_strdupl(
+ foreign->heap, (char*) field, len);
field = rec_get_nth_field_old(rec, 4, &len);
- foreign->referenced_table_name = mem_heap_strdupl
- (foreign->heap, (char*) field, len);
+ foreign->referenced_table_name = mem_heap_strdupl(
+ foreign->heap, (char*) field, len);
btr_pcur_close(&pcur);
mtr_commit(&mtr);
@@ -1257,8 +1264,8 @@ dict_load_foreigns(
/* Get the secondary index based on FOR_NAME from table
SYS_FOREIGN */
- sec_index = dict_table_get_next_index
- (dict_table_get_first_index(sys_foreign));
+ sec_index = dict_table_get_next_index(
+ dict_table_get_first_index(sys_foreign));
start_load:
heap = mem_heap_create(256);
@@ -1289,7 +1296,8 @@ loop:
following call does the comparison in the latin1_swedish_ci
charset-collation, in a case-insensitive way. */
- if (0 != cmp_data_data(dfield_get_type(dfield),
+ if (0 != cmp_data_data(dfield_get_type(dfield)->mtype,
+ dfield_get_type(dfield)->prtype,
dfield_get_data(dfield), dfield_get_len(dfield),
field, len)) {
diff --git a/storage/innobase/dict/dict0mem.c b/storage/innobase/dict/dict0mem.c
index a6a42dd0411..cee0ffec20b 100644
--- a/storage/innobase/dict/dict0mem.c
+++ b/storage/innobase/dict/dict0mem.c
@@ -66,6 +66,7 @@ dict_mem_table_create(
table->cols = mem_heap_alloc(heap, (n_cols + DATA_N_SYS_COLS)
* sizeof(dict_col_t));
+ table->col_names = NULL;
UT_LIST_INIT(table->indexes);
table->auto_inc_lock = mem_heap_alloc(heap, lock_get_size());
@@ -76,20 +77,22 @@ dict_mem_table_create(
UT_LIST_INIT(table->foreign_list);
UT_LIST_INIT(table->referenced_list);
+#ifdef UNIV_DEBUG
table->does_not_fit_in_memory = FALSE;
+#endif /* UNIV_DEBUG */
table->stat_initialized = FALSE;
table->stat_modified_counter = 0;
- table->max_row_size = 0;
+ table->big_rows = 0;
mutex_create(&table->autoinc_mutex, SYNC_DICT_AUTOINC_MUTEX);
table->autoinc_inited = FALSE;
-
+#ifdef UNIV_DEBUG
table->magic_n = DICT_TABLE_MAGIC_N;
-
+#endif /* UNIV_DEBUG */
return(table);
}
@@ -105,9 +108,74 @@ dict_mem_table_free(
ut_ad(table->magic_n == DICT_TABLE_MAGIC_N);
mutex_free(&(table->autoinc_mutex));
+
+ if (table->col_names && (table->n_def < table->n_cols)) {
+ ut_free((void*)table->col_names);
+ }
+
mem_heap_free(table->heap);
}
+/********************************************************************
+Add 'name' to end of the col_names array (see dict_table_t::col_names). Call
+ut_free on col_names (if not NULL), allocate new array (if heap, from it,
+otherwise with ut_malloc), and copy col_names + name to it. */
+static
+const char*
+dict_add_col_name(
+/*==============*/
+ /* out: new column names array */
+ const char* col_names, /* in: existing column names, or
+ NULL */
+ ulint cols, /* in: number of existing columns */
+ const char* name, /* in: new column name */
+ mem_heap_t* heap) /* in: heap, or NULL */
+{
+ ulint i;
+ ulint old_len;
+ ulint new_len;
+ ulint total_len;
+ const char* s;
+ char* res;
+
+ ut_a(((cols == 0) && !col_names) || ((cols > 0) && col_names));
+ ut_a(*name);
+
+ /* Find out length of existing array. */
+ if (col_names) {
+ s = col_names;
+
+ for (i = 0; i < cols; i++) {
+ s += strlen(s) + 1;
+ }
+
+ old_len = s - col_names;
+ } else {
+ old_len = 0;
+ }
+
+ new_len = strlen(name) + 1;
+ total_len = old_len + new_len;
+
+ if (heap) {
+ res = mem_heap_alloc(heap, total_len);
+ } else {
+ res = ut_malloc(total_len);
+ }
+
+ if (old_len > 0) {
+ memcpy(res, col_names, old_len);
+ }
+
+ memcpy(res + old_len, name, new_len);
+
+ if (col_names) {
+ ut_free((char*)col_names);
+ }
+
+ return(res);
+}
+
/**************************************************************************
Adds a column definition to a table. */
@@ -118,29 +186,36 @@ dict_mem_table_add_col(
const char* name, /* in: column name */
ulint mtype, /* in: main datatype */
ulint prtype, /* in: precise type */
- ulint len, /* in: length */
- ulint prec) /* in: precision */
+ ulint len) /* in: precision */
{
dict_col_t* col;
- dtype_t* type;
+ ulint mbminlen;
+ ulint mbmaxlen;
+ mem_heap_t* heap;
ut_ad(table && name);
ut_ad(table->magic_n == DICT_TABLE_MAGIC_N);
table->n_def++;
- col = dict_table_get_nth_col(table, table->n_def - 1);
+ heap = table->n_def < table->n_cols ? NULL : table->heap;
+ table->col_names = dict_add_col_name(table->col_names,
+ table->n_def - 1,
+ name, heap);
+
+ col = (dict_col_t*) dict_table_get_nth_col(table, table->n_def - 1);
col->ind = table->n_def - 1;
- col->name = mem_heap_strdup(table->heap, name);
- col->table = table;
col->ord_part = 0;
- col->clust_pos = ULINT_UNDEFINED;
+ col->mtype = mtype;
+ col->prtype = prtype;
+ col->len = len;
- type = dict_col_get_type(col);
+ dtype_get_mblen(mtype, prtype, &mbminlen, &mbmaxlen);
- dtype_set(type, mtype, prtype, len, prec);
+ col->mbminlen = mbminlen;
+ col->mbmaxlen = mbmaxlen;
}
/**************************************************************************
@@ -171,6 +246,7 @@ dict_mem_index_create(
index->type = type;
index->space = space;
+ index->page = 0;
index->name = mem_heap_strdup(heap, index_name);
index->table_name = table_name;
index->table = NULL;
@@ -183,8 +259,10 @@ dict_mem_index_create(
index->stat_n_diff_key_vals = NULL;
index->cached = FALSE;
+ memset(&index->lock, 0, sizeof index->lock);
+#ifdef UNIV_DEBUG
index->magic_n = DICT_INDEX_MAGIC_N;
-
+#endif /* UNIV_DEBUG */
return(index);
}
diff --git a/storage/innobase/eval/eval0eval.c b/storage/innobase/eval/eval0eval.c
index 18408832e91..cbc47ec508f 100644
--- a/storage/innobase/eval/eval0eval.c
+++ b/storage/innobase/eval/eval0eval.c
@@ -334,7 +334,7 @@ eval_predefined_2(
if (len2 > len1) {
int_val = (lint) (len1
- + (eval_rnd % (len2 - len1 + 1)));
+ + (eval_rnd % (len2 - len1 + 1)));
} else {
int_val = (lint) len1;
}
diff --git a/storage/innobase/eval/eval0proc.c b/storage/innobase/eval/eval0proc.c
index 3b3a42d56ef..f5a9d9dc2a8 100644
--- a/storage/innobase/eval/eval0proc.c
+++ b/storage/innobase/eval/eval0proc.c
@@ -51,8 +51,8 @@ if_step(
for (;;) {
eval_exp(elsif_node->cond);
- if (eval_node_get_ibool_val
- (elsif_node->cond)) {
+ if (eval_node_get_ibool_val(
+ elsif_node->cond)) {
/* The condition evaluated to TRUE:
start execution from the first
diff --git a/storage/innobase/fil/fil0fil.c b/storage/innobase/fil/fil0fil.c
index e0a9955f8fb..1aff3739103 100644
--- a/storage/innobase/fil/fil0fil.c
+++ b/storage/innobase/fil/fil0fil.c
@@ -529,9 +529,8 @@ fil_node_open_file(
os_file_read() in Windows to read from a file opened for
async I/O! */
- node->handle = os_file_create_simple_no_error_handling
- (node->name,
- OS_FILE_OPEN, OS_FILE_READ_ONLY, &success);
+ node->handle = os_file_create_simple_no_error_handling(
+ node->name, OS_FILE_OPEN, OS_FILE_READ_ONLY, &success);
if (!success) {
/* The following call prints an error message */
os_file_get_last_error(TRUE);
@@ -1564,9 +1563,9 @@ fil_write_flushed_lsn_to_data_files(
while (node) {
mutex_exit(&(fil_system->mutex));
- err = fil_write_lsn_and_arch_no_to_file
- (space->id, sum_of_sizes,
- lsn, arch_log_no);
+ err = fil_write_lsn_and_arch_no_to_file(
+ space->id, sum_of_sizes, lsn,
+ arch_log_no);
if (err != DB_SUCCESS) {
return(err);
@@ -1936,9 +1935,9 @@ fil_op_log_parse_or_replay(
ut_a(space_id != 0);
- if (fil_create_new_single_table_tablespace
- (&space_id, name, FALSE,
- FIL_IBD_FILE_INITIAL_SIZE) != DB_SUCCESS) {
+ if (fil_create_new_single_table_tablespace(
+ &space_id, name, FALSE,
+ FIL_IBD_FILE_INITIAL_SIZE) != DB_SUCCESS) {
ut_error;
}
}
@@ -2580,8 +2579,8 @@ fil_reset_too_high_lsns(
filepath = fil_make_ibd_name(name, FALSE);
- file = os_file_create_simple_no_error_handling
- (filepath, OS_FILE_OPEN, OS_FILE_READ_WRITE, &success);
+ file = os_file_create_simple_no_error_handling(
+ filepath, OS_FILE_OPEN, OS_FILE_READ_WRITE, &success);
if (!success) {
/* The following call prints an error message */
os_file_get_last_error(TRUE);
@@ -2654,8 +2653,8 @@ fil_reset_too_high_lsns(
if (ut_dulint_cmp(mach_read_from_8(page + FIL_PAGE_LSN),
current_lsn) > 0) {
/* We have to reset the lsn */
- space_id = mach_read_from_4
- (page + FIL_PAGE_ARCH_LOG_NO_OR_SPACE_ID);
+ space_id = mach_read_from_4(
+ page + FIL_PAGE_ARCH_LOG_NO_OR_SPACE_ID);
page_no = mach_read_from_4(page + FIL_PAGE_OFFSET);
buf_flush_init_for_writing(page, current_lsn, space_id,
@@ -2735,8 +2734,8 @@ fil_open_single_table_tablespace(
filepath = fil_make_ibd_name(name, FALSE);
- file = os_file_create_simple_no_error_handling
- (filepath, OS_FILE_OPEN, OS_FILE_READ_ONLY, &success);
+ file = os_file_create_simple_no_error_handling(
+ filepath, OS_FILE_OPEN, OS_FILE_READ_ONLY, &success);
if (!success) {
/* The following call prints an error message */
os_file_get_last_error(TRUE);
@@ -2887,8 +2886,8 @@ fil_load_single_table_tablespace(
dict_casedn_str(filepath);
# endif /* !UNIV_HOTBACKUP */
#endif
- file = os_file_create_simple_no_error_handling
- (filepath, OS_FILE_OPEN, OS_FILE_READ_ONLY, &success);
+ file = os_file_create_simple_no_error_handling(
+ filepath, OS_FILE_OPEN, OS_FILE_READ_ONLY, &success);
if (!success) {
/* The following call prints an error message */
os_file_get_last_error(TRUE);
@@ -3242,8 +3241,8 @@ fil_load_single_table_tablespaces(void)
".ibd")) {
/* The name ends in .ibd; try opening
the file */
- fil_load_single_table_tablespace
- (dbinfo.name, fileinfo.name);
+ fil_load_single_table_tablespace(
+ dbinfo.name, fileinfo.name);
}
next_file_item:
ret = fil_file_readdir_next_file(&err,
@@ -3736,8 +3735,8 @@ fil_extend_tablespaces_to_stored_len(void)
size_in_header = fsp_get_size_low(buf);
- success = fil_extend_space_to_desired_size
- (&actual_size, space->id, size_in_header);
+ success = fil_extend_space_to_desired_size(
+ &actual_size, space->id, size_in_header);
if (!success) {
fprintf(stderr,
"InnoDB: Error: could not extend the"
@@ -4082,9 +4081,9 @@ fil_io(
for (;;) {
if (node == NULL) {
- fil_report_invalid_page_access
- (block_offset, space_id,
- space->name, byte_offset, len, type);
+ fil_report_invalid_page_access(
+ block_offset, space_id, space->name,
+ byte_offset, len, type);
ut_error;
}
@@ -4113,9 +4112,9 @@ fil_io(
if (space->purpose == FIL_TABLESPACE && space->id != 0
&& node->size <= block_offset) {
- fil_report_invalid_page_access
- (block_offset, space_id,
- space->name, byte_offset, len, type);
+ fil_report_invalid_page_access(
+ block_offset, space_id, space->name, byte_offset,
+ len, type);
ut_error;
}
@@ -4384,10 +4383,10 @@ skip_flush:
space->is_in_unflushed_spaces = FALSE;
- UT_LIST_REMOVE
- (unflushed_spaces,
- system->unflushed_spaces,
- space);
+ UT_LIST_REMOVE(
+ unflushed_spaces,
+ system->unflushed_spaces,
+ space);
}
}
diff --git a/storage/innobase/fsp/fsp0fsp.c b/storage/innobase/fsp/fsp0fsp.c
index 4da25f4d479..00c5e582b3e 100644
--- a/storage/innobase/fsp/fsp0fsp.c
+++ b/storage/innobase/fsp/fsp0fsp.c
@@ -768,8 +768,9 @@ xdes_lst_get_next(
space = buf_frame_get_space_id(descr);
- return(xdes_lst_get_descriptor
- (space, flst_get_next_addr(descr + XDES_FLST_NODE, mtr), mtr));
+ return(xdes_lst_get_descriptor(
+ space,
+ flst_get_next_addr(descr + XDES_FLST_NODE, mtr), mtr));
}
/************************************************************************
@@ -1116,8 +1117,8 @@ fsp_try_extend_data_file(
fprintf(stderr,
"InnoDB: Error: Last data file size is %lu,"
" max size allowed %lu\n",
- (ulong) srv_data_file_sizes
- [srv_n_data_files - 1],
+ (ulong) srv_data_file_sizes[
+ srv_n_data_files - 1],
(ulong) srv_last_file_size_max);
}
@@ -1137,13 +1138,13 @@ fsp_try_extend_data_file(
if (size < FSP_EXTENT_SIZE) {
/* Let us first extend the file to 64 pages */
- success = fsp_try_extend_data_file_with_pages
- (space, FSP_EXTENT_SIZE - 1,
- header, mtr);
+ success = fsp_try_extend_data_file_with_pages(
+ space, FSP_EXTENT_SIZE - 1,
+ header, mtr);
if (!success) {
- new_size = mtr_read_ulint
- (header + FSP_SIZE,
- MLOG_4BYTES, mtr);
+ new_size = mtr_read_ulint(
+ header + FSP_SIZE,
+ MLOG_4BYTES, mtr);
*actual_increase = new_size - old_size;
@@ -1246,9 +1247,9 @@ fsp_fill_free_list(
/* Update the free limit info in the log system and make
a checkpoint */
if (space == 0) {
- log_fsp_current_free_limit_set_and_checkpoint
- ((i + FSP_EXTENT_SIZE)
- / ((1024 * 1024) / UNIV_PAGE_SIZE));
+ log_fsp_current_free_limit_set_and_checkpoint(
+ (i + FSP_EXTENT_SIZE)
+ / ((1024 * 1024) / UNIV_PAGE_SIZE));
}
if (0 == i % XDES_DESCRIBED_PER_PAGE) {
@@ -1967,8 +1968,8 @@ fseg_find_last_used_frag_page_slot(
ut_ad(inode && mtr);
for (i = 0; i < FSEG_FRAG_ARR_N_SLOTS; i++) {
- page_no = fseg_get_nth_frag_page_no
- (inode, FSEG_FRAG_ARR_N_SLOTS - i - 1, mtr);
+ page_no = fseg_get_nth_frag_page_no(
+ inode, FSEG_FRAG_ARR_N_SLOTS - i - 1, mtr);
if (page_no != FIL_NULL) {
@@ -2526,8 +2527,8 @@ fseg_alloc_free_page_low(
return(FIL_NULL);
}
- success = fsp_try_extend_data_file_with_pages
- (space, ret_page, space_header, mtr);
+ success = fsp_try_extend_data_file_with_pages(
+ space, ret_page, space_header, mtr);
if (!success) {
/* No disk space left */
return(FIL_NULL);
@@ -3161,8 +3162,8 @@ fseg_free_extent(
/* Drop search system page hash index if the page is
found in the pool and is hashed */
- btr_search_drop_page_hash_when_freed
- (space, first_page_in_extent + i);
+ btr_search_drop_page_hash_when_freed(
+ space, first_page_in_extent + i);
}
}
@@ -3176,8 +3177,8 @@ fseg_free_extent(
flst_remove(seg_inode + FSEG_NOT_FULL,
descr + XDES_FLST_NODE, mtr);
- not_full_n_used = mtr_read_ulint
- (seg_inode + FSEG_NOT_FULL_N_USED, MLOG_4BYTES, mtr);
+ not_full_n_used = mtr_read_ulint(
+ seg_inode + FSEG_NOT_FULL_N_USED, MLOG_4BYTES, mtr);
descr_n_used = xdes_get_n_used(descr, mtr);
ut_a(not_full_n_used >= descr_n_used);
@@ -3758,15 +3759,15 @@ fsp_validate(
mtr_start(&mtr);
mtr_x_lock(fil_space_get_latch(space), &mtr);
- seg_inode_page = fut_get_ptr
- (space, node_addr, RW_X_LATCH, &mtr)
+ seg_inode_page = fut_get_ptr(
+ space, node_addr, RW_X_LATCH, &mtr)
- FSEG_INODE_PAGE_NODE;
- seg_inode = fsp_seg_inode_page_get_nth_inode
- (seg_inode_page, n, &mtr);
- ut_a(ut_dulint_cmp
- (mach_read_from_8(seg_inode + FSEG_ID),
- ut_dulint_zero) != 0);
+ seg_inode = fsp_seg_inode_page_get_nth_inode(
+ seg_inode_page, n, &mtr);
+ ut_a(ut_dulint_cmp(
+ mach_read_from_8(seg_inode + FSEG_ID),
+ ut_dulint_zero) != 0);
fseg_validate_low(seg_inode, &mtr);
descr_count += flst_get_len(seg_inode + FSEG_FREE,
@@ -3778,8 +3779,8 @@ fsp_validate(
n_used2 += fseg_get_n_frag_pages(seg_inode, &mtr);
- next_node_addr = flst_get_next_addr
- (seg_inode_page + FSEG_INODE_PAGE_NODE, &mtr);
+ next_node_addr = flst_get_next_addr(
+ seg_inode_page + FSEG_INODE_PAGE_NODE, &mtr);
mtr_commit(&mtr);
}
@@ -3804,29 +3805,29 @@ fsp_validate(
mtr_start(&mtr);
mtr_x_lock(fil_space_get_latch(space), &mtr);
- seg_inode_page = fut_get_ptr
- (space, node_addr, RW_X_LATCH, &mtr)
+ seg_inode_page = fut_get_ptr(
+ space, node_addr, RW_X_LATCH, &mtr)
- FSEG_INODE_PAGE_NODE;
- seg_inode = fsp_seg_inode_page_get_nth_inode
- (seg_inode_page, n, &mtr);
- if (ut_dulint_cmp
- (mach_read_from_8(seg_inode + FSEG_ID),
- ut_dulint_zero) != 0) {
+ seg_inode = fsp_seg_inode_page_get_nth_inode(
+ seg_inode_page, n, &mtr);
+ if (ut_dulint_cmp(
+ mach_read_from_8(seg_inode + FSEG_ID),
+ ut_dulint_zero) != 0) {
fseg_validate_low(seg_inode, &mtr);
- descr_count += flst_get_len
- (seg_inode + FSEG_FREE, &mtr);
- descr_count += flst_get_len
- (seg_inode + FSEG_FULL, &mtr);
- descr_count += flst_get_len
- (seg_inode + FSEG_NOT_FULL, &mtr);
- n_used2 += fseg_get_n_frag_pages
- (seg_inode, &mtr);
+ descr_count += flst_get_len(
+ seg_inode + FSEG_FREE, &mtr);
+ descr_count += flst_get_len(
+ seg_inode + FSEG_FULL, &mtr);
+ descr_count += flst_get_len(
+ seg_inode + FSEG_NOT_FULL, &mtr);
+ n_used2 += fseg_get_n_frag_pages(
+ seg_inode, &mtr);
}
- next_node_addr = flst_get_next_addr
- (seg_inode_page + FSEG_INODE_PAGE_NODE, &mtr);
+ next_node_addr = flst_get_next_addr(
+ seg_inode_page + FSEG_INODE_PAGE_NODE, &mtr);
mtr_commit(&mtr);
}
@@ -3931,21 +3932,21 @@ fsp_print(
mtr_start(&mtr);
mtr_x_lock(fil_space_get_latch(space), &mtr);
- seg_inode_page = fut_get_ptr
- (space, node_addr, RW_X_LATCH, &mtr)
+ seg_inode_page = fut_get_ptr(
+ space, node_addr, RW_X_LATCH, &mtr)
- FSEG_INODE_PAGE_NODE;
- seg_inode = fsp_seg_inode_page_get_nth_inode
- (seg_inode_page, n, &mtr);
- ut_a(ut_dulint_cmp
- (mach_read_from_8(seg_inode + FSEG_ID),
- ut_dulint_zero) != 0);
+ seg_inode = fsp_seg_inode_page_get_nth_inode(
+ seg_inode_page, n, &mtr);
+ ut_a(ut_dulint_cmp(
+ mach_read_from_8(seg_inode + FSEG_ID),
+ ut_dulint_zero) != 0);
fseg_print_low(seg_inode, &mtr);
n_segs++;
- next_node_addr = flst_get_next_addr
- (seg_inode_page + FSEG_INODE_PAGE_NODE, &mtr);
+ next_node_addr = flst_get_next_addr(
+ seg_inode_page + FSEG_INODE_PAGE_NODE, &mtr);
mtr_commit(&mtr);
}
@@ -3968,22 +3969,22 @@ fsp_print(
mtr_start(&mtr);
mtr_x_lock(fil_space_get_latch(space), &mtr);
- seg_inode_page = fut_get_ptr
- (space, node_addr, RW_X_LATCH, &mtr)
+ seg_inode_page = fut_get_ptr(
+ space, node_addr, RW_X_LATCH, &mtr)
- FSEG_INODE_PAGE_NODE;
- seg_inode = fsp_seg_inode_page_get_nth_inode
- (seg_inode_page, n, &mtr);
- if (ut_dulint_cmp
- (mach_read_from_8(seg_inode + FSEG_ID),
- ut_dulint_zero) != 0) {
+ seg_inode = fsp_seg_inode_page_get_nth_inode(
+ seg_inode_page, n, &mtr);
+ if (ut_dulint_cmp(
+ mach_read_from_8(seg_inode + FSEG_ID),
+ ut_dulint_zero) != 0) {
fseg_print_low(seg_inode, &mtr);
n_segs++;
}
- next_node_addr = flst_get_next_addr
- (seg_inode_page + FSEG_INODE_PAGE_NODE, &mtr);
+ next_node_addr = flst_get_next_addr(
+ seg_inode_page + FSEG_INODE_PAGE_NODE, &mtr);
mtr_commit(&mtr);
}
diff --git a/storage/innobase/handler/ha_innodb.cc b/storage/innobase/handler/ha_innodb.cc
index 84533d6c814..066c0ce48d4 100644
--- a/storage/innobase/handler/ha_innodb.cc
+++ b/storage/innobase/handler/ha_innodb.cc
@@ -54,6 +54,12 @@ pthread_cond_t commit_cond;
pthread_mutex_t commit_cond_m;
bool innodb_inited= 0;
+/*
+ This needs to exist until the query cache callback is removed
+ or learns to pass hton.
+*/
+static handlerton *legacy_innodb_hton;
+
/*-----------------------------------------------------------------*/
/* These variables are used to implement (semi-)synchronous MySQL binlog
replication for InnoDB tables. */
@@ -197,22 +203,25 @@ static mysql_byte* innobase_get_key(INNOBASE_SHARE *share,uint *length,
my_bool not_used __attribute__((unused)));
static INNOBASE_SHARE *get_share(const char *table_name);
static void free_share(INNOBASE_SHARE *share);
-static int innobase_close_connection(THD* thd);
-static int innobase_commit(THD* thd, bool all);
-static int innobase_rollback(THD* thd, bool all);
-static int innobase_rollback_to_savepoint(THD* thd, void *savepoint);
-static int innobase_savepoint(THD* thd, void *savepoint);
-static int innobase_release_savepoint(THD* thd, void *savepoint);
-static handler *innobase_create_handler(TABLE_SHARE *table,
+static int innobase_close_connection(handlerton *hton, THD* thd);
+static int innobase_commit(handlerton *hton, THD* thd, bool all);
+static int innobase_rollback(handlerton *hton, THD* thd, bool all);
+static int innobase_rollback_to_savepoint(handlerton *hton, THD* thd,
+ void *savepoint);
+static int innobase_savepoint(handlerton *hton, THD* thd, void *savepoint);
+static int innobase_release_savepoint(handlerton *hton, THD* thd,
+ void *savepoint);
+static handler *innobase_create_handler(handlerton *hton,
+ TABLE_SHARE *table,
MEM_ROOT *mem_root);
static const char innobase_hton_name[]= "InnoDB";
-handlerton *innobase_hton;
-
-static handler *innobase_create_handler(TABLE_SHARE *table, MEM_ROOT *mem_root)
+static handler *innobase_create_handler(handlerton *hton,
+ TABLE_SHARE *table,
+ MEM_ROOT *mem_root)
{
- return new (mem_root) ha_innobase(table);
+ return new (mem_root) ha_innobase(hton, table);
}
@@ -380,7 +389,8 @@ documentation, see handler.cc. */
int
innobase_release_temporary_latches(
/*===============================*/
- THD *thd)
+ handlerton *hton,
+ THD *thd)
{
trx_t* trx;
@@ -389,7 +399,7 @@ innobase_release_temporary_latches(
return 0;
}
- trx = (trx_t*) thd->ha_data[innobase_hton->slot];
+ trx = (trx_t*) thd->ha_data[hton->slot];
if (trx) {
innobase_release_stat_resources(trx);
@@ -841,13 +851,14 @@ trx_t*
check_trx_exists(
/*=============*/
/* out: InnoDB transaction handle */
+ handlerton* hton, /* in: handlerton for innodb */
THD* thd) /* in: user thread handle */
{
trx_t* trx;
ut_ad(thd == current_thd);
- trx = (trx_t*) thd->ha_data[innobase_hton->slot];
+ trx = (trx_t*) thd->ha_data[hton->slot];
if (trx == NULL) {
DBUG_ASSERT(thd != NULL);
@@ -861,7 +872,7 @@ check_trx_exists(
CPU time */
trx->support_xa = (ibool)(thd->variables.innodb_support_xa);
- thd->ha_data[innobase_hton->slot] = trx;
+ thd->ha_data[hton->slot] = trx;
} else {
if (trx->magic_n != TRX_MAGIC_N) {
mem_analyze_corruption(trx);
@@ -889,8 +900,8 @@ check_trx_exists(
/*************************************************************************
Construct ha_innobase handler. */
-ha_innobase::ha_innobase(TABLE_SHARE *table_arg)
- :handler(innobase_hton, table_arg),
+ha_innobase::ha_innobase(handlerton *hton, TABLE_SHARE *table_arg)
+ :handler(hton, table_arg),
int_table_flags(HA_REC_NOT_IN_SEQ |
HA_NULL_IN_KEY |
HA_CAN_INDEX_BLOBS |
@@ -917,7 +928,7 @@ ha_innobase::update_thd(
row_prebuilt_t* prebuilt = (row_prebuilt_t*) innobase_prebuilt;
trx_t* trx;
- trx = check_trx_exists(thd);
+ trx = check_trx_exists(ht, thd);
if (prebuilt->trx != trx) {
@@ -938,10 +949,11 @@ inline
void
innobase_register_stmt(
/*===================*/
+ handlerton* hton, /* in: Innobase hton */
THD* thd) /* in: MySQL thd (connection) object */
{
/* Register the statement */
- trans_register_ha(thd, FALSE, innobase_hton);
+ trans_register_ha(thd, FALSE, hton);
}
/*************************************************************************
@@ -955,17 +967,18 @@ inline
void
innobase_register_trx_and_stmt(
/*===========================*/
+ handlerton *hton, /* in: Innobase handlerton */
THD* thd) /* in: MySQL thd (connection) object */
{
/* NOTE that actually innobase_register_stmt() registers also
the transaction in the AUTOCOMMIT=1 mode. */
- innobase_register_stmt(thd);
+ innobase_register_stmt(hton, thd);
if (thd->options & (OPTION_NOT_AUTOCOMMIT | OPTION_BEGIN)) {
/* No autocommit mode, register for a transaction */
- trans_register_ha(thd, TRUE, innobase_hton);
+ trans_register_ha(thd, TRUE, hton);
}
}
@@ -1061,7 +1074,7 @@ innobase_query_caching_of_table_permitted(
return((my_bool)FALSE);
}
- trx = check_trx_exists(thd);
+ trx = check_trx_exists(legacy_innodb_hton, thd);
if (trx->has_search_latch) {
ut_print_timestamp(stderr);
sql_print_error("The calling thread is holding the adaptive "
@@ -1120,7 +1133,7 @@ innobase_query_caching_of_table_permitted(
if (trx->active_trans == 0) {
- innobase_register_trx_and_stmt(thd);
+ innobase_register_trx_and_stmt(legacy_innodb_hton, thd);
trx->active_trans = 1;
}
@@ -1295,7 +1308,7 @@ ha_innobase::init_table_handle_for_HANDLER(void)
if (prebuilt->trx->active_trans == 0) {
- innobase_register_trx_and_stmt(current_thd);
+ innobase_register_trx_and_stmt(ht, current_thd);
prebuilt->trx->active_trans = 1;
}
@@ -1338,7 +1351,8 @@ innobase_init(void *p)
char *default_path;
DBUG_ENTER("innobase_init");
- innobase_hton= (handlerton *)p;
+ handlerton *innobase_hton= (handlerton *)p;
+ legacy_innodb_hton= innobase_hton;
innobase_hton->state=have_innodb;
innobase_hton->db_type= DB_TYPE_INNODB;
@@ -1613,7 +1627,7 @@ error:
Closes an InnoDB database. */
int
-innobase_end(ha_panic_function type)
+innobase_end(handlerton *hton, ha_panic_function type)
/*==============*/
/* out: TRUE if error */
{
@@ -1651,7 +1665,7 @@ Flushes InnoDB logs to disk and makes a checkpoint. Really, a commit flushes
the logs, and the name of this function should be innobase_checkpoint. */
bool
-innobase_flush_logs(void)
+innobase_flush_logs(handlerton *hton)
/*=====================*/
/* out: TRUE if error */
{
@@ -1690,6 +1704,7 @@ int
innobase_start_trx_and_assign_read_view(
/*====================================*/
/* out: 0 */
+ handlerton *hton, /* in: Innodb handlerton */
THD* thd) /* in: MySQL thread handle of the user for whom
the transaction should be committed */
{
@@ -1699,7 +1714,7 @@ innobase_start_trx_and_assign_read_view(
/* Create a new trx struct for thd, if it does not yet have one */
- trx = check_trx_exists(thd);
+ trx = check_trx_exists(hton, thd);
/* This is just to play safe: release a possible FIFO ticket and
search latch. Since we will reserve the kernel mutex, we have to
@@ -1718,9 +1733,7 @@ innobase_start_trx_and_assign_read_view(
/* Set the MySQL flag to mark that there is an active transaction */
if (trx->active_trans == 0) {
-
- innobase_register_trx_and_stmt(current_thd);
-
+ innobase_register_trx_and_stmt(hton, current_thd);
trx->active_trans = 1;
}
@@ -1735,7 +1748,8 @@ int
innobase_commit(
/*============*/
/* out: 0 */
- THD* thd, /* in: MySQL thread handle of the user for whom
+ handlerton *hton, /* in: Innodb handlerton */
+ THD* thd, /* in: MySQL thread handle of the user for whom
the transaction should be committed */
bool all) /* in: TRUE - commit transaction
FALSE - the current SQL statement ended */
@@ -1745,7 +1759,7 @@ innobase_commit(
DBUG_ENTER("innobase_commit");
DBUG_PRINT("trans", ("ending transaction"));
- trx = check_trx_exists(thd);
+ trx = check_trx_exists(hton, thd);
/* Update the info whether we should skip XA steps that eat CPU time */
trx->support_xa = (ibool)(thd->variables.innodb_support_xa);
@@ -1871,6 +1885,7 @@ int
innobase_report_binlog_offset_and_commit(
/*=====================================*/
/* out: 0 */
+ handlerton *hton, /* in: Innodb handlerton */
THD* thd, /* in: user thread */
void* trx_handle, /* in: InnoDB trx handle */
char* log_file_name, /* in: latest binlog file name */
@@ -1888,7 +1903,7 @@ innobase_report_binlog_offset_and_commit(
trx->flush_log_later = TRUE;
- innobase_commit(thd, TRUE);
+ innobase_commit(hton, thd, TRUE);
trx->flush_log_later = FALSE;
@@ -1936,11 +1951,12 @@ int
innobase_commit_complete(
/*=====================*/
/* out: 0 */
+ handlerton *hton, /* in: Innodb handlerton */
THD* thd) /* in: user thread */
{
trx_t* trx;
- trx = (trx_t*) thd->ha_data[innobase_hton->slot];
+ trx = (trx_t*) thd->ha_data[hton->slot];
if (trx && trx->active_trans) {
@@ -1964,6 +1980,7 @@ static int
innobase_rollback(
/*==============*/
/* out: 0 or error number */
+ handlerton *hton, /* in: Innodb handlerton */
THD* thd, /* in: handle to the MySQL thread of the user
whose transaction should be rolled back */
bool all) /* in: TRUE - commit transaction
@@ -1975,7 +1992,7 @@ innobase_rollback(
DBUG_ENTER("innobase_rollback");
DBUG_PRINT("trans", ("aborting transaction"));
- trx = check_trx_exists(thd);
+ trx = check_trx_exists(hton, thd);
/* Update the info whether we should skip XA steps that eat CPU time */
trx->support_xa = (ibool)(thd->variables.innodb_support_xa);
@@ -2047,6 +2064,7 @@ innobase_rollback_to_savepoint(
/*===========================*/
/* out: 0 if success, HA_ERR_NO_SAVEPOINT if
no savepoint with the given name */
+ handlerton *hton, /* in: Innodb handlerton */
THD* thd, /* in: handle to the MySQL thread of the user
whose transaction should be rolled back */
void* savepoint) /* in: savepoint data */
@@ -2058,7 +2076,7 @@ innobase_rollback_to_savepoint(
DBUG_ENTER("innobase_rollback_to_savepoint");
- trx = check_trx_exists(thd);
+ trx = check_trx_exists(hton, thd);
/* Release a possible FIFO ticket and search latch. Since we will
reserve the kernel mutex, we have to release the search system latch
@@ -2083,6 +2101,7 @@ innobase_release_savepoint(
/*=======================*/
/* out: 0 if success, HA_ERR_NO_SAVEPOINT if
no savepoint with the given name */
+ handlerton* hton, /* in: handlerton for Innodb */
THD* thd, /* in: handle to the MySQL thread of the user
whose transaction should be rolled back */
void* savepoint) /* in: savepoint data */
@@ -2093,7 +2112,7 @@ innobase_release_savepoint(
DBUG_ENTER("innobase_release_savepoint");
- trx = check_trx_exists(thd);
+ trx = check_trx_exists(hton, thd);
/* TODO: use provided savepoint data area to store savepoint data */
@@ -2111,6 +2130,7 @@ int
innobase_savepoint(
/*===============*/
/* out: always 0, that is, always succeeds */
+ handlerton* hton, /* in: handle to the Innodb handlerton */
THD* thd, /* in: handle to the MySQL thread */
void* savepoint) /* in: savepoint data */
{
@@ -2127,7 +2147,7 @@ innobase_savepoint(
DBUG_ASSERT(thd->options & (OPTION_NOT_AUTOCOMMIT | OPTION_BEGIN) ||
thd->in_sub_stmt);
- trx = check_trx_exists(thd);
+ trx = check_trx_exists(hton, thd);
/* Release a possible FIFO ticket and search latch. Since we will
reserve the kernel mutex, we have to release the search system latch
@@ -2154,12 +2174,13 @@ int
innobase_close_connection(
/*======================*/
/* out: 0 or error number */
+ handlerton* hton, /* in: innobase handlerton */
THD* thd) /* in: handle to the MySQL thread of the user
whose resources should be free'd */
{
trx_t* trx;
- trx = (trx_t*)thd->ha_data[innobase_hton->slot];
+ trx = (trx_t*)thd->ha_data[hton->slot];
ut_a(trx);
@@ -3025,8 +3046,9 @@ ha_innobase::store_key_val_for_row(
/******************************************************************
Builds a 'template' to the prebuilt struct. The template is used in fast
retrieval of just those column values MySQL needs in its processing. */
+static
void
-ha_innobase::build_template(
+build_template(
/*===========*/
row_prebuilt_t* prebuilt, /* in: prebuilt struct */
THD* thd, /* in: current user thread, used
@@ -3167,8 +3189,8 @@ include_field:
templ->col_no = i;
if (index == clust_index) {
- templ->rec_field_no = (index->table->cols + i)
- ->clust_pos;
+ templ->rec_field_no = dict_col_get_clust_pos_noninline(
+ &index->table->cols[i], index);
} else {
templ->rec_field_no = dict_index_get_nth_col_pos(
index, i);
@@ -3197,7 +3219,7 @@ include_field:
mysql_prefix_len = templ->mysql_col_offset
+ templ->mysql_col_len;
}
- templ->type = index->table->cols[i].type.mtype;
+ templ->type = index->table->cols[i].mtype;
templ->mysql_type = (ulint)field->type();
if (templ->mysql_type == DATA_MYSQL_TRUE_VARCHAR) {
@@ -3206,10 +3228,10 @@ include_field:
}
templ->charset = dtype_get_charset_coll_noninline(
- index->table->cols[i].type.prtype);
- templ->mbminlen = index->table->cols[i].type.mbminlen;
- templ->mbmaxlen = index->table->cols[i].type.mbmaxlen;
- templ->is_unsigned = index->table->cols[i].type.prtype
+ index->table->cols[i].prtype);
+ templ->mbminlen = index->table->cols[i].mbminlen;
+ templ->mbmaxlen = index->table->cols[i].mbmaxlen;
+ templ->is_unsigned = index->table->cols[i].prtype
& DATA_UNSIGNED;
if (templ->type == DATA_BLOB) {
prebuilt->templ_contains_blob = TRUE;
@@ -3227,8 +3249,9 @@ skip_field:
for (i = 0; i < n_requested_fields; i++) {
templ = prebuilt->mysql_template + i;
- templ->rec_field_no =
- (index->table->cols + templ->col_no)->clust_pos;
+ templ->rec_field_no = dict_col_get_clust_pos_noninline(
+ &index->table->cols[templ->col_no],
+ clust_index);
}
}
}
@@ -3252,11 +3275,11 @@ ha_innobase::write_row(
DBUG_ENTER("ha_innobase::write_row");
if (prebuilt->trx !=
- (trx_t*) current_thd->ha_data[innobase_hton->slot]) {
+ (trx_t*) current_thd->ha_data[ht->slot]) {
sql_print_error("The transaction object for the table handle is at "
"%p, but for the current thread it is at %p",
prebuilt->trx,
- (trx_t*) current_thd->ha_data[innobase_hton->slot]);
+ (trx_t*) current_thd->ha_data[ht->slot]);
fputs("InnoDB: Dump of 200 bytes around prebuilt: ", stderr);
ut_print_buf(stderr, ((const byte*)prebuilt) - 100, 200);
@@ -3264,7 +3287,7 @@ ha_innobase::write_row(
"InnoDB: Dump of 200 bytes around transaction.all: ",
stderr);
ut_print_buf(stderr,
- ((byte*)(&(current_thd->ha_data[innobase_hton->slot]))) - 100,
+ ((byte*)(&(current_thd->ha_data[ht->slot]))) - 100,
200);
putc('\n', stderr);
ut_error;
@@ -3318,7 +3341,7 @@ no_commit:
no need to re-acquire locks on it. */
/* Altering to InnoDB format */
- innobase_commit(user_thd, 1);
+ innobase_commit(ht, user_thd, 1);
/* Note that this transaction is still active. */
prebuilt->trx->active_trans = 1;
/* We will need an IX lock on the destination table. */
@@ -3334,7 +3357,7 @@ no_commit:
/* Commit the transaction. This will release the table
locks, so they have to be acquired again. */
- innobase_commit(user_thd, 1);
+ innobase_commit(ht, user_thd, 1);
/* Note that this transaction is still active. */
prebuilt->trx->active_trans = 1;
/* Re-acquire the table lock on the source table. */
@@ -3495,9 +3518,11 @@ calc_row_difference(
ulint col_type;
ulint n_changed = 0;
dfield_t dfield;
+ dict_index_t* clust_index;
uint i;
n_fields = table->s->fields;
+ clust_index = dict_table_get_first_index_noninline(prebuilt->table);
/* We use upd_buff to convert changed fields */
buf = (byte*) upd_buff;
@@ -3528,7 +3553,7 @@ calc_row_difference(
field_mysql_type = field->type();
- col_type = prebuilt->table->cols[i].type.mtype;
+ col_type = prebuilt->table->cols[i].mtype;
switch (col_type) {
@@ -3583,7 +3608,8 @@ calc_row_difference(
/* Let us use a dummy dfield to make the conversion
from the MySQL column format to the InnoDB format */
- dfield.type = (prebuilt->table->cols + i)->type;
+ dict_col_copy_type_noninline(prebuilt->table->cols + i,
+ &dfield.type);
if (n_len != UNIV_SQL_NULL) {
buf = row_mysql_store_col_in_innobase_format(
@@ -3602,7 +3628,8 @@ calc_row_difference(
}
ufield->exp = NULL;
- ufield->field_no = prebuilt->table->cols[i].clust_pos;
+ ufield->field_no = dict_col_get_clust_pos_noninline(
+ &prebuilt->table->cols[i], clust_index);
n_changed++;
}
}
@@ -3637,7 +3664,7 @@ ha_innobase::update_row(
DBUG_ENTER("ha_innobase::update_row");
ut_a(prebuilt->trx ==
- (trx_t*) current_thd->ha_data[innobase_hton->slot]);
+ (trx_t*) current_thd->ha_data[ht->slot]);
if (table->timestamp_field_type & TIMESTAMP_AUTO_SET_ON_UPDATE)
table->timestamp_field->set_time();
@@ -3698,7 +3725,7 @@ ha_innobase::delete_row(
DBUG_ENTER("ha_innobase::delete_row");
ut_a(prebuilt->trx ==
- (trx_t*) current_thd->ha_data[innobase_hton->slot]);
+ (trx_t*) current_thd->ha_data[ht->slot]);
if (last_query_id != user_thd->query_id) {
prebuilt->sql_stat_start = TRUE;
@@ -3796,7 +3823,7 @@ ha_innobase::try_semi_consistent_read(bool yes)
row_prebuilt_t* prebuilt = (row_prebuilt_t*) innobase_prebuilt;
ut_a(prebuilt->trx ==
- (trx_t*) current_thd->ha_data[innobase_hton->slot]);
+ (trx_t*) current_thd->ha_data[ht->slot]);
/* Row read type is set to semi consistent read if this was
requested by the MySQL and either innodb_locks_unsafe_for_binlog
@@ -3963,7 +3990,7 @@ ha_innobase::index_read(
DBUG_ENTER("index_read");
ut_a(prebuilt->trx ==
- (trx_t*) current_thd->ha_data[innobase_hton->slot]);
+ (trx_t*) current_thd->ha_data[ht->slot]);
statistic_increment(current_thd->status_var.ha_read_key_count,
&LOCK_status);
@@ -4078,7 +4105,7 @@ ha_innobase::change_active_index(
ut_ad(user_thd == current_thd);
ut_a(prebuilt->trx ==
- (trx_t*) current_thd->ha_data[innobase_hton->slot]);
+ (trx_t*) current_thd->ha_data[ht->slot]);
active_index = keynr;
@@ -4168,7 +4195,7 @@ ha_innobase::general_fetch(
DBUG_ENTER("general_fetch");
ut_a(prebuilt->trx ==
- (trx_t*) current_thd->ha_data[innobase_hton->slot]);
+ (trx_t*) current_thd->ha_data[ht->slot]);
innodb_srv_conc_enter_innodb(prebuilt->trx);
@@ -4404,7 +4431,7 @@ ha_innobase::rnd_pos(
&LOCK_status);
ut_a(prebuilt->trx ==
- (trx_t*) current_thd->ha_data[innobase_hton->slot]);
+ (trx_t*) current_thd->ha_data[ht->slot]);
if (prebuilt->clust_index_was_generated) {
/* No primary key was defined for the table and we
@@ -4454,7 +4481,7 @@ ha_innobase::position(
uint len;
ut_a(prebuilt->trx ==
- (trx_t*) current_thd->ha_data[innobase_hton->slot]);
+ (trx_t*) current_thd->ha_data[ht->slot]);
if (prebuilt->clust_index_was_generated) {
/* No primary key was defined for the table and we
@@ -4582,8 +4609,7 @@ create_table_def(
| nulls_allowed | unsigned_type
| binary_type | long_true_varchar,
charset_no),
- col_len,
- 0);
+ col_len);
}
error = row_create_table_for_mysql(table, trx);
@@ -4782,7 +4808,7 @@ ha_innobase::create(
/* Get the transaction associated with the current thd, or create one
if not yet created */
- parent_trx = check_trx_exists(thd);
+ parent_trx = check_trx_exists(ht, thd);
/* In case MySQL calls this in the middle of a SELECT query, release
possible adaptive hash latch to avoid deadlocks of threads */
@@ -4955,7 +4981,7 @@ ha_innobase::discard_or_import_tablespace(
ut_a(prebuilt->trx && prebuilt->trx->magic_n == TRX_MAGIC_N);
ut_a(prebuilt->trx ==
- (trx_t*) current_thd->ha_data[innobase_hton->slot]);
+ (trx_t*) current_thd->ha_data[ht->slot]);
dict_table = prebuilt->table;
trx = prebuilt->trx;
@@ -5035,7 +5061,7 @@ ha_innobase::delete_table(
/* Get the transaction associated with the current thd, or create one
if not yet created */
- parent_trx = check_trx_exists(thd);
+ parent_trx = check_trx_exists(ht, thd);
/* In case MySQL calls this in the middle of a SELECT query, release
possible adaptive hash latch to avoid deadlocks of threads */
@@ -5102,6 +5128,7 @@ void
innobase_drop_database(
/*===================*/
/* out: error number */
+ handlerton *hton, /* in: handlerton of Innodb */
char* path) /* in: database path; inside InnoDB the name
of the last directory in the path is used as
the database name: for example, in 'mysql/data/test'
@@ -5117,7 +5144,7 @@ innobase_drop_database(
/* Get the transaction associated with the current thd, or create one
if not yet created */
- parent_trx = check_trx_exists(current_thd);
+ parent_trx = check_trx_exists(hton, current_thd);
/* In case MySQL calls this in the middle of a SELECT query, release
possible adaptive hash latch to avoid deadlocks of threads */
@@ -5196,7 +5223,7 @@ ha_innobase::rename_table(
/* Get the transaction associated with the current thd, or create one
if not yet created */
- parent_trx = check_trx_exists(current_thd);
+ parent_trx = check_trx_exists(ht, current_thd);
/* In case MySQL calls this in the middle of a SELECT query, release
possible adaptive hash latch to avoid deadlocks of threads */
@@ -5283,7 +5310,7 @@ ha_innobase::records_in_range(
DBUG_ENTER("records_in_range");
ut_a(prebuilt->trx ==
- (trx_t*) current_thd->ha_data[innobase_hton->slot]);
+ (trx_t*) current_thd->ha_data[ht->slot]);
prebuilt->trx->op_info = (char*)"estimating records in index range";
@@ -5725,7 +5752,7 @@ ha_innobase::check(
ut_a(prebuilt->trx && prebuilt->trx->magic_n == TRX_MAGIC_N);
ut_a(prebuilt->trx ==
- (trx_t*) current_thd->ha_data[innobase_hton->slot]);
+ (trx_t*) current_thd->ha_data[ht->slot]);
if (prebuilt->mysql_template == NULL) {
/* Build the template; we will use a dummy template
@@ -6009,7 +6036,7 @@ ha_innobase::can_switch_engines(void)
DBUG_ENTER("ha_innobase::can_switch_engines");
ut_a(prebuilt->trx ==
- (trx_t*) current_thd->ha_data[innobase_hton->slot]);
+ (trx_t*) current_thd->ha_data[ht->slot]);
prebuilt->trx->op_info =
"determining if there are foreign key constraints";
@@ -6176,25 +6203,11 @@ ha_innobase::start_stmt(
1) ::store_lock(),
2) ::external_lock(),
3) ::init_table_handle_for_HANDLER(), and
- 4) :.transactional_table_lock(). */
+ 4) ::transactional_table_lock(). */
prebuilt->select_lock_type =
prebuilt->stored_select_lock_type;
}
-
- if (prebuilt->stored_select_lock_type != LOCK_S
- && prebuilt->stored_select_lock_type != LOCK_X) {
- sql_print_error(
- "stored_select_lock_type is %lu inside "
- "::start_stmt()!",
- prebuilt->stored_select_lock_type);
-
- /* Set the value to LOCK_X: this is just fault
- tolerance, we do not know what the correct value
- should be! */
-
- prebuilt->select_lock_type = LOCK_X;
- }
}
trx->detailed_error[0] = '\0';
@@ -6202,10 +6215,10 @@ ha_innobase::start_stmt(
/* Set the MySQL flag to mark that there is an active transaction */
if (trx->active_trans == 0) {
- innobase_register_trx_and_stmt(thd);
+ innobase_register_trx_and_stmt(ht, thd);
trx->active_trans = 1;
} else {
- innobase_register_stmt(thd);
+ innobase_register_stmt(ht, thd);
}
return(0);
@@ -6278,10 +6291,10 @@ ha_innobase::external_lock(
transaction */
if (trx->active_trans == 0) {
- innobase_register_trx_and_stmt(thd);
+ innobase_register_trx_and_stmt(ht, thd);
trx->active_trans = 1;
} else if (trx->n_mysql_tables_in_use == 0) {
- innobase_register_stmt(thd);
+ innobase_register_stmt(ht, thd);
}
trx->n_mysql_tables_in_use++;
@@ -6359,7 +6372,7 @@ ha_innobase::external_lock(
if (!(thd->options & (OPTION_NOT_AUTOCOMMIT | OPTION_BEGIN))) {
if (trx->active_trans != 0) {
- innobase_commit(thd, TRUE);
+ innobase_commit(ht, thd, TRUE);
}
} else {
if (trx->isolation_level <= TRX_ISO_READ_COMMITTED
@@ -6440,7 +6453,7 @@ ha_innobase::transactional_table_lock(
/* Set the MySQL flag to mark that there is an active transaction */
if (trx->active_trans == 0) {
- innobase_register_trx_and_stmt(thd);
+ innobase_register_trx_and_stmt(ht, thd);
trx->active_trans = 1;
}
@@ -6488,6 +6501,7 @@ Monitor to the client. */
bool
innodb_show_status(
/*===============*/
+ handlerton* hton, /* in: the innodb handlerton */
THD* thd, /* in: the MySQL query thread of the caller */
stat_print_fn *stat_print)
{
@@ -6503,7 +6517,7 @@ innodb_show_status(
DBUG_RETURN(FALSE);
}
- trx = check_trx_exists(thd);
+ trx = check_trx_exists(hton, thd);
innobase_release_stat_resources(trx);
@@ -6578,6 +6592,7 @@ Implements the SHOW MUTEX STATUS command. . */
bool
innodb_mutex_show_status(
/*=====================*/
+ handlerton* hton, /* in: the innodb handlerton */
THD* thd, /* in: the MySQL query thread of the
caller */
stat_print_fn* stat_print)
@@ -6659,14 +6674,15 @@ innodb_mutex_show_status(
DBUG_RETURN(FALSE);
}
-bool innobase_show_status(THD* thd, stat_print_fn* stat_print,
- enum ha_stat_type stat_type)
+bool innobase_show_status(handlerton *hton, THD* thd,
+ stat_print_fn* stat_print,
+ enum ha_stat_type stat_type)
{
switch (stat_type) {
case HA_ENGINE_STATUS:
- return innodb_show_status(thd, stat_print);
+ return innodb_show_status(hton, thd, stat_print);
case HA_ENGINE_MUTEX:
- return innodb_mutex_show_status(thd, stat_print);
+ return innodb_mutex_show_status(hton, thd, stat_print);
default:
return FALSE;
}
@@ -6766,7 +6782,7 @@ ha_innobase::store_lock(
because we call update_thd() later, in ::external_lock()! Failure to
understand this caused a serious memory corruption bug in 5.1.11. */
- trx = check_trx_exists(thd);
+ trx = check_trx_exists(ht, thd);
/* NOTE: MySQL can call this function with lock 'type' TL_IGNORE!
Be careful to ignore TL_IGNORE if we are going to do something with
@@ -7152,7 +7168,7 @@ ha_innobase::reset_auto_increment(ulonglong value)
bool
ha_innobase::get_error_message(int error, String *buf)
{
- trx_t* trx = check_trx_exists(current_thd);
+ trx_t* trx = check_trx_exists(ht, current_thd);
buf->copy(trx->detailed_error, strlen(trx->detailed_error),
system_charset_info);
@@ -7371,13 +7387,14 @@ int
innobase_xa_prepare(
/*================*/
/* out: 0 or error number */
+ handlerton *hton,
THD* thd, /* in: handle to the MySQL thread of the user
whose XA transaction should be prepared */
bool all) /* in: TRUE - commit transaction
FALSE - the current SQL statement ended */
{
int error = 0;
- trx_t* trx = check_trx_exists(thd);
+ trx_t* trx = check_trx_exists(hton, thd);
if (thd->lex->sql_command != SQLCOM_XA_PREPARE &&
(all || !(thd->options & (OPTION_NOT_AUTOCOMMIT | OPTION_BEGIN))))
@@ -7467,6 +7484,7 @@ innobase_xa_recover(
/*================*/
/* out: number of prepared transactions
stored in xid_list */
+ handlerton *hton,
XID* xid_list, /* in/out: prepared transactions */
uint len) /* in: number of slots in xid_list */
{
@@ -7486,6 +7504,7 @@ int
innobase_commit_by_xid(
/*===================*/
/* out: 0 or error number */
+ handlerton *hton,
XID* xid) /* in: X/Open XA transaction identification */
{
trx_t* trx;
@@ -7509,6 +7528,7 @@ int
innobase_rollback_by_xid(
/*=====================*/
/* out: 0 or error number */
+ handlerton *hton,
XID *xid) /* in: X/Open XA transaction identification */
{
trx_t* trx;
@@ -7529,12 +7549,13 @@ This consistent view is then used inside of MySQL when accessing records
using a cursor. */
void*
-innobase_create_cursor_view(void)
-/*=============================*/
- /* out: Pointer to cursor view or NULL */
+innobase_create_cursor_view(
+ /* out: pointer to cursor view or NULL */
+ handlerton *hton, /* in: innobase hton */
+ THD* thd) /* in: user thread handle */
{
return(read_cursor_view_create_for_mysql(
- check_trx_exists(current_thd)));
+ check_trx_exists(hton, thd)));
}
/***********************************************************************
@@ -7544,10 +7565,11 @@ corresponding MySQL thread still lacks one. */
void
innobase_close_cursor_view(
-/*=======================*/
+ handlerton *hton,
+ THD* thd, /* in: user thread handle */
void* curview)/* in: Consistent read view to be closed */
{
- read_cursor_view_close_for_mysql(check_trx_exists(current_thd),
+ read_cursor_view_close_for_mysql(check_trx_exists(hton, current_thd),
(cursor_view_t*) curview);
}
@@ -7560,9 +7582,11 @@ restored to a transaction read view. */
void
innobase_set_cursor_view(
/*=====================*/
+ handlerton *hton,
+ THD* thd, /* in: user thread handle */
void* curview)/* in: Consistent cursor view to be set */
{
- read_cursor_set_for_mysql(check_trx_exists(current_thd),
+ read_cursor_set_for_mysql(check_trx_exists(hton, current_thd),
(cursor_view_t*) curview);
}
@@ -7607,7 +7631,7 @@ SHOW_VAR innodb_status_variables_export[]= {
};
struct st_mysql_storage_engine innobase_storage_engine=
-{ MYSQL_HANDLERTON_INTERFACE_VERSION, innobase_hton};
+{ MYSQL_HANDLERTON_INTERFACE_VERSION };
mysql_declare_plugin(innobase)
{
@@ -7616,6 +7640,7 @@ mysql_declare_plugin(innobase)
innobase_hton_name,
"Innobase OY",
"Supports transactions, row-level locking, and foreign keys",
+ PLUGIN_LICENSE_GPL,
innobase_init, /* Plugin Init */
NULL, /* Plugin Deinit */
0x0100 /* 1.0 */,
diff --git a/storage/innobase/handler/ha_innodb.h b/storage/innobase/handler/ha_innodb.h
index 4d5dc6b52d6..d6c9b8a0d9f 100644
--- a/storage/innobase/handler/ha_innodb.h
+++ b/storage/innobase/handler/ha_innodb.h
@@ -80,7 +80,7 @@ class ha_innobase: public handler
/* Init values for the class: */
public:
- ha_innobase(TABLE_SHARE *table_arg);
+ ha_innobase(handlerton *hton, TABLE_SHARE *table_arg);
~ha_innobase() {}
/*
Get the row type from the storage engine. If this method returns
@@ -201,8 +201,6 @@ class ha_innobase: public handler
int cmp_ref(const byte *ref1, const byte *ref2);
bool check_if_incompatible_data(HA_CREATE_INFO *info,
uint table_changes);
- void build_template(struct row_prebuilt_struct *prebuilt, THD *thd,
- TABLE *table, uint templ_type);
};
extern SHOW_VAR innodb_status_variables[];
@@ -240,8 +238,8 @@ extern ulong srv_flush_log_at_trx_commit;
}
int innobase_init(void);
-int innobase_end(ha_panic_function type);
-bool innobase_flush_logs(void);
+int innobase_end(handlerton *hton, ha_panic_function type);
+bool innobase_flush_logs(handlerton *hton);
uint innobase_get_free_space(void);
/*
@@ -258,14 +256,14 @@ int innobase_commit_complete(void* trx_handle);
void innobase_store_binlog_offset_and_flush_log(char *binlog_name,longlong offset);
#endif
-void innobase_drop_database(char *path);
-bool innobase_show_status(THD* thd, stat_print_fn*, enum ha_stat_type);
+void innobase_drop_database(handlerton *hton, char *path);
+bool innobase_show_status(handlerton *hton, THD* thd, stat_print_fn*, enum ha_stat_type);
-int innobase_release_temporary_latches(THD *thd);
+int innobase_release_temporary_latches(handlerton *hton, THD *thd);
-void innobase_store_binlog_offset_and_flush_log(char *binlog_name,longlong offset);
+void innobase_store_binlog_offset_and_flush_log(handlerton *hton, char *binlog_name,longlong offset);
-int innobase_start_trx_and_assign_read_view(THD* thd);
+int innobase_start_trx_and_assign_read_view(handlerton *hton, THD* thd);
/***********************************************************************
This function is used to prepare X/Open XA distributed transaction */
@@ -273,6 +271,7 @@ This function is used to prepare X/Open XA distributed transaction */
int innobase_xa_prepare(
/*====================*/
/* out: 0 or error number */
+ handlerton *hton, /* in: innobase hton */
THD* thd, /* in: handle to the MySQL thread of the user
whose XA transaction should be prepared */
bool all); /* in: TRUE - commit transaction
@@ -285,6 +284,7 @@ int innobase_xa_recover(
/*====================*/
/* out: number of prepared transactions
stored in xid_list */
+ handlerton *hton, /* in: innobase hton */
XID* xid_list, /* in/out: prepared transactions */
uint len); /* in: number of slots in xid_list */
@@ -295,6 +295,7 @@ which is in the prepared state */
int innobase_commit_by_xid(
/*=======================*/
/* out: 0 or error number */
+ handlerton *hton, /* in: innobase hton */
XID* xid); /* in : X/Open XA Transaction Identification */
/***********************************************************************
@@ -303,6 +304,7 @@ which is in the prepared state */
int innobase_rollback_by_xid(
/* out: 0 or error number */
+ handlerton *hton, /* in: innobase hton */
XID *xid); /* in : X/Open XA Transaction Identification */
@@ -313,9 +315,10 @@ This consistent view is then used inside of MySQL when accessing records
using a cursor. */
void*
-innobase_create_cursor_view(void);
-/*=============================*/
- /* out: Pointer to cursor view or NULL */
+innobase_create_cursor_view(
+ /* out: Pointer to cursor view or NULL */
+ handlerton *hton, /* in: innobase hton */
+ THD* thd); /* in: user thread handle */
/***********************************************************************
Close the given consistent cursor view of a transaction and restore
@@ -325,8 +328,11 @@ corresponding MySQL thread still lacks one. */
void
innobase_close_cursor_view(
/*=======================*/
+ handlerton *hton, /* in: innobase hton */
+ THD* thd, /* in: user thread handle */
void* curview); /* in: Consistent read view to be closed */
+
/***********************************************************************
Set the given consistent cursor view to a transaction which is created
if the corresponding MySQL thread still lacks one. If the given
@@ -336,4 +342,6 @@ restored to a transaction read view. */
void
innobase_set_cursor_view(
/*=====================*/
+ handlerton *hton, /* in: innobase hton */
+ THD* thd, /* in: user thread handle */
void* curview); /* in: Consistent read view to be set */
diff --git a/storage/innobase/ibuf/ibuf0ibuf.c b/storage/innobase/ibuf/ibuf0ibuf.c
index 2f4d0ae1009..96ab928a436 100644
--- a/storage/innobase/ibuf/ibuf0ibuf.c
+++ b/storage/innobase/ibuf/ibuf0ibuf.c
@@ -305,7 +305,7 @@ ibuf_tree_root_get(
ut_a(space == 0);
ut_ad(ibuf_inside());
- mtr_x_lock(dict_tree_get_lock((data->index)->tree), mtr);
+ mtr_x_lock(dict_index_get_lock(data->index), mtr);
page = buf_page_get(space, FSP_IBUF_TREE_ROOT_PAGE_NO, RW_X_LATCH,
mtr);
@@ -524,16 +524,16 @@ ibuf_data_init_for_space(
/* use old-style record format for the insert buffer */
table = dict_mem_table_create(buf, space, 2, 0);
- dict_mem_table_add_col(table, "PAGE_NO", DATA_BINARY, 0, 0, 0);
- dict_mem_table_add_col(table, "TYPES", DATA_BINARY, 0, 0, 0);
+ dict_mem_table_add_col(table, "PAGE_NO", DATA_BINARY, 0, 0);
+ dict_mem_table_add_col(table, "TYPES", DATA_BINARY, 0, 0);
table->id = ut_dulint_add(DICT_IBUF_ID_MIN, space);
dict_table_add_to_cache(table);
- index = dict_mem_index_create
- (buf, "CLUST_IND", space,
- DICT_CLUSTERED | DICT_UNIVERSAL | DICT_IBUF, 2);
+ index = dict_mem_index_create(
+ buf, "CLUST_IND", space,
+ DICT_CLUSTERED | DICT_UNIVERSAL | DICT_IBUF, 2);
dict_mem_index_add_field(index, "PAGE_NO", 0);
dict_mem_index_add_field(index, "TYPES", 0);
@@ -768,9 +768,9 @@ ibuf_set_free_bits_low(
return;
}
- bitmap_page = ibuf_bitmap_get_map_page
- (buf_frame_get_space_id(page),
- buf_frame_get_page_no(page), mtr);
+ bitmap_page = ibuf_bitmap_get_map_page(
+ buf_frame_get_space_id(page),
+ buf_frame_get_page_no(page), mtr);
#ifdef UNIV_IBUF_DEBUG
# if 0
fprintf(stderr,
@@ -818,17 +818,17 @@ ibuf_set_free_bits(
mtr_start(&mtr);
- bitmap_page = ibuf_bitmap_get_map_page
- (buf_frame_get_space_id(page),
- buf_frame_get_page_no(page), &mtr);
+ bitmap_page = ibuf_bitmap_get_map_page(
+ buf_frame_get_space_id(page), buf_frame_get_page_no(page),
+ &mtr);
if (max_val != ULINT_UNDEFINED) {
#ifdef UNIV_IBUF_DEBUG
ulint old_val;
- old_val = ibuf_bitmap_page_get_bits
- (bitmap_page, buf_frame_get_page_no(page),
- IBUF_BITMAP_FREE, &mtr);
+ old_val = ibuf_bitmap_page_get_bits(
+ bitmap_page, buf_frame_get_page_no(page),
+ IBUF_BITMAP_FREE, &mtr);
# if 0
if (old_val != max_val) {
fprintf(stderr,
@@ -1145,9 +1145,8 @@ ibuf_dummy_index_add_col(
dict_mem_table_add_col(index->table, "DUMMY",
dtype_get_mtype(type),
dtype_get_prtype(type),
- dtype_get_len(type),
- dtype_get_prec(type));
- dict_index_add_col(index,
+ dtype_get_len(type));
+ dict_index_add_col(index, index->table, (dict_col_t*)
dict_table_get_nth_col(index->table, i), len);
}
/************************************************************************
@@ -1165,6 +1164,11 @@ ibuf_dummy_index_free(
dict_mem_table_free(table);
}
+void
+dict_index_print_low(
+/*=================*/
+ dict_index_t* index); /* in: index */
+
/*************************************************************************
Builds the entry to insert into a non-clustered index when we have the
corresponding record in an ibuf index. */
@@ -1213,9 +1217,9 @@ ibuf_build_entry_from_ibuf_rec(
dfield_set_data(field, data, len);
- dtype_read_for_order_and_null_size
- (dfield_get_type(field),
- types + i * DATA_ORDER_NULL_TYPE_BUF_SIZE);
+ dtype_read_for_order_and_null_size(
+ dfield_get_type(field),
+ types + i * DATA_ORDER_NULL_TYPE_BUF_SIZE);
}
*pindex = ibuf_dummy_index_create(n_fields, FALSE);
@@ -1235,8 +1239,8 @@ ibuf_build_entry_from_ibuf_rec(
types = rec_get_nth_field_old(ibuf_rec, 3, &len);
ut_a(len % DATA_NEW_ORDER_NULL_TYPE_BUF_SIZE <= 1);
- index = ibuf_dummy_index_create
- (n_fields, len % DATA_NEW_ORDER_NULL_TYPE_BUF_SIZE);
+ index = ibuf_dummy_index_create(
+ n_fields, len % DATA_NEW_ORDER_NULL_TYPE_BUF_SIZE);
if (len % DATA_NEW_ORDER_NULL_TYPE_BUF_SIZE) {
/* compact record format */
@@ -1254,9 +1258,9 @@ ibuf_build_entry_from_ibuf_rec(
dfield_set_data(field, data, len);
- dtype_new_read_for_order_and_null_size
- (dfield_get_type(field),
- types + i * DATA_NEW_ORDER_NULL_TYPE_BUF_SIZE);
+ dtype_new_read_for_order_and_null_size(
+ dfield_get_type(field),
+ types + i * DATA_NEW_ORDER_NULL_TYPE_BUF_SIZE);
ibuf_dummy_index_add_col(index, dfield_get_type(field), len);
}
@@ -1315,8 +1319,8 @@ ibuf_rec_get_volume(
ulint volume;
dict_index_t* dummy_index;
mem_heap_t* heap = mem_heap_create(500);
- dtuple_t* entry = ibuf_build_entry_from_ibuf_rec
- (ibuf_rec, heap, &dummy_index);
+ dtuple_t* entry = ibuf_build_entry_from_ibuf_rec(
+ ibuf_rec, heap, &dummy_index);
volume = rec_get_converted_size(dummy_index, entry);
ibuf_dummy_index_free(dummy_index);
mem_heap_free(heap);
@@ -1332,15 +1336,15 @@ ibuf_rec_get_volume(
if (new_format) {
data = rec_get_nth_field_old(ibuf_rec, i + 4, &len);
- dtype_new_read_for_order_and_null_size
- (&dtype, types + i
- * DATA_NEW_ORDER_NULL_TYPE_BUF_SIZE);
+ dtype_new_read_for_order_and_null_size(
+ &dtype, types + i
+ * DATA_NEW_ORDER_NULL_TYPE_BUF_SIZE);
} else {
data = rec_get_nth_field_old(ibuf_rec, i + 2, &len);
- dtype_read_for_order_and_null_size
- (&dtype, types + i
- * DATA_ORDER_NULL_TYPE_BUF_SIZE);
+ dtype_read_for_order_and_null_size(
+ &dtype, types + i
+ * DATA_ORDER_NULL_TYPE_BUF_SIZE);
}
if (len == UNIV_SQL_NULL) {
@@ -1365,8 +1369,8 @@ ibuf_entry_build(
index tree; NOTE that the original entry
must be kept because we copy pointers to its
fields */
+ dict_index_t* index, /* in: non-clustered index */
dtuple_t* entry, /* in: entry for a non-clustered index */
- ibool comp, /* in: flag: TRUE=compact record format */
ulint space, /* in: space id */
ulint page_no,/* in: index page number where entry should
be inserted */
@@ -1430,13 +1434,12 @@ ibuf_entry_build(
dfield_set_data(field, buf, 4);
- ut_ad(comp == 0 || comp == 1);
/* Store the type info in buf2, and add the fields from entry to
tuple */
buf2 = mem_heap_alloc(heap, n_fields
* DATA_NEW_ORDER_NULL_TYPE_BUF_SIZE
- + comp);
- if (comp) {
+ + dict_table_is_comp(index->table));
+ if (dict_table_is_comp(index->table)) {
*buf2++ = 0; /* write the compact format indicator */
}
for (i = 0; i < n_fields; i++) {
@@ -1447,22 +1450,23 @@ ibuf_entry_build(
entry_field = dtuple_get_nth_field(entry, i);
dfield_copy(field, entry_field);
- dtype_new_store_for_order_and_null_size
- (buf2 + i * DATA_NEW_ORDER_NULL_TYPE_BUF_SIZE,
- dfield_get_type(entry_field));
+ dtype_new_store_for_order_and_null_size(
+ buf2 + i * DATA_NEW_ORDER_NULL_TYPE_BUF_SIZE,
+ dfield_get_type(entry_field),
+ dict_index_get_nth_field(index, i)->prefix_len);
}
/* Store the type info in buf2 to field 3 of tuple */
field = dtuple_get_nth_field(tuple, 3);
- if (comp) {
+ if (dict_table_is_comp(index->table)) {
buf2--;
}
dfield_set_data(field, buf2, n_fields
* DATA_NEW_ORDER_NULL_TYPE_BUF_SIZE
- + comp);
+ + dict_table_is_comp(index->table));
/* Set all the types in the new tuple binary */
dtuple_set_types_binary(tuple, n_fields + 4);
@@ -2605,8 +2609,7 @@ ibuf_insert_low(
the first fields and the type information for other fields, and which
will be inserted to the insert buffer. */
- ibuf_entry = ibuf_entry_build(entry, dict_table_is_comp(index->table),
- space, page_no, heap);
+ ibuf_entry = ibuf_entry_build(index, entry, space, page_no, heap);
/* Open a cursor to the insert buffer tree to calculate if we can add
the new entry to it without exceeding the free space limit for the
@@ -2879,8 +2882,9 @@ dump:
PAGE_CUR_LE, &page_cur);
/* This time the record must fit */
- if (UNIV_UNLIKELY(!page_cur_tuple_insert
- (&page_cur, entry, index, mtr))) {
+ if (UNIV_UNLIKELY(!page_cur_tuple_insert(
+ &page_cur, entry, index,
+ mtr))) {
ut_print_timestamp(stderr);
@@ -2888,10 +2892,10 @@ dump:
"InnoDB: Error: Insert buffer insert"
" fails; page free %lu,"
" dtuple size %lu\n",
- (ulong) page_get_max_insert_size
- (page, 1),
- (ulong) rec_get_converted_size
- (index, entry));
+ (ulong) page_get_max_insert_size(
+ page, 1),
+ (ulong) rec_get_converted_size(
+ index, entry));
fputs("InnoDB: Cannot insert index record ",
stderr);
dtuple_print(stderr, entry);
@@ -2901,14 +2905,14 @@ dump:
" Please run CHECK TABLE on\n"
"InnoDB: that table.\n", stderr);
- bitmap_page = ibuf_bitmap_get_map_page
- (buf_frame_get_space_id(page),
- buf_frame_get_page_no(page),
- mtr);
- old_bits = ibuf_bitmap_page_get_bits
- (bitmap_page,
- buf_frame_get_page_no(page),
- IBUF_BITMAP_FREE, mtr);
+ bitmap_page = ibuf_bitmap_get_map_page(
+ buf_frame_get_space_id(page),
+ buf_frame_get_page_no(page),
+ mtr);
+ old_bits = ibuf_bitmap_page_get_bits(
+ bitmap_page,
+ buf_frame_get_page_no(page),
+ IBUF_BITMAP_FREE, mtr);
fprintf(stderr, "Bitmap bits %lu\n",
(ulong) old_bits);
@@ -2996,7 +3000,7 @@ ibuf_delete_rec(
btr_pcur_commit_specify_mtr(pcur, mtr);
fputs("InnoDB: Validating insert buffer tree:\n", stderr);
- if (!btr_validate_tree(ibuf_data->index->tree, NULL)) {
+ if (!btr_validate_index(ibuf_data->index, NULL)) {
ut_error;
}
@@ -3235,12 +3239,12 @@ loop:
keep the latch to the ibuf_rec page until the
insertion is finished! */
dict_index_t* dummy_index;
- dulint max_trx_id = page_get_max_trx_id
- (buf_frame_align(ibuf_rec));
+ dulint max_trx_id = page_get_max_trx_id(
+ buf_frame_align(ibuf_rec));
page_update_max_trx_id(page, max_trx_id);
- entry = ibuf_build_entry_from_ibuf_rec
- (ibuf_rec, heap, &dummy_index);
+ entry = ibuf_build_entry_from_ibuf_rec(
+ ibuf_rec, heap, &dummy_index);
#ifdef UNIV_IBUF_DEBUG
volume += rec_get_converted_size(dummy_index, entry)
+ page_dir_calc_reserved_space(1);
@@ -3283,15 +3287,15 @@ reset_bit:
ibuf_bitmap_page_set_bits(bitmap_page, page_no,
IBUF_BITMAP_BUFFERED, FALSE, &mtr);
if (page) {
- ulint old_bits = ibuf_bitmap_page_get_bits
- (bitmap_page, page_no, IBUF_BITMAP_FREE, &mtr);
+ ulint old_bits = ibuf_bitmap_page_get_bits(
+ bitmap_page, page_no, IBUF_BITMAP_FREE, &mtr);
ulint new_bits = ibuf_index_page_calc_free(page);
#if 0 /* defined UNIV_IBUF_DEBUG */
fprintf(stderr, "Old bits %lu new bits %lu"
" max size %lu\n",
old_bits, new_bits,
- page_get_max_insert_size_after_reorganize
- (page, 1));
+ page_get_max_insert_size_after_reorganize(
+ page, 1));
#endif
if (old_bits != new_bits) {
ibuf_bitmap_page_set_bits(bitmap_page, page_no,
diff --git a/storage/innobase/include/btr0btr.h b/storage/innobase/include/btr0btr.h
index 288b0459b13..664607a26aa 100644
--- a/storage/innobase/include/btr0btr.h
+++ b/storage/innobase/include/btr0btr.h
@@ -52,7 +52,7 @@ page_t*
btr_root_get(
/*=========*/
/* out: root page, x-latched */
- dict_tree_t* tree, /* in: index tree */
+ dict_index_t* index, /* in: index tree */
mtr_t* mtr); /* in: mtr */
/******************************************************************
Gets a buffer page and declares its latching order level. */
@@ -255,7 +255,7 @@ that mtr holds an x-latch on the tree. */
void
btr_insert_on_non_leaf_level(
/*=========================*/
- dict_tree_t* tree, /* in: tree */
+ dict_index_t* index, /* in: index */
ulint level, /* in: level, must be > 0 */
dtuple_t* tuple, /* in: the record to be inserted */
mtr_t* mtr); /* in: mtr */
@@ -274,7 +274,7 @@ Deletes on the upper level the node pointer to a page. */
void
btr_node_ptr_delete(
/*================*/
- dict_tree_t* tree, /* in: index tree */
+ dict_index_t* index, /* in: index tree */
page_t* page, /* in: page whose node pointer is deleted */
mtr_t* mtr); /* in: mtr */
#ifdef UNIV_DEBUG
@@ -285,7 +285,7 @@ ibool
btr_check_node_ptr(
/*===============*/
/* out: TRUE */
- dict_tree_t* tree, /* in: index tree */
+ dict_index_t* index, /* in: index tree */
page_t* page, /* in: index page */
mtr_t* mtr); /* in: mtr */
#endif /* UNIV_DEBUG */
@@ -361,7 +361,7 @@ btr_page_alloc(
/*===========*/
/* out: new allocated page, x-latched;
NULL if out of space */
- dict_tree_t* tree, /* in: index tree */
+ dict_index_t* index, /* in: index tree */
ulint hint_page_no, /* in: hint of a good page */
byte file_direction, /* in: direction where a possible
page split is made */
@@ -375,7 +375,7 @@ storage pages because the page must contain info on its level. */
void
btr_page_free(
/*==========*/
- dict_tree_t* tree, /* in: index tree */
+ dict_index_t* index, /* in: index tree */
page_t* page, /* in: page to be freed, x-latched */
mtr_t* mtr); /* in: mtr */
/******************************************************************
@@ -386,7 +386,7 @@ argument. */
void
btr_page_free_low(
/*==============*/
- dict_tree_t* tree, /* in: index tree */
+ dict_index_t* index, /* in: index tree */
page_t* page, /* in: page to be freed, x-latched */
ulint level, /* in: page level */
mtr_t* mtr); /* in: mtr */
@@ -397,14 +397,14 @@ Prints size info of a B-tree. */
void
btr_print_size(
/*===========*/
- dict_tree_t* tree); /* in: index tree */
+ dict_index_t* index); /* in: index tree */
/******************************************************************
-Prints directories and other info of all nodes in the tree. */
+Prints directories and other info of all nodes in the index. */
void
-btr_print_tree(
-/*===========*/
- dict_tree_t* tree, /* in: tree */
+btr_print_index(
+/*============*/
+ dict_index_t* index, /* in: index */
ulint width); /* in: print this many entries from start
and end */
#endif /* UNIV_BTR_PRINT */
@@ -425,10 +425,10 @@ btr_index_rec_validate(
Checks the consistency of an index tree. */
ibool
-btr_validate_tree(
-/*==============*/
+btr_validate_index(
+/*===============*/
/* out: TRUE if ok */
- dict_tree_t* tree, /* in: tree */
+ dict_index_t* index, /* in: index */
trx_t* trx); /* in: transaction or NULL */
#define BTR_N_LEAF_PAGES 1
diff --git a/storage/innobase/include/btr0btr.ic b/storage/innobase/include/btr0btr.ic
index 1f39b52f3c8..4a88f58b318 100644
--- a/storage/innobase/include/btr0btr.ic
+++ b/storage/innobase/include/btr0btr.ic
@@ -204,7 +204,7 @@ btr_node_ptr_get_child_page_no(
fprintf(stderr,
"InnoDB: a nonsensical page number 0"
" in a node ptr record at offset %lu\n",
- (ulong) ut_align_offset(rec, UNIV_PAGE_SIZE));
+ (ulong) page_offset(rec));
buf_page_print(buf_frame_align(rec));
}
diff --git a/storage/innobase/include/btr0cur.h b/storage/innobase/include/btr0cur.h
index 1d41a345699..213dcb7f568 100644
--- a/storage/innobase/include/btr0cur.h
+++ b/storage/innobase/include/btr0cur.h
@@ -59,13 +59,13 @@ btr_cur_get_page(
/* out: pointer to page */
btr_cur_t* cursor);/* in: tree cursor */
/*************************************************************
-Returns the tree of a cursor. */
+Returns the index of a cursor. */
UNIV_INLINE
-dict_tree_t*
-btr_cur_get_tree(
-/*=============*/
- /* out: tree */
- btr_cur_t* cursor);/* in: tree cursor */
+dict_index_t*
+btr_cur_get_index(
+/*==============*/
+ /* out: index */
+ btr_cur_t* cursor);/* in: B-tree cursor */
/*************************************************************
Positions a tree cursor at a given record. */
UNIV_INLINE
diff --git a/storage/innobase/include/btr0cur.ic b/storage/innobase/include/btr0cur.ic
index 76a4ff938a2..bd2c46eb734 100644
--- a/storage/innobase/include/btr0cur.ic
+++ b/storage/innobase/include/btr0cur.ic
@@ -56,15 +56,15 @@ btr_cur_get_page(
}
/*************************************************************
-Returns the tree of a cursor. */
+Returns the index of a cursor. */
UNIV_INLINE
-dict_tree_t*
-btr_cur_get_tree(
-/*=============*/
- /* out: tree */
- btr_cur_t* cursor) /* in: tree cursor */
+dict_index_t*
+btr_cur_get_index(
+/*==============*/
+ /* out: index */
+ btr_cur_t* cursor) /* in: B-tree cursor */
{
- return((cursor->index)->tree);
+ return(cursor->index);
}
/*************************************************************
@@ -109,15 +109,8 @@ btr_cur_compress_recommendation(
one page: we recommend compression if this is not the
root page. */
- if (dict_tree_get_page((cursor->index)->tree)
- == buf_frame_get_page_no(page)) {
-
- /* It is the root page */
-
- return(FALSE);
- }
-
- return(TRUE);
+ return(dict_index_get_page(cursor->index)
+ != buf_frame_get_page_no(page));
}
return(FALSE);
@@ -153,15 +146,8 @@ btr_cur_can_delete_without_compress(
one page, OR the page will become empty: we recommend
compression if this is not the root page. */
- if (dict_tree_get_page((cursor->index)->tree)
- == buf_frame_get_page_no(page)) {
-
- /* It is the root page */
-
- return(TRUE);
- }
-
- return(FALSE);
+ return(dict_index_get_page(cursor->index)
+ == buf_frame_get_page_no(page));
}
return(TRUE);
diff --git a/storage/innobase/include/btr0pcur.h b/storage/innobase/include/btr0pcur.h
index 0276fe45922..ee40e905544 100644
--- a/storage/innobase/include/btr0pcur.h
+++ b/storage/innobase/include/btr0pcur.h
@@ -445,7 +445,7 @@ selects, updates, and deletes. */
struct btr_pcur_struct{
btr_cur_t btr_cur; /* a B-tree cursor */
- ulint latch_mode; /* see FIXME note below!
+ ulint latch_mode; /* see TODO note below!
BTR_SEARCH_LEAF, BTR_MODIFY_LEAF,
BTR_MODIFY_TREE, or BTR_NO_LATCHES,
depending on the latching state of
@@ -473,7 +473,7 @@ struct btr_pcur_struct{
dulint modify_clock; /* the modify clock value of the
buffer block when the cursor position
was stored */
- ulint pos_state; /* see FIXME note below!
+ ulint pos_state; /* see TODO note below!
BTR_PCUR_IS_POSITIONED,
BTR_PCUR_WAS_POSITIONED,
BTR_PCUR_NOT_POSITIONED */
@@ -495,14 +495,18 @@ struct btr_pcur_struct{
is not NULL */
};
-#define BTR_PCUR_IS_POSITIONED 1997660512 /* FIXME: currently, the state
+#define BTR_PCUR_IS_POSITIONED 1997660512 /* TODO: currently, the state
can be BTR_PCUR_IS_POSITIONED,
though it really should be
BTR_PCUR_WAS_POSITIONED,
because we have no obligation
to commit the cursor with
mtr; similarly latch_mode may
- be out of date */
+ be out of date. This can
+ lead to problems if btr_pcur
+ is not used the right way;
+ all current code should be
+ ok. */
#define BTR_PCUR_WAS_POSITIONED 1187549791
#define BTR_PCUR_NOT_POSITIONED 1328997689
diff --git a/storage/innobase/include/btr0sea.h b/storage/innobase/include/btr0sea.h
index 62b1d2db559..8b4408ef852 100644
--- a/storage/innobase/include/btr0sea.h
+++ b/storage/innobase/include/btr0sea.h
@@ -134,48 +134,34 @@ btr_search_validate(void);
/*======================*/
/* out: TRUE if ok */
-/* Search info directions */
-#define BTR_SEA_NO_DIRECTION 1
-#define BTR_SEA_LEFT 2
-#define BTR_SEA_RIGHT 3
-#define BTR_SEA_SAME_REC 4
-
/* The search info struct in an index */
struct btr_search_struct{
- ulint magic_n; /* magic number */
- /* The following 4 fields are currently not used: */
- rec_t* last_search; /* pointer to the lower limit record of the
- previous search; NULL if not known */
- ulint n_direction; /* number of consecutive searches in the
- same direction */
- ulint direction; /* BTR_SEA_NO_DIRECTION, BTR_SEA_LEFT,
- BTR_SEA_RIGHT, BTR_SEA_SAME_REC,
- or BTR_SEA_SAME_PAGE */
- dulint modify_clock; /* value of modify clock at the time
- last_search was stored */
- /*----------------------*/
- /* The following 4 fields are not protected by any latch: */
+ /* The following fields are not protected by any latch.
+ Unfortunately, this means that they must be aligned to
+ the machine word, i.e., they cannot be turned into bit-fields. */
page_t* root_guess; /* the root page frame when it was last time
fetched, or NULL */
- ulint hash_analysis; /* when this exceeds a certain value, the
- hash analysis starts; this is reset if no
+ ulint hash_analysis; /* when this exceeds BTR_SEARCH_HASH_ANALYSIS,
+ the hash analysis starts; this is reset if no
success noticed */
ibool last_hash_succ; /* TRUE if the last search would have
succeeded, or did succeed, using the hash
index; NOTE that the value here is not exact:
it is not calculated for every search, and the
calculation itself is not always accurate! */
- ulint n_hash_potential;/* number of consecutive searches which would
- have succeeded, or did succeed, using the hash
- index */
+ ulint n_hash_potential;
+ /* number of consecutive searches
+ which would have succeeded, or did succeed,
+ using the hash index;
+ the range is 0 .. BTR_SEARCH_BUILD_LIMIT + 5 */
/*----------------------*/
ulint n_fields; /* recommended prefix length for hash search:
number of full fields */
ulint n_bytes; /* recommended prefix: number of bytes in
- an incomplete field */
- ulint side; /* BTR_SEARCH_LEFT_SIDE or
- BTR_SEARCH_RIGHT_SIDE, depending on whether
+ an incomplete field;
+ cf. BTR_PAGE_MAX_REC_SIZE */
+ ibool left_side; /* TRUE or FALSE, depending on whether
the leftmost record of several records with
the same prefix should be indexed in the
hash index */
@@ -188,10 +174,12 @@ struct btr_search_struct{
far */
ulint n_searches; /* number of searches */
#endif /* UNIV_SEARCH_PERF_STAT */
+#ifdef UNIV_DEBUG
+ ulint magic_n; /* magic number */
+# define BTR_SEARCH_MAGIC_N 1112765
+#endif /* UNIV_DEBUG */
};
-#define BTR_SEARCH_MAGIC_N 1112765
-
/* The hash index system */
typedef struct btr_search_sys_struct btr_search_sys_t;
@@ -229,9 +217,6 @@ is no hope in building a hash index. */
#define BTR_SEARCH_HASH_ANALYSIS 17
-#define BTR_SEARCH_LEFT_SIDE 1
-#define BTR_SEARCH_RIGHT_SIDE 2
-
/* Limit of consecutive searches for trying a search shortcut on the search
pattern */
diff --git a/storage/innobase/include/buf0buf.h b/storage/innobase/include/buf0buf.h
index 110ef36a296..2fc6bf4bcb9 100644
--- a/storage/innobase/include/buf0buf.h
+++ b/storage/innobase/include/buf0buf.h
@@ -825,8 +825,7 @@ struct buf_block_struct{
search: number of full fields */
ulint n_bytes; /* recommended prefix: number of bytes
in an incomplete field */
- ulint side; /* BTR_SEARCH_LEFT_SIDE or
- BTR_SEARCH_RIGHT_SIDE, depending on
+ ibool left_side; /* TRUE or FALSE, depending on
whether the leftmost record of several
records with the same prefix should be
indexed in the hash index */
@@ -851,9 +850,7 @@ struct buf_block_struct{
ulint curr_n_fields; /* prefix length for hash indexing:
number of full fields */
ulint curr_n_bytes; /* number of bytes in hash indexing */
- ulint curr_side; /* BTR_SEARCH_LEFT_SIDE or
- BTR_SEARCH_RIGHT_SIDE in hash
- indexing */
+ ibool curr_left_side; /* TRUE or FALSE in hash indexing */
dict_index_t* index; /* Index for which the adaptive
hash index has been created. */
/* 6. Debug fields */
diff --git a/storage/innobase/include/data0data.ic b/storage/innobase/include/data0data.ic
index 77fce029851..753fa9ba45f 100644
--- a/storage/innobase/include/data0data.ic
+++ b/storage/innobase/include/data0data.ic
@@ -334,7 +334,7 @@ dtuple_set_types_binary(
for (i = 0; i < n; i++) {
dfield_type = dfield_get_type(dtuple_get_nth_field(tuple, i));
- dtype_set(dfield_type, DATA_BINARY, 0, 0, 0);
+ dtype_set(dfield_type, DATA_BINARY, 0, 0);
}
}
diff --git a/storage/innobase/include/data0type.h b/storage/innobase/include/data0type.h
index 7a9456637d6..e5e9c5076be 100644
--- a/storage/innobase/include/data0type.h
+++ b/storage/innobase/include/data0type.h
@@ -18,10 +18,6 @@ extern ulint data_mysql_default_charset_coll;
/* SQL data type struct */
typedef struct dtype_struct dtype_t;
-/* This variable is initialized as the standard binary variable length
-data type */
-extern dtype_t* dtype_binary;
-
/*-------------------------------------------*/
/* The 'MAIN TYPE' of a column */
#define DATA_VARCHAR 1 /* character varying of the
@@ -124,11 +120,7 @@ be less than 256 */
#define DATA_ROLL_PTR 2 /* rollback data pointer: 7 bytes */
#define DATA_ROLL_PTR_LEN 7
-#define DATA_MIX_ID 3 /* mixed index label: a dulint, stored in
- a row in a compressed form */
-#define DATA_MIX_ID_LEN 9 /* maximum stored length for mix id (in a
- compressed dulint form) */
-#define DATA_N_SYS_COLS 4 /* number of system columns defined above */
+#define DATA_N_SYS_COLS 3 /* number of system columns defined above */
/* Flags ORed to the precise data type */
#define DATA_NOT_NULL 256 /* this is ORed to the precise type when
@@ -176,7 +168,11 @@ dtype_get_at_most_n_mbchars(
/*========================*/
/* out: length of the prefix,
in bytes */
- const dtype_t* dtype, /* in: data type */
+ ulint prtype, /* in: precise type */
+ ulint mbminlen, /* in: minimum length of a
+ multi-byte character */
+ ulint mbmaxlen, /* in: maximum length of a
+ multi-byte character */
ulint prefix_len, /* in: length of the requested
prefix, in characters, multiplied by
dtype_get_mbmaxlen(dtype) */
@@ -224,8 +220,7 @@ dtype_set(
dtype_t* type, /* in: type struct to init */
ulint mtype, /* in: main data type */
ulint prtype, /* in: precise type */
- ulint len, /* in: length of type */
- ulint prec); /* in: precision of type */
+ ulint len); /* in: precision of type */
/*************************************************************************
Copies a data type structure. */
UNIV_INLINE
@@ -233,7 +228,7 @@ void
dtype_copy(
/*=======*/
dtype_t* type1, /* in: type struct to copy to */
- dtype_t* type2); /* in: type struct to copy from */
+ const dtype_t* type2); /* in: type struct to copy from */
/*************************************************************************
Gets the SQL main data type. */
UNIV_INLINE
@@ -249,6 +244,18 @@ dtype_get_prtype(
/*=============*/
dtype_t* type);
/*************************************************************************
+Compute the mbminlen and mbmaxlen members of a data type structure. */
+UNIV_INLINE
+void
+dtype_get_mblen(
+/*============*/
+ ulint mtype, /* in: main type */
+ ulint prtype, /* in: precise type (and collation) */
+ ulint* mbminlen, /* out: minimum length of a
+ multi-byte character */
+ ulint* mbmaxlen); /* out: maximum length of a
+ multi-byte character */
+/*************************************************************************
Gets the MySQL charset-collation code for MySQL string types. */
ulint
@@ -280,13 +287,6 @@ dtype_get_len(
/*==========*/
dtype_t* type);
/*************************************************************************
-Gets the type precision. */
-UNIV_INLINE
-ulint
-dtype_get_prec(
-/*===========*/
- dtype_t* type);
-/*************************************************************************
Gets the minimum length of a character, in bytes. */
UNIV_INLINE
ulint
@@ -312,50 +312,52 @@ dtype_get_pad_char(
/*===============*/
/* out: padding character code, or
ULINT_UNDEFINED if no padding specified */
- const dtype_t* type); /* in: type */
+ ulint mtype, /* in: main type */
+ ulint prtype); /* in: precise type */
/***************************************************************************
Returns the size of a fixed size data type, 0 if not a fixed size type. */
UNIV_INLINE
ulint
-dtype_get_fixed_size(
-/*=================*/
+dtype_get_fixed_size_low(
+/*=====================*/
/* out: fixed size, or 0 */
- dtype_t* type); /* in: type */
+ ulint mtype, /* in: main type */
+ ulint prtype, /* in: precise type */
+ ulint len, /* in: length */
+ ulint mbminlen, /* in: minimum length of a multibyte char */
+ ulint mbmaxlen); /* in: maximum length of a multibyte char */
/***************************************************************************
Returns the minimum size of a data type. */
UNIV_INLINE
ulint
-dtype_get_min_size(
-/*===============*/
+dtype_get_min_size_low(
+/*===================*/
/* out: minimum size */
- const dtype_t* type); /* in: type */
+ ulint mtype, /* in: main type */
+ ulint prtype, /* in: precise type */
+ ulint len, /* in: length */
+ ulint mbminlen, /* in: minimum length of a multibyte char */
+ ulint mbmaxlen); /* in: maximum length of a multibyte char */
/***************************************************************************
Returns the maximum size of a data type. Note: types in system tables may be
incomplete and return incorrect information. */
-
+UNIV_INLINE
ulint
-dtype_get_max_size(
-/*===============*/
- /* out: maximum size (ULINT_MAX for
- unbounded types) */
- const dtype_t* type); /* in: type */
+dtype_get_max_size_low(
+/*===================*/
+ /* out: maximum size */
+ ulint mtype, /* in: main type */
+ ulint len); /* in: length */
/***************************************************************************
-Returns a stored SQL NULL size for a type. For fixed length types it is
-the fixed length of the type, otherwise 0. */
+Returns the ROW_FORMAT=REDUNDANT stored SQL NULL size of a type.
+For fixed length types it is the fixed length of the type, otherwise 0. */
UNIV_INLINE
ulint
dtype_get_sql_null_size(
/*====================*/
- /* out: SQL null storage size */
- dtype_t* type); /* in: type */
-/***************************************************************************
-Returns TRUE if a type is of a fixed size. */
-UNIV_INLINE
-ibool
-dtype_is_fixed_size(
-/*================*/
- /* out: TRUE if fixed size */
- dtype_t* type); /* in: type */
+ /* out: SQL null storage size
+ in ROW_FORMAT=REDUNDANT */
+ const dtype_t* type); /* in: type */
/**************************************************************************
Reads to a type the stored information which determines its alphabetical
ordering and the storage size of an SQL NULL value. */
@@ -376,7 +378,9 @@ dtype_new_store_for_order_and_null_size(
byte* buf, /* in: buffer for
DATA_NEW_ORDER_NULL_TYPE_BUF_SIZE
bytes where we store the info */
- dtype_t* type); /* in: type struct */
+ dtype_t* type, /* in: type struct */
+ ulint prefix_len);/* in: prefix length to
+ replace type->len, or 0 */
/**************************************************************************
Reads to a type the stored information which determines its alphabetical
ordering and the storage size of an SQL NULL value. This is the 4.1.x storage
@@ -413,25 +417,30 @@ dtype_new_read_for_order_and_null_size()
sym_tab_add_null_lit() */
struct dtype_struct{
- ulint mtype; /* main data type */
- ulint prtype; /* precise type; MySQL data type, charset code,
- flags to indicate nullability, signedness,
- whether this is a binary string, whether this
- is a true VARCHAR where MySQL uses 2 bytes to
- store the length */
+ unsigned mtype:8; /* main data type */
+ unsigned prtype:24; /* precise type; MySQL data
+ type, charset code, flags to
+ indicate nullability,
+ signedness, whether this is a
+ binary string, whether this is
+ a true VARCHAR where MySQL
+ uses 2 bytes to store the length */
/* the remaining fields do not affect alphabetical ordering: */
- ulint len; /* length; for MySQL data this is
- field->pack_length(), except that for a
- >= 5.0.3 type true VARCHAR this is the
- maximum byte length of the string data
- (in addition to the string, MySQL uses 1 or
- 2 bytes to store the string length) */
- ulint prec; /* precision */
-
- ulint mbminlen; /* minimum length of a character, in bytes */
- ulint mbmaxlen; /* maximum length of a character, in bytes */
+ unsigned len:16; /* length; for MySQL data this
+ is field->pack_length(),
+ except that for a >= 5.0.3
+ type true VARCHAR this is the
+ maximum byte length of the
+ string data (in addition to
+ the string, MySQL uses 1 or 2
+ bytes to store the string length) */
+
+ unsigned mbminlen:2; /* minimum length of a
+ character, in bytes */
+ unsigned mbmaxlen:3; /* maximum length of a
+ character, in bytes */
};
#ifndef UNIV_NONINL
diff --git a/storage/innobase/include/data0type.ic b/storage/innobase/include/data0type.ic
index d2027592c09..b447c9c39c2 100644
--- a/storage/innobase/include/data0type.ic
+++ b/storage/innobase/include/data0type.ic
@@ -48,36 +48,53 @@ dtype_get_mysql_type(
}
/*************************************************************************
-Sets the mbminlen and mbmaxlen members of a data type structure. */
+Compute the mbminlen and mbmaxlen members of a data type structure. */
UNIV_INLINE
void
-dtype_set_mblen(
+dtype_get_mblen(
/*============*/
- dtype_t* type) /* in/out: type struct */
+ ulint mtype, /* in: main type */
+ ulint prtype, /* in: precise type (and collation) */
+ ulint* mbminlen, /* out: minimum length of a
+ multi-byte character */
+ ulint* mbmaxlen) /* out: maximum length of a
+ multi-byte character */
{
- ut_ad(type);
- if (dtype_is_string_type(type->mtype)) {
+ if (dtype_is_string_type(mtype)) {
#ifndef UNIV_HOTBACKUP
- innobase_get_cset_width(dtype_get_charset_coll(type->prtype),
- &type->mbminlen, &type->mbmaxlen);
- ut_ad(type->mbminlen <= type->mbmaxlen);
+ innobase_get_cset_width(dtype_get_charset_coll(prtype),
+ mbminlen, mbmaxlen);
+ ut_ad(*mbminlen <= *mbmaxlen);
+ ut_ad(*mbminlen <= 2); /* cf. the bit-field in dtype_t */
+ ut_ad(*mbmaxlen < 1 << 3); /* cf. the bit-field in dtype_t */
#else /* !UNIV_HOTBACKUP */
-#ifdef notdefined
- printf("ibbackup: DEBUG: type->mtype=%lu, type->prtype=%lu\n",
- type->mtype, type->prtype);
-#endif
- ut_a(type->mtype <= DATA_BINARY);
-#ifdef notdefined
- ut_a(type->prtype == (DATA_BINARY | DATA_NOT_NULL));
-#endif
- type->mbminlen = type->mbmaxlen = 1;
+ ut_a(mtype <= DATA_BINARY);
+ *mbminlen = *mbmaxlen = 1;
#endif /* !UNIV_HOTBACKUP */
} else {
- type->mbminlen = type->mbmaxlen = 0;
+ *mbminlen = *mbmaxlen = 0;
}
}
/*************************************************************************
+Compute the mbminlen and mbmaxlen members of a data type structure. */
+UNIV_INLINE
+void
+dtype_set_mblen(
+/*============*/
+ dtype_t* type) /* in/out: type */
+{
+ ulint mbminlen;
+ ulint mbmaxlen;
+
+ dtype_get_mblen(type->mtype, type->prtype, &mbminlen, &mbmaxlen);
+ type->mbminlen = mbminlen;
+ type->mbmaxlen = mbmaxlen;
+
+ ut_ad(dtype_validate(type));
+}
+
+/*************************************************************************
Sets a data type structure. */
UNIV_INLINE
void
@@ -86,8 +103,7 @@ dtype_set(
dtype_t* type, /* in: type struct to init */
ulint mtype, /* in: main data type */
ulint prtype, /* in: precise type */
- ulint len, /* in: length of type */
- ulint prec) /* in: precision of type */
+ ulint len) /* in: precision of type */
{
ut_ad(type);
ut_ad(mtype <= DATA_MTYPE_MAX);
@@ -95,10 +111,8 @@ dtype_set(
type->mtype = mtype;
type->prtype = prtype;
type->len = len;
- type->prec = prec;
dtype_set_mblen(type);
- ut_ad(dtype_validate(type));
}
/*************************************************************************
@@ -108,7 +122,7 @@ void
dtype_copy(
/*=======*/
dtype_t* type1, /* in: type struct to copy to */
- dtype_t* type2) /* in: type struct to copy from */
+ const dtype_t* type2) /* in: type struct to copy from */
{
*type1 = *type2;
@@ -155,19 +169,6 @@ dtype_get_len(
}
/*************************************************************************
-Gets the type precision. */
-UNIV_INLINE
-ulint
-dtype_get_prec(
-/*===========*/
- dtype_t* type)
-{
- ut_ad(type);
-
- return(type->prec);
-}
-
-/*************************************************************************
Gets the minimum length of a character, in bytes. */
UNIV_INLINE
ulint
@@ -195,19 +196,20 @@ dtype_get_mbmaxlen(
}
/*************************************************************************
-Gets the padding character code for the type. */
+Gets the padding character code for a type. */
UNIV_INLINE
ulint
dtype_get_pad_char(
/*===============*/
/* out: padding character code, or
ULINT_UNDEFINED if no padding specified */
- const dtype_t* type) /* in: type */
+ ulint mtype, /* in: main type */
+ ulint prtype) /* in: precise type */
{
- switch (type->mtype) {
+ switch (mtype) {
case DATA_FIXBINARY:
case DATA_BINARY:
- if (UNIV_UNLIKELY(dtype_get_charset_coll(type->prtype)
+ if (UNIV_UNLIKELY(dtype_get_charset_coll(prtype)
== DATA_MYSQL_BINARY_CHARSET_COLL)) {
/* Starting from 5.0.18, do not pad
VARBINARY or BINARY columns. */
@@ -223,7 +225,7 @@ dtype_get_pad_char(
return(0x20);
case DATA_BLOB:
- if ((type->prtype & DATA_BINARY_TYPE) == 0) {
+ if (!(prtype & DATA_BINARY_TYPE)) {
return(0x20);
}
/* Fall through */
@@ -244,11 +246,14 @@ dtype_new_store_for_order_and_null_size(
byte* buf, /* in: buffer for
DATA_NEW_ORDER_NULL_TYPE_BUF_SIZE
bytes where we store the info */
- dtype_t* type) /* in: type struct */
+ dtype_t* type, /* in: type struct */
+ ulint prefix_len)/* in: prefix length to
+ replace type->len, or 0 */
{
#if 6 != DATA_NEW_ORDER_NULL_TYPE_BUF_SIZE
#error "6 != DATA_NEW_ORDER_NULL_TYPE_BUF_SIZE"
#endif
+ ulint len;
buf[0] = (byte)(type->mtype & 0xFFUL);
@@ -263,7 +268,9 @@ dtype_new_store_for_order_and_null_size(
buf[1] = (byte)(type->prtype & 0xFFUL);
- mach_write_to_2(buf + 2, type->len & 0xFFFFUL);
+ len = prefix_len ? prefix_len : type->len;
+
+ mach_write_to_2(buf + 2, len & 0xFFFFUL);
ut_ad(dtype_get_charset_coll(type->prtype) < 256);
mach_write_to_2(buf + 4, dtype_get_charset_coll(type->prtype));
@@ -284,7 +291,9 @@ dtype_read_for_order_and_null_size(
dtype_t* type, /* in: type struct */
byte* buf) /* in: buffer for stored type order info */
{
- ut_ad(4 == DATA_ORDER_NULL_TYPE_BUF_SIZE);
+#if 4 != DATA_ORDER_NULL_TYPE_BUF_SIZE
+# error "4 != DATA_ORDER_NULL_TYPE_BUF_SIZE"
+#endif
type->mtype = buf[0] & 63;
type->prtype = buf[1];
@@ -356,34 +365,31 @@ dtype_new_read_for_order_and_null_size(
Returns the size of a fixed size data type, 0 if not a fixed size type. */
UNIV_INLINE
ulint
-dtype_get_fixed_size(
-/*=================*/
+dtype_get_fixed_size_low(
+/*=====================*/
/* out: fixed size, or 0 */
- dtype_t* type) /* in: type */
+ ulint mtype, /* in: main type */
+ ulint prtype, /* in: precise type */
+ ulint len, /* in: length */
+ ulint mbminlen, /* in: minimum length of a multibyte char */
+ ulint mbmaxlen) /* in: maximum length of a multibyte char */
{
- ulint mtype;
-
- mtype = dtype_get_mtype(type);
-
switch (mtype) {
case DATA_SYS:
#ifdef UNIV_DEBUG
- switch (type->prtype & DATA_MYSQL_TYPE_MASK) {
- default:
- ut_ad(0);
- return(0);
+ switch (prtype & DATA_MYSQL_TYPE_MASK) {
case DATA_ROW_ID:
- ut_ad(type->len == DATA_ROW_ID_LEN);
+ ut_ad(len == DATA_ROW_ID_LEN);
break;
case DATA_TRX_ID:
- ut_ad(type->len == DATA_TRX_ID_LEN);
+ ut_ad(len == DATA_TRX_ID_LEN);
break;
case DATA_ROLL_PTR:
- ut_ad(type->len == DATA_ROLL_PTR_LEN);
- break;
- case DATA_MIX_ID:
- ut_ad(type->len == DATA_MIX_ID_LEN);
+ ut_ad(len == DATA_ROLL_PTR_LEN);
break;
+ default:
+ ut_ad(0);
+ return(0);
}
#endif /* UNIV_DEBUG */
case DATA_CHAR:
@@ -391,32 +397,32 @@ dtype_get_fixed_size(
case DATA_INT:
case DATA_FLOAT:
case DATA_DOUBLE:
- return(dtype_get_len(type));
+ return(len);
case DATA_MYSQL:
- if (type->prtype & DATA_BINARY_TYPE) {
- return(dtype_get_len(type));
+ if (prtype & DATA_BINARY_TYPE) {
+ return(len);
} else {
#ifdef UNIV_HOTBACKUP
- if (type->mbminlen == type->mbmaxlen) {
- return(dtype_get_len(type));
+ if (mbminlen == mbmaxlen) {
+ return(len);
}
#else /* UNIV_HOTBACKUP */
/* We play it safe here and ask MySQL for
mbminlen and mbmaxlen. Although
- type->mbminlen and type->mbmaxlen are
- initialized if and only if type->prtype
+ mbminlen and mbmaxlen are
+ initialized if and only if prtype
is (in one of the 3 functions in this file),
it could be that none of these functions
has been called. */
- ulint mbminlen, mbmaxlen;
+ ulint i_mbminlen, i_mbmaxlen;
- innobase_get_cset_width
- (dtype_get_charset_coll(type->prtype),
- &mbminlen, &mbmaxlen);
+ innobase_get_cset_width(
+ dtype_get_charset_coll(prtype),
+ &i_mbminlen, &i_mbmaxlen);
- if (UNIV_UNLIKELY(type->mbminlen != mbminlen)
- || UNIV_UNLIKELY(type->mbmaxlen != mbmaxlen)) {
+ if (UNIV_UNLIKELY(mbminlen != i_mbminlen)
+ || UNIV_UNLIKELY(mbmaxlen != i_mbmaxlen)) {
ut_print_timestamp(stderr);
fprintf(stderr, " InnoDB: "
@@ -424,13 +430,13 @@ dtype_get_fixed_size(
"mbmaxlen=%lu, "
"type->mbminlen=%lu, "
"type->mbmaxlen=%lu\n",
+ (ulong) i_mbminlen,
+ (ulong) i_mbmaxlen,
(ulong) mbminlen,
- (ulong) mbmaxlen,
- (ulong) type->mbminlen,
- (ulong) type->mbmaxlen);
+ (ulong) mbmaxlen);
}
if (mbminlen == mbmaxlen) {
- return(dtype_get_len(type));
+ return(len);
}
#endif /* !UNIV_HOTBACKUP */
}
@@ -452,30 +458,31 @@ dtype_get_fixed_size(
Returns the minimum size of a data type. */
UNIV_INLINE
ulint
-dtype_get_min_size(
-/*===============*/
+dtype_get_min_size_low(
+/*===================*/
/* out: minimum size */
- const dtype_t* type) /* in: type */
+ ulint mtype, /* in: main type */
+ ulint prtype, /* in: precise type */
+ ulint len, /* in: length */
+ ulint mbminlen, /* in: minimum length of a multibyte char */
+ ulint mbmaxlen) /* in: maximum length of a multibyte char */
{
- switch (type->mtype) {
+ switch (mtype) {
case DATA_SYS:
#ifdef UNIV_DEBUG
- switch (type->prtype & DATA_MYSQL_TYPE_MASK) {
- default:
- ut_ad(0);
- return(0);
+ switch (prtype & DATA_MYSQL_TYPE_MASK) {
case DATA_ROW_ID:
- ut_ad(type->len == DATA_ROW_ID_LEN);
+ ut_ad(len == DATA_ROW_ID_LEN);
break;
case DATA_TRX_ID:
- ut_ad(type->len == DATA_TRX_ID_LEN);
+ ut_ad(len == DATA_TRX_ID_LEN);
break;
case DATA_ROLL_PTR:
- ut_ad(type->len == DATA_ROLL_PTR_LEN);
- break;
- case DATA_MIX_ID:
- ut_ad(type->len == DATA_MIX_ID_LEN);
+ ut_ad(len == DATA_ROLL_PTR_LEN);
break;
+ default:
+ ut_ad(0);
+ return(0);
}
#endif /* UNIV_DEBUG */
case DATA_CHAR:
@@ -483,58 +490,73 @@ dtype_get_min_size(
case DATA_INT:
case DATA_FLOAT:
case DATA_DOUBLE:
- return(type->len);
+ return(len);
case DATA_MYSQL:
- if ((type->prtype & DATA_BINARY_TYPE)
- || type->mbminlen == type->mbmaxlen) {
- return(type->len);
+ if ((prtype & DATA_BINARY_TYPE) || mbminlen == mbmaxlen) {
+ return(len);
}
/* this is a variable-length character set */
- ut_a(type->mbminlen > 0);
- ut_a(type->mbmaxlen > type->mbminlen);
- ut_a(type->len % type->mbmaxlen == 0);
- return(type->len * type->mbminlen / type->mbmaxlen);
+ ut_a(mbminlen > 0);
+ ut_a(mbmaxlen > mbminlen);
+ ut_a(len % mbmaxlen == 0);
+ return(len * mbminlen / mbmaxlen);
case DATA_VARCHAR:
case DATA_BINARY:
case DATA_DECIMAL:
case DATA_VARMYSQL:
case DATA_BLOB:
return(0);
- default: ut_error;
+ default:
+ ut_error;
}
return(0);
}
/***************************************************************************
-Returns a stored SQL NULL size for a type. For fixed length types it is
-the fixed length of the type, otherwise 0. */
+Returns the maximum size of a data type. Note: types in system tables may be
+incomplete and return incorrect information. */
UNIV_INLINE
ulint
-dtype_get_sql_null_size(
-/*====================*/
- /* out: SQL null storage size */
- dtype_t* type) /* in: type */
+dtype_get_max_size_low(
+/*===================*/
+ /* out: maximum size */
+ ulint mtype, /* in: main type */
+ ulint len) /* in: length */
{
- return(dtype_get_fixed_size(type));
+ switch (mtype) {
+ case DATA_SYS:
+ case DATA_CHAR:
+ case DATA_FIXBINARY:
+ case DATA_INT:
+ case DATA_FLOAT:
+ case DATA_DOUBLE:
+ case DATA_MYSQL:
+ case DATA_VARCHAR:
+ case DATA_BINARY:
+ case DATA_DECIMAL:
+ case DATA_VARMYSQL:
+ return(len);
+ case DATA_BLOB:
+ break;
+ default:
+ ut_error;
+ }
+
+ return(ULINT_MAX);
}
/***************************************************************************
-Returns TRUE if a type is of a fixed size. */
+Returns the ROW_FORMAT=REDUNDANT stored SQL NULL size of a type.
+For fixed length types it is the fixed length of the type, otherwise 0. */
UNIV_INLINE
-ibool
-dtype_is_fixed_size(
-/*================*/
- /* out: TRUE if fixed size */
- dtype_t* type) /* in: type */
+ulint
+dtype_get_sql_null_size(
+/*====================*/
+ /* out: SQL null storage size
+ in ROW_FORMAT=REDUNDANT */
+ const dtype_t* type) /* in: type */
{
- ulint size;
-
- size = dtype_get_fixed_size(type);
-
- if (size) {
- return(TRUE);
- }
-
- return(FALSE);
+ return(dtype_get_fixed_size_low(type->mtype, type->prtype, type->len,
+ type->mbminlen, type->mbmaxlen) > 0);
}
diff --git a/storage/innobase/include/dict0boot.h b/storage/innobase/include/dict0boot.h
index 41ce0ac059a..cac79410b24 100644
--- a/storage/innobase/include/dict0boot.h
+++ b/storage/innobase/include/dict0boot.h
@@ -103,7 +103,7 @@ dict_create(void);
#define DICT_HDR_ROW_ID 0 /* The latest assigned row id */
#define DICT_HDR_TABLE_ID 8 /* The latest assigned table id */
#define DICT_HDR_INDEX_ID 16 /* The latest assigned index id */
-#define DICT_HDR_MIX_ID 24 /* The latest assigned mix id */
+#define DICT_HDR_MIX_ID 24 /* Obsolete, always 0. */
#define DICT_HDR_TABLES 32 /* Root of the table index tree */
#define DICT_HDR_TABLE_IDS 36 /* Root of the table index tree */
#define DICT_HDR_COLUMNS 40 /* Root of the column index tree */
diff --git a/storage/innobase/include/dict0dict.h b/storage/innobase/include/dict0dict.h
index b30aebe5ff6..a9775ab3d40 100644
--- a/storage/innobase/include/dict0dict.h
+++ b/storage/innobase/include/dict0dict.h
@@ -79,24 +79,77 @@ dict_load_space_id_list(void);
/*************************************************************************
Gets the column data type. */
UNIV_INLINE
-dtype_t*
-dict_col_get_type(
-/*==============*/
- dict_col_t* col);
+void
+dict_col_copy_type(
+/*===============*/
+ const dict_col_t* col, /* in: column */
+ dtype_t* type); /* out: data type */
+/*************************************************************************
+Gets the column data type. */
+
+void
+dict_col_copy_type_noninline(
+/*=========================*/
+ const dict_col_t* col, /* in: column */
+ dtype_t* type); /* out: data type */
+/***************************************************************************
+Returns the minimum size of the column. */
+UNIV_INLINE
+ulint
+dict_col_get_min_size(
+/*==================*/
+ /* out: minimum size */
+ const dict_col_t* col); /* in: column */
+/***************************************************************************
+Returns the maximum size of the column. */
+UNIV_INLINE
+ulint
+dict_col_get_max_size(
+/*==================*/
+ /* out: maximum size */
+ const dict_col_t* col); /* in: column */
+/***************************************************************************
+Returns the size of a fixed size column, 0 if not a fixed size column. */
+UNIV_INLINE
+ulint
+dict_col_get_fixed_size(
+/*====================*/
+ /* out: fixed size, or 0 */
+ const dict_col_t* col); /* in: column */
+/***************************************************************************
+Returns the ROW_FORMAT=REDUNDANT stored SQL NULL size of a column.
+For fixed length types it is the fixed length of the type, otherwise 0. */
+UNIV_INLINE
+ulint
+dict_col_get_sql_null_size(
+/*=======================*/
+ /* out: SQL null storage size
+ in ROW_FORMAT=REDUNDANT */
+ const dict_col_t* col); /* in: column */
+
/*************************************************************************
Gets the column number. */
UNIV_INLINE
ulint
dict_col_get_no(
/*============*/
- dict_col_t* col);
+ const dict_col_t* col);
/*************************************************************************
Gets the column position in the clustered index. */
UNIV_INLINE
ulint
dict_col_get_clust_pos(
/*===================*/
- dict_col_t* col);
+ const dict_col_t* col, /* in: table column */
+ const dict_index_t* clust_index); /* in: clustered index */
+/*************************************************************************
+Gets the column position in the clustered index. */
+
+ulint
+dict_col_get_clust_pos_noninline(
+/*=============================*/
+ const dict_col_t* col, /* in: table column */
+ const dict_index_t* clust_index); /* in: clustered index */
/********************************************************************
If the given column name is reserved for InnoDB system columns, return
TRUE. */
@@ -354,6 +407,19 @@ dict_table_get_index_noninline(
dict_table_t* table, /* in: table */
const char* name); /* in: index name */
/**************************************************************************
+Returns a column's name. */
+
+const char*
+dict_table_get_col_name(
+/*====================*/
+ /* out: column name. NOTE: not
+ guaranteed to stay valid if table is
+ modified in any way (columns added,
+ etc.). */
+ const dict_table_t* table, /* in: table */
+ ulint col_nr);/* in: column number */
+
+/**************************************************************************
Prints a table definition. */
void
@@ -468,30 +534,30 @@ dict_table_get_n_cols(
/************************************************************************
Gets the nth column of a table. */
UNIV_INLINE
-dict_col_t*
+const dict_col_t*
dict_table_get_nth_col(
/*===================*/
- /* out: pointer to column object */
- dict_table_t* table, /* in: table */
- ulint pos); /* in: position of column */
+ /* out: pointer to column object */
+ const dict_table_t* table, /* in: table */
+ ulint pos); /* in: position of column */
/************************************************************************
Gets the nth column of a table. */
-dict_col_t*
+const dict_col_t*
dict_table_get_nth_col_noninline(
/*=============================*/
- /* out: pointer to column object */
- dict_table_t* table, /* in: table */
- ulint pos); /* in: position of column */
+ /* out: pointer to column object */
+ const dict_table_t* table, /* in: table */
+ ulint pos); /* in: position of column */
/************************************************************************
Gets the given system column of a table. */
UNIV_INLINE
-dict_col_t*
+const dict_col_t*
dict_table_get_sys_col(
/*===================*/
- /* out: pointer to column object */
- dict_table_t* table, /* in: table */
- ulint sys); /* in: DATA_ROW_ID, ... */
+ /* out: pointer to column object */
+ const dict_table_t* table, /* in: table */
+ ulint sys); /* in: DATA_ROW_ID, ... */
/************************************************************************
Gets the given system column number of a table. */
UNIV_INLINE
@@ -549,12 +615,11 @@ dict_index_find_on_id_low(
/* out: index or NULL if not found from cache */
dulint id); /* in: index id */
/**************************************************************************
-Adds an index to dictionary cache. */
+Adds an index to the dictionary cache. */
-ibool
+void
dict_index_add_to_cache(
/*====================*/
- /* out: TRUE if success */
dict_table_t* table, /* in: table on which the index is */
dict_index_t* index, /* in, own: index; NOTE! The index memory
object is freed in this function! */
@@ -614,23 +679,23 @@ dict_index_get_nth_field(
dict_index_t* index, /* in: index */
ulint pos); /* in: position of field */
/************************************************************************
-Gets pointer to the nth field data type in an index. */
+Gets pointer to the nth column in an index. */
UNIV_INLINE
-dtype_t*
-dict_index_get_nth_type(
-/*====================*/
- /* out: data type */
- dict_index_t* index, /* in: index */
- ulint pos); /* in: position of the field */
+const dict_col_t*
+dict_index_get_nth_col(
+/*===================*/
+ /* out: column */
+ const dict_index_t* index, /* in: index */
+ ulint pos); /* in: position of the field */
/************************************************************************
Gets the column number of the nth field in an index. */
UNIV_INLINE
ulint
dict_index_get_nth_col_no(
/*======================*/
- /* out: column number */
- dict_index_t* index, /* in: index */
- ulint pos); /* in: position of the field */
+ /* out: column number */
+ const dict_index_t* index, /* in: index */
+ ulint pos); /* in: position of the field */
/************************************************************************
Looks for column n in an index. */
@@ -694,6 +759,7 @@ void
dict_index_add_col(
/*===============*/
dict_index_t* index, /* in: index */
+ dict_table_t* table, /* in: table */
dict_col_t* col, /* in: column */
ulint prefix_len); /* in: column prefix length */
/***********************************************************************
@@ -706,38 +772,12 @@ dict_index_copy_types(
dict_index_t* index, /* in: index */
ulint n_fields); /* in: number of field types to copy */
/*************************************************************************
-Gets the index tree where the index is stored. */
-UNIV_INLINE
-dict_tree_t*
-dict_index_get_tree(
-/*================*/
- /* out: index tree */
- dict_index_t* index); /* in: index */
-/*************************************************************************
Gets the field column. */
UNIV_INLINE
-dict_col_t*
+const dict_col_t*
dict_field_get_col(
/*===============*/
- dict_field_t* field);
-/**************************************************************************
-Creates an index tree struct. */
-
-dict_tree_t*
-dict_tree_create(
-/*=============*/
- /* out, own: created tree */
- dict_index_t* index, /* in: the index for which to create: in the
- case of a mixed tree, this should be the
- index of the cluster object */
- ulint page_no);/* in: root page number of the index */
-/**************************************************************************
-Frees an index tree struct. */
-
-void
-dict_tree_free(
-/*===========*/
- dict_tree_t* tree); /* in, own: index tree */
+ const dict_field_t* field);
/**************************************************************************
In an index tree, finds the index corresponding to a record in the tree. */
@@ -755,20 +795,20 @@ Checks that a tuple has n_fields_cmp value in a sensible range, so that
no comparison can occur with the page number field in a node pointer. */
ibool
-dict_tree_check_search_tuple(
-/*=========================*/
+dict_index_check_search_tuple(
+/*==========================*/
/* out: TRUE if ok */
- dict_tree_t* tree, /* in: index tree */
+ dict_index_t* index, /* in: index */
dtuple_t* tuple); /* in: tuple used in a search */
#endif /* UNIV_DEBUG */
/**************************************************************************
Builds a node pointer out of a physical record and a page number. */
dtuple_t*
-dict_tree_build_node_ptr(
-/*=====================*/
+dict_index_build_node_ptr(
+/*======================*/
/* out, own: node pointer */
- dict_tree_t* tree, /* in: index tree */
+ dict_index_t* index, /* in: index */
rec_t* rec, /* in: record for which to build node
pointer */
ulint page_no,/* in: page number to put in node pointer */
@@ -780,10 +820,10 @@ Copies an initial segment of a physical record, long enough to specify an
index entry uniquely. */
rec_t*
-dict_tree_copy_rec_order_prefix(
-/*============================*/
+dict_index_copy_rec_order_prefix(
+/*=============================*/
/* out: pointer to the prefix record */
- dict_tree_t* tree, /* in: index tree */
+ dict_index_t* index, /* in: index */
rec_t* rec, /* in: record for which to copy prefix */
ulint* n_fields,/* out: number of fields copied */
byte** buf, /* in/out: memory buffer for the copied prefix,
@@ -793,10 +833,10 @@ dict_tree_copy_rec_order_prefix(
Builds a typed data tuple out of a physical record. */
dtuple_t*
-dict_tree_build_data_tuple(
-/*=======================*/
+dict_index_build_data_tuple(
+/*========================*/
/* out, own: data tuple */
- dict_tree_t* tree, /* in: index tree */
+ dict_index_t* index, /* in: index */
rec_t* rec, /* in: record for which to build data tuple */
ulint n_fields,/* in: number of data fields */
mem_heap_t* heap); /* in: memory heap where tuple created */
@@ -804,61 +844,60 @@ dict_tree_build_data_tuple(
Gets the space id of the root of the index tree. */
UNIV_INLINE
ulint
-dict_tree_get_space(
-/*================*/
+dict_index_get_space(
+/*=================*/
/* out: space id */
- dict_tree_t* tree); /* in: tree */
+ dict_index_t* index); /* in: index */
/*************************************************************************
Sets the space id of the root of the index tree. */
UNIV_INLINE
void
-dict_tree_set_space(
-/*================*/
- dict_tree_t* tree, /* in: tree */
+dict_index_set_space(
+/*=================*/
+ dict_index_t* index, /* in: index */
ulint space); /* in: space id */
/*************************************************************************
Gets the page number of the root of the index tree. */
UNIV_INLINE
ulint
-dict_tree_get_page(
-/*===============*/
+dict_index_get_page(
+/*================*/
/* out: page number */
- dict_tree_t* tree); /* in: tree */
+ dict_index_t* tree); /* in: index */
/*************************************************************************
Sets the page number of the root of index tree. */
UNIV_INLINE
void
-dict_tree_set_page(
-/*===============*/
- dict_tree_t* tree, /* in: tree */
+dict_index_set_page(
+/*================*/
+ dict_index_t* index, /* in: index */
ulint page); /* in: page number */
/*************************************************************************
Gets the type of the index tree. */
UNIV_INLINE
ulint
-dict_tree_get_type(
-/*===============*/
+dict_index_get_type(
+/*================*/
/* out: type */
- dict_tree_t* tree); /* in: tree */
+ dict_index_t* index); /* in: index */
/*************************************************************************
Gets the read-write lock of the index tree. */
UNIV_INLINE
rw_lock_t*
-dict_tree_get_lock(
-/*===============*/
+dict_index_get_lock(
+/*================*/
/* out: read-write lock */
- dict_tree_t* tree); /* in: tree */
+ dict_index_t* index); /* in: index */
/************************************************************************
Returns free space reserved for future updates of records. This is
relevant only in the case of many consecutive inserts, as updates
which make the records bigger might fragment the index. */
UNIV_INLINE
ulint
-dict_tree_get_space_reserve(
-/*========================*/
+dict_index_get_space_reserve(void);
+/*==============================*/
/* out: number of free bytes on page,
reserved for updates */
- dict_tree_t* tree); /* in: a tree */
/*************************************************************************
Calculates the minimum record length in an index. */
@@ -945,7 +984,6 @@ struct dict_sys_struct{
on name */
hash_table_t* table_id_hash; /* hash table of the tables, based
on id */
- hash_table_t* col_hash; /* hash table of the columns */
UT_LIST_BASE_NODE_T(dict_table_t)
table_LRU; /* LRU list of tables */
ulint size; /* varying space in bytes occupied
diff --git a/storage/innobase/include/dict0dict.ic b/storage/innobase/include/dict0dict.ic
index de00148535f..d59e99277da 100644
--- a/storage/innobase/include/dict0dict.ic
+++ b/storage/innobase/include/dict0dict.ic
@@ -9,18 +9,74 @@ Created 1/8/1996 Heikki Tuuri
#include "dict0load.h"
#include "trx0undo.h"
#include "trx0sys.h"
+#include "rem0types.h"
+#include "data0type.h"
/*************************************************************************
Gets the column data type. */
UNIV_INLINE
-dtype_t*
-dict_col_get_type(
-/*==============*/
- dict_col_t* col)
+void
+dict_col_copy_type(
+/*===============*/
+ const dict_col_t* col, /* in: column */
+ dtype_t* type) /* out: data type */
{
- ut_ad(col);
+ ut_ad(col && type);
- return(&col->type);
+ type->mtype = col->mtype;
+ type->prtype = col->prtype;
+ type->len = col->len;
+ type->mbminlen = col->mbminlen;
+ type->mbmaxlen = col->mbmaxlen;
+}
+
+/***************************************************************************
+Returns the minimum size of the column. */
+UNIV_INLINE
+ulint
+dict_col_get_min_size(
+/*==================*/
+ /* out: minimum size */
+ const dict_col_t* col) /* in: column */
+{
+ return(dtype_get_min_size_low(col->mtype, col->prtype, col->len,
+ col->mbminlen, col->mbmaxlen));
+}
+/***************************************************************************
+Returns the maximum size of the column. */
+UNIV_INLINE
+ulint
+dict_col_get_max_size(
+/*==================*/
+ /* out: maximum size */
+ const dict_col_t* col) /* in: column */
+{
+ return(dtype_get_max_size_low(col->mtype, col->len));
+}
+/***************************************************************************
+Returns the size of a fixed size column, 0 if not a fixed size column. */
+UNIV_INLINE
+ulint
+dict_col_get_fixed_size(
+/*====================*/
+ /* out: fixed size, or 0 */
+ const dict_col_t* col) /* in: column */
+{
+ return(dtype_get_fixed_size_low(col->mtype, col->prtype, col->len,
+ col->mbminlen, col->mbmaxlen));
+}
+/***************************************************************************
+Returns the ROW_FORMAT=REDUNDANT stored SQL NULL size of a column.
+For fixed length types it is the fixed length of the type, otherwise 0. */
+UNIV_INLINE
+ulint
+dict_col_get_sql_null_size(
+/*=======================*/
+ /* out: SQL null storage size
+ in ROW_FORMAT=REDUNDANT */
+ const dict_col_t* col) /* in: column */
+{
+ return(dict_col_get_fixed_size(col));
}
/*************************************************************************
@@ -29,7 +85,7 @@ UNIV_INLINE
ulint
dict_col_get_no(
/*============*/
- dict_col_t* col)
+ const dict_col_t* col)
{
ut_ad(col);
@@ -42,11 +98,23 @@ UNIV_INLINE
ulint
dict_col_get_clust_pos(
/*===================*/
- dict_col_t* col)
+ const dict_col_t* col, /* in: table column */
+ const dict_index_t* clust_index) /* in: clustered index */
{
+ ulint i;
+
ut_ad(col);
+ ut_ad(clust_index && clust_index->type & DICT_CLUSTERED);
+
+ for (i = 0; i < clust_index->n_def; i++) {
+ const dict_field_t* field = &clust_index->fields[i];
- return(col->clust_pos);
+ if (!field->prefix_len && field->col == col) {
+ return(i);
+ }
+ }
+
+ return(ULINT_UNDEFINED);
}
/************************************************************************
@@ -132,12 +200,12 @@ dict_table_get_n_cols(
/************************************************************************
Gets the nth column of a table. */
UNIV_INLINE
-dict_col_t*
+const dict_col_t*
dict_table_get_nth_col(
/*===================*/
- /* out: pointer to column object */
- dict_table_t* table, /* in: table */
- ulint pos) /* in: position of column */
+ /* out: pointer to column object */
+ const dict_table_t* table, /* in: table */
+ ulint pos) /* in: position of column */
{
ut_ad(table);
ut_ad(pos < table->n_def);
@@ -149,14 +217,14 @@ dict_table_get_nth_col(
/************************************************************************
Gets the given system column of a table. */
UNIV_INLINE
-dict_col_t*
+const dict_col_t*
dict_table_get_sys_col(
/*===================*/
- /* out: pointer to column object */
- dict_table_t* table, /* in: table */
- ulint sys) /* in: DATA_ROW_ID, ... */
+ /* out: pointer to column object */
+ const dict_table_t* table, /* in: table */
+ ulint sys) /* in: DATA_ROW_ID, ... */
{
- dict_col_t* col;
+ const dict_col_t* col;
ut_ad(table);
ut_ad(sys < DATA_N_SYS_COLS);
@@ -164,8 +232,8 @@ dict_table_get_sys_col(
col = dict_table_get_nth_col(table, table->n_cols
- DATA_N_SYS_COLS + sys);
- ut_ad(col->type.mtype == DATA_SYS);
- ut_ad(col->type.prtype == (sys | DATA_NOT_NULL));
+ ut_ad(col->mtype == DATA_SYS);
+ ut_ad(col->prtype == (sys | DATA_NOT_NULL));
return(col);
}
@@ -311,45 +379,28 @@ dict_index_get_sys_col_pos(
dict_index_t* index, /* in: index */
ulint type) /* in: DATA_ROW_ID, ... */
{
- dict_col_t* col;
-
ut_ad(index);
ut_ad(index->magic_n == DICT_INDEX_MAGIC_N);
ut_ad(!(index->type & DICT_UNIVERSAL));
- col = dict_table_get_sys_col(index->table, type);
-
if (index->type & DICT_CLUSTERED) {
- return(col->clust_pos);
+ return(dict_col_get_clust_pos(
+ dict_table_get_sys_col(index->table, type),
+ index));
}
- return(dict_index_get_nth_col_pos
- (index, dict_table_get_sys_col_no(index->table, type)));
-}
-
-/*************************************************************************
-Gets the index tree where the index is stored. */
-UNIV_INLINE
-dict_tree_t*
-dict_index_get_tree(
-/*================*/
- /* out: index tree */
- dict_index_t* index) /* in: index */
-{
- ut_ad(index);
- ut_ad(index->magic_n == DICT_INDEX_MAGIC_N);
-
- return(index->tree);
+ return(dict_index_get_nth_col_pos(
+ index, dict_table_get_sys_col_no(index->table, type)));
}
/*************************************************************************
Gets the field column. */
UNIV_INLINE
-dict_col_t*
+const dict_col_t*
dict_field_get_col(
/*===============*/
- dict_field_t* field)
+ const dict_field_t* field)
{
ut_ad(field);
@@ -357,17 +408,17 @@ dict_field_get_col(
}
/************************************************************************
-Gets pointer to the nth field data type in an index. */
+Gets pointer to the nth column in an index. */
UNIV_INLINE
-dtype_t*
-dict_index_get_nth_type(
-/*====================*/
- /* out: data type */
- dict_index_t* index, /* in: index */
- ulint pos) /* in: position of the field */
+const dict_col_t*
+dict_index_get_nth_col(
+/*===================*/
+ /* out: column */
+ const dict_index_t* index, /* in: index */
+ ulint pos) /* in: position of the field */
{
- return(dict_col_get_type(dict_field_get_col
- (dict_index_get_nth_field(index, pos))));
+ return(dict_field_get_col(dict_index_get_nth_field((dict_index_t*)
+ index, pos)));
}
/************************************************************************
@@ -376,102 +427,101 @@ UNIV_INLINE
ulint
dict_index_get_nth_col_no(
/*======================*/
- /* out: column number */
- dict_index_t* index, /* in: index */
- ulint pos) /* in: position of the field */
+ /* out: column number */
+ const dict_index_t* index, /* in: index */
+ ulint pos) /* in: position of the field */
{
- return(dict_col_get_no(dict_field_get_col
- (dict_index_get_nth_field(index, pos))));
+ return(dict_col_get_no(dict_index_get_nth_col(index, pos)));
}
/*************************************************************************
Gets the space id of the root of the index tree. */
UNIV_INLINE
ulint
-dict_tree_get_space(
-/*================*/
+dict_index_get_space(
+/*=================*/
/* out: space id */
- dict_tree_t* tree) /* in: tree */
+ dict_index_t* index) /* in: index */
{
- ut_ad(tree);
- ut_ad(tree->magic_n == DICT_TREE_MAGIC_N);
+ ut_ad(index);
+ ut_ad(index->magic_n == DICT_INDEX_MAGIC_N);
- return(tree->space);
+ return(index->space);
}
/*************************************************************************
Sets the space id of the root of the index tree. */
UNIV_INLINE
void
-dict_tree_set_space(
-/*================*/
- dict_tree_t* tree, /* in: tree */
+dict_index_set_space(
+/*=================*/
+ dict_index_t* index, /* in: index */
ulint space) /* in: space id */
{
- ut_ad(tree);
- ut_ad(tree->magic_n == DICT_TREE_MAGIC_N);
+ ut_ad(index);
+ ut_ad(index->magic_n == DICT_INDEX_MAGIC_N);
- tree->space = space;
+ index->space = space;
}
/*************************************************************************
Gets the page number of the root of the index tree. */
UNIV_INLINE
ulint
-dict_tree_get_page(
-/*===============*/
+dict_index_get_page(
+/*================*/
/* out: page number */
- dict_tree_t* tree) /* in: tree */
+ dict_index_t* index) /* in: index */
{
- ut_ad(tree);
- ut_ad(tree->magic_n == DICT_TREE_MAGIC_N);
+ ut_ad(index);
+ ut_ad(index->magic_n == DICT_INDEX_MAGIC_N);
- return(tree->page);
+ return(index->page);
}
/*************************************************************************
Sets the page number of the root of index tree. */
UNIV_INLINE
void
-dict_tree_set_page(
-/*===============*/
- dict_tree_t* tree, /* in: tree */
+dict_index_set_page(
+/*================*/
+ dict_index_t* index, /* in: index */
ulint page) /* in: page number */
{
- ut_ad(tree);
- ut_ad(tree->magic_n == DICT_TREE_MAGIC_N);
+ ut_ad(index);
+ ut_ad(index->magic_n == DICT_INDEX_MAGIC_N);
- tree->page = page;
+ index->page = page;
}
/*************************************************************************
Gets the type of the index tree. */
UNIV_INLINE
ulint
-dict_tree_get_type(
-/*===============*/
+dict_index_get_type(
+/*================*/
/* out: type */
- dict_tree_t* tree) /* in: tree */
+ dict_index_t* index) /* in: index */
{
- ut_ad(tree);
- ut_ad(tree->magic_n == DICT_TREE_MAGIC_N);
+ ut_ad(index);
+ ut_ad(index->magic_n == DICT_INDEX_MAGIC_N);
- return(tree->type);
+ return(index->type);
}
/*************************************************************************
Gets the read-write lock of the index tree. */
UNIV_INLINE
rw_lock_t*
-dict_tree_get_lock(
-/*===============*/
+dict_index_get_lock(
+/*================*/
/* out: read-write lock */
- dict_tree_t* tree) /* in: tree */
+ dict_index_t* index) /* in: index */
{
- ut_ad(tree);
- ut_ad(tree->magic_n == DICT_TREE_MAGIC_N);
+ ut_ad(index);
+ ut_ad(index->magic_n == DICT_INDEX_MAGIC_N);
- return(&(tree->lock));
+ return(&(index->lock));
}
/************************************************************************
@@ -480,16 +530,11 @@ relevant only in the case of many consecutive inserts, as updates
which make the records bigger might fragment the index. */
UNIV_INLINE
ulint
-dict_tree_get_space_reserve(
-/*========================*/
+dict_index_get_space_reserve(void)
+/*==============================*/
/* out: number of free bytes on page,
reserved for updates */
- dict_tree_t* tree) /* in: a tree */
{
- ut_ad(tree);
-
- UT_NOT_USED(tree);
-
return(UNIV_PAGE_SIZE / 16);
}
diff --git a/storage/innobase/include/dict0mem.h b/storage/innobase/include/dict0mem.h
index e8682b79387..a23f89954a4 100644
--- a/storage/innobase/include/dict0mem.h
+++ b/storage/innobase/include/dict0mem.h
@@ -75,8 +75,7 @@ dict_mem_table_add_col(
const char* name, /* in: column name */
ulint mtype, /* in: main datatype */
ulint prtype, /* in: precise type */
- ulint len, /* in: length */
- ulint prec); /* in: precision */
+ ulint len); /* in: precision */
/**************************************************************************
Creates an index memory object. */
@@ -122,16 +121,41 @@ dict_mem_foreign_create(void);
/* Data structure for a column in a table */
struct dict_col_struct{
- hash_node_t hash; /* hash chain node */
- ulint ind; /* table column position (they are numbered
- starting from 0) */
- ulint clust_pos;/* position of the column in the
- clustered index */
- ulint ord_part;/* count of how many times this column
- appears in ordering fields of an index */
- const char* name; /* name */
- dtype_t type; /* data type */
- dict_table_t* table; /* back pointer to table of this column */
+ /*----------------------*/
+ /* The following are copied from dtype_t,
+ so that all bit-fields can be packed tightly. */
+ unsigned mtype:8; /* main data type */
+ unsigned prtype:24; /* precise type; MySQL data
+ type, charset code, flags to
+ indicate nullability,
+ signedness, whether this is a
+ binary string, whether this is
+ a true VARCHAR where MySQL
+ uses 2 bytes to store the length */
+
+ /* the remaining fields do not affect alphabetical ordering: */
+
+ unsigned len:16; /* length; for MySQL data this
+ is field->pack_length(),
+ except that for a >= 5.0.3
+ type true VARCHAR this is the
+ maximum byte length of the
+ string data (in addition to
+ the string, MySQL uses 1 or 2
+ bytes to store the string length) */
+
+ unsigned mbminlen:2; /* minimum length of a
+ character, in bytes */
+ unsigned mbmaxlen:3; /* maximum length of a
+ character, in bytes */
+ /*----------------------*/
+ /* End of definitions copied from dtype_t */
+
+ unsigned ind:10; /* table column position
+ (starting from 0) */
+ unsigned ord_part:1; /* nonzero if this column
+ appears in the ordering fields
+ of an index */
};
/* DICT_MAX_INDEX_COL_LEN is measured in bytes and is the max index column
@@ -145,35 +169,18 @@ UTF-8 charset. In that charset, a character may take at most 3 bytes. */
struct dict_field_struct{
dict_col_t* col; /* pointer to the table column */
const char* name; /* name of the column */
- ulint prefix_len; /* 0 or the length of the column
+ unsigned prefix_len:10; /* 0 or the length of the column
prefix in bytes in a MySQL index of
type, e.g., INDEX (textcol(25));
must be smaller than
DICT_MAX_INDEX_COL_LEN; NOTE that
in the UTF-8 charset, MySQL sets this
to 3 * the prefix len in UTF-8 chars */
- ulint fixed_len; /* 0 or the fixed length of the
+ unsigned fixed_len:10; /* 0 or the fixed length of the
column if smaller than
DICT_MAX_INDEX_COL_LEN */
};
-/* Data structure for an index tree */
-struct dict_tree_struct{
- ulint type; /* tree type */
- dulint id; /* id of the index stored in the tree */
- ulint space; /* space of index tree */
- ulint page; /* index tree root page number */
- byte pad[64];/* Padding to prevent other memory hotspots on
- the same memory cache line */
- rw_lock_t lock; /* read-write lock protecting the upper levels
- of the index tree */
- dict_index_t* tree_index; /* the index stored in the
- index tree */
- ulint magic_n;/* magic number */
-};
-
-#define DICT_TREE_MAGIC_N 7545676
-
/* Data structure for an index */
struct dict_index_struct{
dulint id; /* id of the index */
@@ -182,30 +189,28 @@ struct dict_index_struct{
const char* name; /* index name */
const char* table_name; /* table name */
dict_table_t* table; /* back pointer to table */
- ulint space; /* space where the index tree is placed */
- ulint trx_id_offset;/* position of the the trx id column
+ unsigned space:32;
+ /* space where the index tree is placed */
+ unsigned page:32;/* index tree root page number */
+ unsigned trx_id_offset:10;/* position of the the trx id column
in a clustered index record, if the fields
before it are known to be of a fixed size,
0 otherwise */
- ulint n_user_defined_cols;
+ unsigned n_user_defined_cols:10;
/* number of columns the user defined to
be in the index: in the internal
representation we add more columns */
- ulint n_uniq; /* number of fields from the beginning
+ unsigned n_uniq:10;/* number of fields from the beginning
which are enough to determine an index
entry uniquely */
- ulint n_def; /* number of fields defined so far */
- ulint n_fields;/* number of fields in the index */
+ unsigned n_def:10;/* number of fields defined so far */
+ unsigned n_fields:10;/* number of fields in the index */
+ unsigned n_nullable:10;/* number of nullable fields */
+ unsigned cached:1;/* TRUE if the index object is in the
+ dictionary cache */
dict_field_t* fields; /* array of field descriptions */
- ulint n_nullable;/* number of nullable fields */
UT_LIST_NODE_T(dict_index_t)
indexes;/* list of indexes of the table */
- dict_tree_t* tree; /* index tree struct */
- UT_LIST_NODE_T(dict_index_t)
- tree_indexes; /* list of indexes of the same index
- tree */
- ibool cached; /* TRUE if the index object is in the
- dictionary cache */
btr_search_t* search_info; /* info used in optimistic searches */
/*----------------------*/
ib_longlong* stat_n_diff_key_vals;
@@ -218,7 +223,12 @@ struct dict_index_struct{
ulint stat_n_leaf_pages;
/* approximate number of leaf pages in the
index tree */
+ rw_lock_t lock; /* read-write lock protecting the upper levels
+ of the index tree */
+#ifdef UNIV_DEBUG
ulint magic_n;/* magic number */
+# define DICT_INDEX_MAGIC_N 76789786
+#endif
};
/* Data structure for a foreign key constraint; an example:
@@ -229,7 +239,13 @@ struct dict_foreign_struct{
this memory heap */
char* id; /* id of the constraint as a
null-terminated string */
- ulint type; /* 0 or DICT_FOREIGN_ON_DELETE_CASCADE
+ unsigned n_fields:10; /* number of indexes' first fields
+ for which the the foreign key
+ constraint is defined: we allow the
+ indexes to contain more fields than
+ mentioned in the constraint, as long
+ as the first fields are as mentioned */
+ unsigned type:6; /* 0 or DICT_FOREIGN_ON_DELETE_CASCADE
or DICT_FOREIGN_ON_DELETE_SET_NULL */
char* foreign_table_name;/* foreign table name */
dict_table_t* foreign_table; /* table where the foreign key is */
@@ -240,12 +256,6 @@ struct dict_foreign_struct{
is */
const char** referenced_col_names;/* names of the referenced
columns in the referenced table */
- ulint n_fields; /* number of indexes' first fields
- for which the the foreign key
- constraint is defined: we allow the
- indexes to contain more fields than
- mentioned in the constraint, as long
- as the first fields are as mentioned */
dict_index_t* foreign_index; /* foreign index; we require that
both tables contain explicitly defined
indexes for the constraint: InnoDB
@@ -270,12 +280,9 @@ a foreign key constraint is enforced, therefore RESTRICT just means no flag */
#define DICT_FOREIGN_ON_UPDATE_NO_ACTION 32
-#define DICT_INDEX_MAGIC_N 76789786
-
/* Data structure for a database table */
struct dict_table_struct{
dulint id; /* id of the table */
- ulint flags; /* DICT_TF_COMPACT, ... */
mem_heap_t* heap; /* memory heap */
const char* name; /* table name */
const char* dir_path_of_temp_table;/* NULL or the directory path
@@ -284,20 +291,33 @@ struct dict_table_struct{
innodb_file_per_table is defined in my.cnf;
in Unix this is usually /tmp/..., in Windows
\temp\... */
- ulint space; /* space where the clustered index of the
+ unsigned space:32;
+ /* space where the clustered index of the
table is placed */
- ibool ibd_file_missing;/* TRUE if this is in a single-table
+ unsigned ibd_file_missing:1;
+ /* TRUE if this is in a single-table
tablespace and the .ibd file is missing; then
we must return in ha_innodb.cc an error if the
user tries to query such an orphaned table */
- ibool tablespace_discarded;/* this flag is set TRUE when the
- user calls DISCARD TABLESPACE on this table,
- and reset to FALSE in IMPORT TABLESPACE */
+ unsigned tablespace_discarded:1;
+ /* this flag is set TRUE when the user
+ calls DISCARD TABLESPACE on this
+ table, and reset to FALSE in IMPORT
+ TABLESPACE */
+ unsigned cached:1;/* TRUE if the table object has been added
+ to the dictionary cache */
+ unsigned flags:8;/* DICT_TF_COMPACT, ... */
+ unsigned n_def:10;/* number of columns defined so far */
+ unsigned n_cols:10;/* number of columns */
+ dict_col_t* cols; /* array of column descriptions */
+ const char* col_names;
+ /* n_def column names packed in an
+ "name1\0name2\0...nameN\0" array. until
+ n_def reaches n_cols, this is allocated with
+ ut_malloc, and the final size array is
+ allocated through the table's heap. */
hash_node_t name_hash; /* hash chain node */
hash_node_t id_hash; /* hash chain node */
- ulint n_def; /* number of columns defined so far */
- ulint n_cols; /* number of columns */
- dict_col_t* cols; /* array of column descriptions */
UT_LIST_BASE_NODE_T(dict_index_t)
indexes; /* list of indexes of the table */
UT_LIST_BASE_NODE_T(dict_foreign_t)
@@ -321,8 +341,6 @@ struct dict_table_struct{
on the table: we cannot drop the table while
there are foreign key checks running on
it! */
- ibool cached; /* TRUE if the table object has been added
- to the dictionary cache */
lock_t* auto_inc_lock;/* a buffer for an auto-inc lock
for this table: we allocate the memory here
so that individual transactions can get it
@@ -339,12 +357,7 @@ struct dict_table_struct{
had an IX lock on */
UT_LIST_BASE_NODE_T(lock_t)
locks; /* list of locks on the table */
- ulint max_row_size;
- /* maximum size of a single row in the
- table, not guaranteed to be especially
- accurate. it's ULINT_MAX if there are
- unbounded variable-width fields. initialized
- in dict_table_add_to_cache. */
+#ifdef UNIV_DEBUG
/*----------------------*/
ibool does_not_fit_in_memory;
/* this field is used to specify in simulations
@@ -355,7 +368,15 @@ struct dict_table_struct{
dictionary on disk, and the database will
forget about value TRUE if it has to reload
the table definition from disk */
+#endif /* UNIV_DEBUG */
/*----------------------*/
+ unsigned big_rows:1;
+ /* flag: TRUE if the maximum length of
+ a single row exceeds BIG_ROW_SIZE;
+ initialized in dict_table_add_to_cache() */
+ unsigned stat_initialized:1; /* TRUE if statistics have
+ been calculated the first time
+ after database startup or table creation */
ib_longlong stat_n_rows;
/* approximate number of rows in the table;
we periodically calculate new estimates */
@@ -364,9 +385,6 @@ struct dict_table_struct{
database pages */
ulint stat_sum_of_other_index_sizes;
/* other indexes in database pages */
- ibool stat_initialized; /* TRUE if statistics have
- been calculated the first time
- after database startup or table creation */
ulint stat_modified_counter;
/* when a row is inserted, updated, or deleted,
we add 1 to this number; we calculate new
@@ -389,9 +407,11 @@ struct dict_table_struct{
SELECT MAX(auto inc column) */
ib_longlong autoinc;/* autoinc counter value to give to the
next inserted row */
+#ifdef UNIV_DEBUG
ulint magic_n;/* magic number */
+# define DICT_TABLE_MAGIC_N 76333786
+#endif /* UNIV_DEBUG */
};
-#define DICT_TABLE_MAGIC_N 76333786
#ifndef UNIV_NONINL
#include "dict0mem.ic"
diff --git a/storage/innobase/include/dict0types.h b/storage/innobase/include/dict0types.h
index bd8a1a996d1..b90545f2105 100644
--- a/storage/innobase/include/dict0types.h
+++ b/storage/innobase/include/dict0types.h
@@ -13,7 +13,6 @@ typedef struct dict_sys_struct dict_sys_t;
typedef struct dict_col_struct dict_col_t;
typedef struct dict_field_struct dict_field_t;
typedef struct dict_index_struct dict_index_t;
-typedef struct dict_tree_struct dict_tree_t;
typedef struct dict_table_struct dict_table_t;
typedef struct dict_foreign_struct dict_foreign_t;
diff --git a/storage/innobase/include/ibuf0ibuf.ic b/storage/innobase/include/ibuf0ibuf.ic
index 4c5f6dbf5e1..4d65a7f5250 100644
--- a/storage/innobase/include/ibuf0ibuf.ic
+++ b/storage/innobase/include/ibuf0ibuf.ic
@@ -165,8 +165,8 @@ ibuf_index_page_calc_free(
/* out: value for ibuf bitmap bits */
page_t* page) /* in: non-unique secondary index page */
{
- return(ibuf_index_page_calc_free_bits
- (page_get_max_insert_size_after_reorganize(page, 1)));
+ return(ibuf_index_page_calc_free_bits(
+ page_get_max_insert_size_after_reorganize(page, 1)));
}
/****************************************************************************
diff --git a/storage/innobase/include/page0page.h b/storage/innobase/include/page0page.h
index 7f99f670190..833d268c9de 100644
--- a/storage/innobase/include/page0page.h
+++ b/storage/innobase/include/page0page.h
@@ -132,6 +132,24 @@ directory. */
#define PAGE_DIR_SLOT_MAX_N_OWNED 8
#define PAGE_DIR_SLOT_MIN_N_OWNED 4
+/****************************************************************
+Gets the start of a page. */
+UNIV_INLINE
+page_t*
+page_align(
+/*=======*/
+ /* out: start of the page */
+ void* ptr) /* in: pointer to page frame */
+ __attribute__((const));
+/****************************************************************
+Gets the offset within a page. */
+UNIV_INLINE
+ulint
+page_offset(
+/*========*/
+ /* out: offset from the start of the page */
+ const void* ptr) /* in: pointer to page frame */
+ __attribute__((const));
/*****************************************************************
Returns the max trx id field value. */
UNIV_INLINE
diff --git a/storage/innobase/include/page0page.ic b/storage/innobase/include/page0page.ic
index 9348acd5ffc..d9e67f3eeeb 100644
--- a/storage/innobase/include/page0page.ic
+++ b/storage/innobase/include/page0page.ic
@@ -15,6 +15,28 @@ Created 2/2/1994 Heikki Tuuri
#define UNIV_INLINE
#endif
+/****************************************************************
+Gets the start of a page. */
+UNIV_INLINE
+page_t*
+page_align(
+/*=======*/
+ /* out: start of the page */
+ void* ptr) /* in: pointer to page frame */
+{
+ return((page_t*) ut_align_down(ptr, UNIV_PAGE_SIZE));
+}
+/****************************************************************
+Gets the offset within a page. */
+UNIV_INLINE
+ulint
+page_offset(
+/*========*/
+ /* out: offset from the start of the page */
+ const void* ptr) /* in: pointer to page frame */
+{
+ return(ut_align_offset(ptr, UNIV_PAGE_SIZE));
+}
/*****************************************************************
Returns the max trx id field value. */
UNIV_INLINE
@@ -175,7 +197,7 @@ page_rec_is_comp(
/* out: nonzero if in compact format */
const rec_t* rec) /* in: record */
{
- return(page_is_comp(ut_align_down((rec_t*) rec, UNIV_PAGE_SIZE)));
+ return(page_is_comp(page_align((rec_t*) rec)));
}
/****************************************************************
@@ -291,7 +313,7 @@ page_rec_is_user_rec(
/* out: TRUE if a user record */
const rec_t* rec) /* in: record */
{
- return(page_rec_is_user_rec_low(ut_align_offset(rec, UNIV_PAGE_SIZE)));
+ return(page_rec_is_user_rec_low(page_offset(rec)));
}
/****************************************************************
@@ -303,7 +325,7 @@ page_rec_is_supremum(
/* out: TRUE if the supremum record */
const rec_t* rec) /* in: record */
{
- return(page_rec_is_supremum_low(ut_align_offset(rec, UNIV_PAGE_SIZE)));
+ return(page_rec_is_supremum_low(page_offset(rec)));
}
/****************************************************************
@@ -315,7 +337,7 @@ page_rec_is_infimum(
/* out: TRUE if the infimum record */
const rec_t* rec) /* in: record */
{
- return(page_rec_is_infimum_low(ut_align_offset(rec, UNIV_PAGE_SIZE)));
+ return(page_rec_is_infimum_low(page_offset(rec)));
}
/*****************************************************************
@@ -351,7 +373,7 @@ page_cmp_dtuple_rec_with_match(
ut_ad(rec_offs_validate(rec, NULL, offsets));
ut_ad(!rec_offs_comp(offsets) == !page_rec_is_comp(rec));
- rec_offset = ut_align_offset(rec, UNIV_PAGE_SIZE);
+ rec_offset = page_offset(rec);
if (UNIV_UNLIKELY(rec_offset == PAGE_NEW_INFIMUM)
|| UNIV_UNLIKELY(rec_offset == PAGE_OLD_INFIMUM)) {
@@ -492,7 +514,7 @@ page_dir_slot_set_rec(
{
ut_ad(page_rec_check(rec));
- mach_write_to_2(slot, ut_align_offset(rec, UNIV_PAGE_SIZE));
+ mach_write_to_2(slot, page_offset(rec));
}
/*******************************************************************
@@ -550,7 +572,7 @@ page_rec_get_next(
ut_ad(page_rec_check(rec));
- page = ut_align_down(rec, UNIV_PAGE_SIZE);
+ page = page_align(rec);
offs = rec_get_next_offs(rec, page_is_comp(page));
@@ -592,11 +614,11 @@ page_rec_set_next(
ut_ad(page_rec_check(rec));
ut_ad(!page_rec_is_supremum(rec));
- page = ut_align_down(rec, UNIV_PAGE_SIZE);
+ page = page_align(rec);
if (next) {
ut_ad(!page_rec_is_infimum(next));
- ut_ad(page == ut_align_down(next, UNIV_PAGE_SIZE));
+ ut_ad(page == page_align(next));
offs = (ulint) (next - page);
} else {
offs = 0;
@@ -623,7 +645,7 @@ page_rec_get_prev(
ut_ad(page_rec_check(rec));
- page = ut_align_down(rec, UNIV_PAGE_SIZE);
+ page = page_align(rec);
ut_ad(!page_rec_is_infimum(rec));
@@ -735,15 +757,15 @@ page_get_max_insert_size(
if (page_is_comp(page)) {
occupied = page_header_get_field(page, PAGE_HEAP_TOP)
- PAGE_NEW_SUPREMUM_END
- + page_dir_calc_reserved_space
- (n_recs + page_dir_get_n_heap(page) - 2);
+ + page_dir_calc_reserved_space(
+ n_recs + page_dir_get_n_heap(page) - 2);
free_space = page_get_free_space_of_empty(TRUE);
} else {
occupied = page_header_get_field(page, PAGE_HEAP_TOP)
- PAGE_OLD_SUPREMUM_END
- + page_dir_calc_reserved_space
- (n_recs + page_dir_get_n_heap(page) - 2);
+ + page_dir_calc_reserved_space(
+ n_recs + page_dir_get_n_heap(page) - 2);
free_space = page_get_free_space_of_empty(FALSE);
}
diff --git a/storage/innobase/include/read0read.ic b/storage/innobase/include/read0read.ic
index 9785cf1b3ce..3aded1ca07c 100644
--- a/storage/innobase/include/read0read.ic
+++ b/storage/innobase/include/read0read.ic
@@ -69,9 +69,9 @@ read_view_sees_trx_id(
for (i = 0; i < n_ids; i++) {
- cmp = ut_dulint_cmp
- (trx_id,
- read_view_get_nth_trx_id(view, n_ids - i - 1));
+ cmp = ut_dulint_cmp(
+ trx_id,
+ read_view_get_nth_trx_id(view, n_ids - i - 1));
if (cmp <= 0) {
return(cmp < 0);
}
diff --git a/storage/innobase/include/rem0cmp.h b/storage/innobase/include/rem0cmp.h
index 36d91db0e87..c6a6e5de4db 100644
--- a/storage/innobase/include/rem0cmp.h
+++ b/storage/innobase/include/rem0cmp.h
@@ -16,16 +16,17 @@ Created 7/1/1994 Heikki Tuuri
#include "rem0rec.h"
/*****************************************************************
-Returns TRUE if two types are equal for comparison purposes. */
+Returns TRUE if two columns are equal for comparison purposes. */
ibool
-cmp_types_are_equal(
-/*================*/
- /* out: TRUE if the types are considered
- equal in comparisons */
- dtype_t* type1, /* in: type 1 */
- dtype_t* type2, /* in: type 2 */
- ibool check_charsets); /* in: whether to check charsets */
+cmp_cols_are_equal(
+/*===============*/
+ /* out: TRUE if the columns are
+ considered equal in comparisons */
+ const dict_col_t* col1, /* in: column 1 */
+ const dict_col_t* col2, /* in: column 2 */
+ ibool check_charsets);
+ /* in: whether to check charsets */
/*****************************************************************
This function is used to compare two data fields for which we know the
data type. */
@@ -35,7 +36,8 @@ cmp_data_data(
/*==========*/
/* out: 1, 0, -1, if data1 is greater, equal,
less than data2, respectively */
- dtype_t* cur_type,/* in: data type of the fields */
+ ulint mtype, /* in: main type */
+ ulint prtype, /* in: precise type */
byte* data1, /* in: data field (== a pointer to a memory
buffer) */
ulint len1, /* in: data field length or UNIV_SQL_NULL */
@@ -51,7 +53,8 @@ cmp_data_data_slow(
/*===============*/
/* out: 1, 0, -1, if data1 is greater, equal,
less than data2, respectively */
- dtype_t* cur_type,/* in: data type of the fields */
+ ulint mtype, /* in: main type */
+ ulint prtype, /* in: precise type */
byte* data1, /* in: data field (== a pointer to a memory
buffer) */
ulint len1, /* in: data field length or UNIV_SQL_NULL */
diff --git a/storage/innobase/include/rem0cmp.ic b/storage/innobase/include/rem0cmp.ic
index 5653ec1ac44..52dc7ff5dc9 100644
--- a/storage/innobase/include/rem0cmp.ic
+++ b/storage/innobase/include/rem0cmp.ic
@@ -15,7 +15,8 @@ cmp_data_data(
/*==========*/
/* out: 1, 0, -1, if data1 is greater, equal,
less than data2, respectively */
- dtype_t* cur_type,/* in: data type of the fields */
+ ulint mtype, /* in: main type */
+ ulint prtype, /* in: precise type */
byte* data1, /* in: data field (== a pointer to a memory
buffer) */
ulint len1, /* in: data field length or UNIV_SQL_NULL */
@@ -23,7 +24,7 @@ cmp_data_data(
buffer) */
ulint len2) /* in: data field length or UNIV_SQL_NULL */
{
- return(cmp_data_data_slow(cur_type, data1, len1, data2, len2));
+ return(cmp_data_data_slow(mtype, prtype, data1, len1, data2, len2));
}
/*****************************************************************
@@ -38,12 +39,17 @@ cmp_dfield_dfield(
dfield_t* dfield1,/* in: data field; must have type field set */
dfield_t* dfield2)/* in: data field */
{
+ const dtype_t* type;
+
ut_ad(dfield_check_typed(dfield1));
- return(cmp_data_data
- (dfield_get_type(dfield1),
- dfield_get_data(dfield1), dfield_get_len(dfield1),
- dfield_get_data(dfield2), dfield_get_len(dfield2)));
+ type = dfield_get_type(dfield1);
+
+ return(cmp_data_data(type->mtype, type->prtype,
+ dfield_get_data(dfield1),
+ dfield_get_len(dfield1),
+ dfield_get_data(dfield2),
+ dfield_get_len(dfield2)));
}
/*****************************************************************
diff --git a/storage/innobase/include/rem0rec.h b/storage/innobase/include/rem0rec.h
index af11198d001..43ef6650e90 100644
--- a/storage/innobase/include/rem0rec.h
+++ b/storage/innobase/include/rem0rec.h
@@ -14,11 +14,6 @@ Created 5/30/1994 Heikki Tuuri
#include "rem0types.h"
#include "mtr0types.h"
-/* Maximum values for various fields (for non-blob tuples) */
-#define REC_MAX_N_FIELDS (1024 - 1)
-#define REC_MAX_HEAP_NO (2 * 8192 - 1)
-#define REC_MAX_N_OWNED (16 - 1)
-
/* Info bit denoting the predefined minimum record: this bit is set
if and only if the record is the first user record on a non-leaf
B-tree page that is the leftmost page on its level
diff --git a/storage/innobase/include/rem0rec.ic b/storage/innobase/include/rem0rec.ic
index 5e4c0ea0664..ace90247b80 100644
--- a/storage/innobase/include/rem0rec.ic
+++ b/storage/innobase/include/rem0rec.ic
@@ -336,8 +336,8 @@ rec_set_next_offs(
as a non-negative number */
field_value = (ulint)((lint)next
- - (lint)ut_align_offset
- (rec, UNIV_PAGE_SIZE));
+ - (lint)ut_align_offset(
+ rec, UNIV_PAGE_SIZE));
field_value &= REC_NEXT_MASK;
} else {
field_value = 0;
@@ -597,15 +597,15 @@ rec_get_deleted_flag(
ulint comp) /* in: nonzero=compact page format */
{
if (UNIV_EXPECT(comp, REC_OFFS_COMPACT)) {
- return(UNIV_UNLIKELY
- (rec_get_bit_field_1(rec, REC_NEW_INFO_BITS,
- REC_INFO_DELETED_FLAG,
- REC_INFO_BITS_SHIFT)));
+ return(UNIV_UNLIKELY(
+ rec_get_bit_field_1(rec, REC_NEW_INFO_BITS,
+ REC_INFO_DELETED_FLAG,
+ REC_INFO_BITS_SHIFT)));
} else {
- return(UNIV_UNLIKELY
- (rec_get_bit_field_1(rec, REC_OLD_INFO_BITS,
- REC_INFO_DELETED_FLAG,
- REC_INFO_BITS_SHIFT)));
+ return(UNIV_UNLIKELY(
+ rec_get_bit_field_1(rec, REC_OLD_INFO_BITS,
+ REC_INFO_DELETED_FLAG,
+ REC_INFO_BITS_SHIFT)));
}
}
@@ -846,16 +846,16 @@ rec_offs_validate(
if (index) {
ulint max_n_fields;
ut_ad((ulint) index == offsets[3]);
- max_n_fields = ut_max
- (dict_index_get_n_fields(index),
- dict_index_get_n_unique_in_tree(index) + 1);
+ max_n_fields = ut_max(
+ dict_index_get_n_fields(index),
+ dict_index_get_n_unique_in_tree(index) + 1);
if (comp && rec) {
switch (rec_get_status(rec)) {
case REC_STATUS_ORDINARY:
break;
case REC_STATUS_NODE_PTR:
- max_n_fields = dict_index_get_n_unique_in_tree
- (index) + 1;
+ max_n_fields = dict_index_get_n_unique_in_tree(
+ index) + 1;
break;
case REC_STATUS_INFIMUM:
case REC_STATUS_SUPREMUM:
@@ -1453,8 +1453,8 @@ rec_get_converted_size(
data_size = dtuple_get_data_size(dtuple);
- extra_size = rec_get_converted_extra_size
- (data_size, dtuple_get_n_fields(dtuple));
+ extra_size = rec_get_converted_extra_size(
+ data_size, dtuple_get_n_fields(dtuple));
return(data_size + extra_size);
}
diff --git a/storage/innobase/include/rem0types.h b/storage/innobase/include/rem0types.h
index 94c394499c5..79c162392d2 100644
--- a/storage/innobase/include/rem0types.h
+++ b/storage/innobase/include/rem0types.h
@@ -12,5 +12,9 @@ Created 5/30/1994 Heikki Tuuri
/* We define the physical record simply as an array of bytes */
typedef byte rec_t;
+/* Maximum values for various fields (for non-blob tuples) */
+#define REC_MAX_N_FIELDS (1024 - 1)
+#define REC_MAX_HEAP_NO (2 * 8192 - 1)
+#define REC_MAX_N_OWNED (16 - 1)
#endif
diff --git a/storage/innobase/include/row0upd.ic b/storage/innobase/include/row0upd.ic
index 5e852559fe4..6173849e68f 100644
--- a/storage/innobase/include/row0upd.ic
+++ b/storage/innobase/include/row0upd.ic
@@ -93,8 +93,8 @@ upd_field_set_field_no(
(ulong) dict_index_get_n_fields(index));
}
- dtype_copy(dfield_get_type(&(upd_field->new_val)),
- dict_index_get_nth_type(index, field_no));
+ dict_col_copy_type(dict_index_get_nth_col(index, field_no),
+ dfield_get_type(&(upd_field->new_val)));
}
/*************************************************************************
diff --git a/storage/innobase/include/sync0rw.h b/storage/innobase/include/sync0rw.h
index e5f3e1341c5..d8f3c400918 100644
--- a/storage/innobase/include/sync0rw.h
+++ b/storage/innobase/include/sync0rw.h
@@ -426,13 +426,6 @@ struct rw_lock_struct {
waiters (readers or writers) in the global
wait array, waiting for this rw_lock.
Otherwise, == 0. */
- ibool writer_is_wait_ex;
- /* This is TRUE if the writer field is
- RW_LOCK_WAIT_EX; this field is located far
- from the memory update hotspot fields which
- are at the start of this struct, thus we can
- peek this field without causing much memory
- bus traffic */
UT_LIST_NODE_T(rw_lock_t) list;
/* All allocated rw locks are put into a
list */
@@ -440,15 +433,21 @@ struct rw_lock_struct {
UT_LIST_BASE_NODE_T(rw_lock_debug_t) debug_list;
/* In the debug version: pointer to the debug
info list of the lock */
-#endif /* UNIV_SYNC_DEBUG */
-
ulint level; /* Level in the global latching order. */
+#endif /* UNIV_SYNC_DEBUG */
const char* cfile_name;/* File name where lock created */
- ulint cline; /* Line where created */
const char* last_s_file_name;/* File name where last s-locked */
const char* last_x_file_name;/* File name where last x-locked */
- ulint last_s_line; /* Line number where last time s-locked */
- ulint last_x_line; /* Line number where last time x-locked */
+ ibool writer_is_wait_ex;
+ /* This is TRUE if the writer field is
+ RW_LOCK_WAIT_EX; this field is located far
+ from the memory update hotspot fields which
+ are at the start of this struct, thus we can
+ peek this field without causing much memory
+ bus traffic */
+ unsigned cline:14; /* Line where created */
+ unsigned last_s_line:14; /* Line number where last time s-locked */
+ unsigned last_x_line:14; /* Line number where last time x-locked */
ulint magic_n;
};
diff --git a/storage/innobase/include/univ.i b/storage/innobase/include/univ.i
index e60241b0ff3..63fdabbe823 100644
--- a/storage/innobase/include/univ.i
+++ b/storage/innobase/include/univ.i
@@ -91,6 +91,7 @@ memory is read outside the allocated blocks. */
#define UNIV_SYNC_PERF_STAT
#define UNIV_SEARCH_PERF_STAT
#define UNIV_SRV_PRINT_LATCH_WAITS
+#define UNIV_BTR_PRINT
#endif
#define UNIV_BTR_DEBUG
diff --git a/storage/innobase/lock/lock0lock.c b/storage/innobase/lock/lock0lock.c
index 3a2f17f41e5..551470f49b6 100644
--- a/storage/innobase/lock/lock0lock.c
+++ b/storage/innobase/lock/lock0lock.c
@@ -1041,8 +1041,8 @@ lock_has_to_wait(
return(lock_rec_has_to_wait(lock1->trx,
lock1->type_mode, lock2,
- lock_rec_get_nth_bit
- (lock1, 1)));
+ lock_rec_get_nth_bit(
+ lock1, 1)));
}
return(TRUE);
@@ -1303,13 +1303,13 @@ lock_rec_get_next(
if (page_rec_is_comp(rec)) {
do {
lock = lock_rec_get_next_on_page(lock);
- } while (lock && !lock_rec_get_nth_bit
- (lock, rec_get_heap_no(rec, TRUE)));
+ } while (lock && !lock_rec_get_nth_bit(
+ lock, rec_get_heap_no(rec, TRUE)));
} else {
do {
lock = lock_rec_get_next_on_page(lock);
- } while (lock && !lock_rec_get_nth_bit
- (lock, rec_get_heap_no(rec, FALSE)));
+ } while (lock && !lock_rec_get_nth_bit(
+ lock, rec_get_heap_no(rec, FALSE)));
}
return(lock);
@@ -1880,8 +1880,8 @@ lock_rec_enqueue_waiting(
if (lock_deadlock_occurs(lock, trx)) {
lock_reset_lock_and_trx_wait(lock);
- lock_rec_reset_nth_bit(lock, rec_get_heap_no
- (rec, page_rec_is_comp(rec)));
+ lock_rec_reset_nth_bit(lock, rec_get_heap_no(
+ rec, page_rec_is_comp(rec)));
return(DB_DEADLOCK);
}
@@ -2661,8 +2661,9 @@ lock_move_reorganize_page(
for (;;) {
ut_ad(comp || !memcmp(page_cur_get_rec(&cur1),
page_cur_get_rec(&cur2),
- rec_get_data_size_old
- (page_cur_get_rec(&cur2))));
+ rec_get_data_size_old(
+ page_cur_get_rec(
+ &cur2))));
old_heap_no = rec_get_heap_no(page_cur_get_rec(&cur2),
comp);
@@ -2759,8 +2760,9 @@ lock_move_rec_list_end(
while (page_cur_get_rec(&cur1) != sup) {
ut_ad(comp || !memcmp(page_cur_get_rec(&cur1),
page_cur_get_rec(&cur2),
- rec_get_data_size_old
- (page_cur_get_rec(&cur2))));
+ rec_get_data_size_old(
+ page_cur_get_rec(
+ &cur2))));
heap_no = rec_get_heap_no(page_cur_get_rec(&cur1),
comp);
@@ -2839,8 +2841,9 @@ lock_move_rec_list_start(
while (page_cur_get_rec(&cur1) != rec) {
ut_ad(comp || !memcmp(page_cur_get_rec(&cur1),
page_cur_get_rec(&cur2),
- rec_get_data_size_old
- (page_cur_get_rec(&cur2))));
+ rec_get_data_size_old(
+ page_cur_get_rec(
+ &cur2))));
heap_no = rec_get_heap_no(page_cur_get_rec(&cur1),
comp);
@@ -2898,8 +2901,8 @@ lock_update_split_right(
of the infimum on right page */
lock_rec_inherit_to_gap(page_get_supremum_rec(left_page),
- page_rec_get_next
- (page_get_infimum_rec(right_page)));
+ page_rec_get_next(
+ page_get_infimum_rec(right_page)));
lock_mutex_exit_kernel();
}
@@ -3000,8 +3003,8 @@ lock_update_split_left(
successor of the infimum on the right page */
lock_rec_inherit_to_gap(page_get_supremum_rec(left_page),
- page_rec_get_next
- (page_get_infimum_rec(right_page)));
+ page_rec_get_next(
+ page_get_infimum_rec(right_page)));
lock_mutex_exit_kernel();
}
@@ -3439,9 +3442,9 @@ lock_deadlock_recursive(
incompatible mode, and is itself waiting for
a lock */
- ret = lock_deadlock_recursive
- (start, lock_trx,
- lock_trx->wait_lock, cost, depth + 1);
+ ret = lock_deadlock_recursive(
+ start, lock_trx,
+ lock_trx->wait_lock, cost, depth + 1);
if (ret != 0) {
return(ret);
@@ -4219,9 +4222,9 @@ lock_rec_print(
if (page) {
rec_t* rec
= page_find_rec_with_heap_no(page, i);
- offsets = rec_get_offsets
- (rec, lock->index, offsets,
- ULINT_UNDEFINED, &heap);
+ offsets = rec_get_offsets(
+ rec, lock->index, offsets,
+ ULINT_UNDEFINED, &heap);
rec_print_new(file, rec, offsets);
}
@@ -4378,14 +4381,14 @@ loop:
fprintf(file,
"Trx read view will not see trx with"
" id >= %lu %lu, sees < %lu %lu\n",
- (ulong) ut_dulint_get_high
- (trx->read_view->low_limit_id),
- (ulong) ut_dulint_get_low
- (trx->read_view->low_limit_id),
- (ulong) ut_dulint_get_high
- (trx->read_view->up_limit_id),
- (ulong) ut_dulint_get_low
- (trx->read_view->up_limit_id));
+ (ulong) ut_dulint_get_high(
+ trx->read_view->low_limit_id),
+ (ulong) ut_dulint_get_low(
+ trx->read_view->low_limit_id),
+ (ulong) ut_dulint_get_high(
+ trx->read_view->up_limit_id),
+ (ulong) ut_dulint_get_low(
+ trx->read_view->up_limit_id));
}
fprintf(file,
@@ -4443,8 +4446,8 @@ loop:
mtr_start(&mtr);
- page = buf_page_get_with_no_latch
- (space, page_no, &mtr);
+ page = buf_page_get_with_no_latch(
+ space, page_no, &mtr);
mtr_commit(&mtr);
@@ -4510,8 +4513,9 @@ lock_table_queue_validate(
ut_a(!is_waiting);
- ut_a(!lock_table_other_has_incompatible
- (lock->trx, 0, table, lock_get_mode(lock)));
+ ut_a(!lock_table_other_has_incompatible(
+ lock->trx, 0, table,
+ lock_get_mode(lock)));
} else {
is_waiting = TRUE;
@@ -4580,8 +4584,8 @@ lock_rec_queue_validate(
impl_trx = lock_clust_rec_some_has_impl(rec, index, offsets);
- if (impl_trx && lock_rec_other_has_expl_req
- (LOCK_S, 0, LOCK_WAIT, rec, impl_trx)) {
+ if (impl_trx && lock_rec_other_has_expl_req(
+ LOCK_S, 0, LOCK_WAIT, rec, impl_trx)) {
ut_a(lock_rec_has_expl(LOCK_X | LOCK_REC_NOT_GAP,
rec, impl_trx));
@@ -4594,11 +4598,11 @@ lock_rec_queue_validate(
next function call: we have to release lock table mutex
to obey the latching order */
- impl_trx = lock_sec_rec_some_has_impl_off_kernel
- (rec, index, offsets);
+ impl_trx = lock_sec_rec_some_has_impl_off_kernel(
+ rec, index, offsets);
- if (impl_trx && lock_rec_other_has_expl_req
- (LOCK_S, 0, LOCK_WAIT, rec, impl_trx)) {
+ if (impl_trx && lock_rec_other_has_expl_req(
+ LOCK_S, 0, LOCK_WAIT, rec, impl_trx)) {
ut_a(lock_rec_has_expl(LOCK_X | LOCK_REC_NOT_GAP,
rec, impl_trx));
@@ -4626,8 +4630,8 @@ lock_rec_queue_validate(
} else {
mode = LOCK_S;
}
- ut_a(!lock_rec_other_has_expl_req
- (mode, 0, 0, rec, lock->trx));
+ ut_a(!lock_rec_other_has_expl_req(
+ mode, 0, 0, rec, lock->trx));
} else if (lock_get_wait(lock) && !lock_rec_get_gap(lock)) {
@@ -4764,8 +4768,8 @@ lock_validate(void)
while (lock) {
if (lock_get_type(lock) & LOCK_TABLE) {
- lock_table_queue_validate
- (lock->un_member.tab_lock.table);
+ lock_table_queue_validate(
+ lock->un_member.tab_lock.table);
}
lock = UT_LIST_GET_NEXT(trx_locks, lock);
@@ -4787,9 +4791,9 @@ lock_validate(void)
space = lock->un_member.rec_lock.space;
page_no = lock->un_member.rec_lock.page_no;
- if (ut_dulint_cmp
- (ut_dulint_create(space, page_no),
- limit) >= 0) {
+ if (ut_dulint_cmp(
+ ut_dulint_create(space, page_no),
+ limit) >= 0) {
break;
}
@@ -4889,8 +4893,9 @@ lock_rec_insert_check_and_lock(
had to wait for their insert. Both had waiting gap type lock requests
on the successor, which produced an unnecessary deadlock. */
- if (lock_rec_other_has_conflicting
- (LOCK_X | LOCK_GAP | LOCK_INSERT_INTENTION, next_rec, trx)) {
+ if (lock_rec_other_has_conflicting(
+ LOCK_X | LOCK_GAP | LOCK_INSERT_INTENTION, next_rec,
+ trx)) {
/* Note that we may get DB_SUCCESS also here! */
err = lock_rec_enqueue_waiting(LOCK_X | LOCK_GAP
@@ -4952,8 +4957,8 @@ lock_rec_convert_impl_to_expl(
if (index->type & DICT_CLUSTERED) {
impl_trx = lock_clust_rec_some_has_impl(rec, index, offsets);
} else {
- impl_trx = lock_sec_rec_some_has_impl_off_kernel
- (rec, index, offsets);
+ impl_trx = lock_sec_rec_some_has_impl_off_kernel(
+ rec, index, offsets);
}
if (impl_trx) {
@@ -4963,9 +4968,9 @@ lock_rec_convert_impl_to_expl(
if (!lock_rec_has_expl(LOCK_X | LOCK_REC_NOT_GAP, rec,
impl_trx)) {
- lock_rec_add_to_queue
- (LOCK_REC | LOCK_X | LOCK_REC_NOT_GAP,
- rec, index, impl_trx);
+ lock_rec_add_to_queue(
+ LOCK_REC | LOCK_X | LOCK_REC_NOT_GAP,
+ rec, index, impl_trx);
}
}
}
diff --git a/storage/innobase/log/log0log.c b/storage/innobase/log/log0log.c
index 9ac9e40466c..5d8875f1bd0 100644
--- a/storage/innobase/log/log0log.c
+++ b/storage/innobase/log/log0log.c
@@ -355,8 +355,8 @@ log_close(void)
full by the current mtr: the next mtr log record group
will start within this block at the offset data_len */
- log_block_set_first_rec_group
- (log_block, log_block_get_data_len(log_block));
+ log_block_set_first_rec_group(
+ log_block, log_block_get_data_len(log_block));
}
if (log->buf_free > log->max_buf_free) {
@@ -900,17 +900,17 @@ log_group_init(
#endif /* UNIV_LOG_ARCHIVE */
for (i = 0; i < n_files; i++) {
- *(group->file_header_bufs + i) = ut_align
- (mem_alloc(LOG_FILE_HDR_SIZE + OS_FILE_LOG_BLOCK_SIZE),
- OS_FILE_LOG_BLOCK_SIZE);
+ *(group->file_header_bufs + i) = ut_align(
+ mem_alloc(LOG_FILE_HDR_SIZE + OS_FILE_LOG_BLOCK_SIZE),
+ OS_FILE_LOG_BLOCK_SIZE);
memset(*(group->file_header_bufs + i), '\0',
LOG_FILE_HDR_SIZE);
#ifdef UNIV_LOG_ARCHIVE
- *(group->archive_file_header_bufs + i) = ut_align
- (mem_alloc(LOG_FILE_HDR_SIZE + OS_FILE_LOG_BLOCK_SIZE),
- OS_FILE_LOG_BLOCK_SIZE);
+ *(group->archive_file_header_bufs + i) = ut_align(
+ mem_alloc(LOG_FILE_HDR_SIZE + OS_FILE_LOG_BLOCK_SIZE),
+ OS_FILE_LOG_BLOCK_SIZE);
memset(*(group->archive_file_header_bufs + i), '\0',
LOG_FILE_HDR_SIZE);
#endif /* UNIV_LOG_ARCHIVE */
@@ -923,9 +923,8 @@ log_group_init(
group->archived_offset = 0;
#endif /* UNIV_LOG_ARCHIVE */
- group->checkpoint_buf = ut_align
- (mem_alloc(2 * OS_FILE_LOG_BLOCK_SIZE),
- OS_FILE_LOG_BLOCK_SIZE);
+ group->checkpoint_buf = ut_align(
+ mem_alloc(2 * OS_FILE_LOG_BLOCK_SIZE), OS_FILE_LOG_BLOCK_SIZE);
memset(group->checkpoint_buf, '\0', OS_FILE_LOG_BLOCK_SIZE);
@@ -1029,9 +1028,9 @@ log_sys_check_flush_completion(void)
/* Move the log buffer content to the start of the
buffer */
- move_start = ut_calc_align_down
- (log_sys->write_end_offset,
- OS_FILE_LOG_BLOCK_SIZE);
+ move_start = ut_calc_align_down(
+ log_sys->write_end_offset,
+ OS_FILE_LOG_BLOCK_SIZE);
move_end = ut_calc_align(log_sys->buf_free,
OS_FILE_LOG_BLOCK_SIZE);
@@ -1255,16 +1254,16 @@ loop:
(ulong) ut_dulint_get_high(start_lsn),
(ulong) ut_dulint_get_low(start_lsn),
(ulong) log_block_get_hdr_no(buf),
- (ulong) log_block_get_hdr_no
- (buf + write_len - OS_FILE_LOG_BLOCK_SIZE));
+ (ulong) log_block_get_hdr_no(
+ buf + write_len - OS_FILE_LOG_BLOCK_SIZE));
ut_a(log_block_get_hdr_no(buf)
== log_block_convert_lsn_to_no(start_lsn));
for (i = 0; i < write_len / OS_FILE_LOG_BLOCK_SIZE; i++) {
ut_a(log_block_get_hdr_no(buf) + i
- == log_block_get_hdr_no
- (buf + i * OS_FILE_LOG_BLOCK_SIZE));
+ == log_block_get_hdr_no(
+ buf + i * OS_FILE_LOG_BLOCK_SIZE));
}
}
#endif /* UNIV_DEBUG */
@@ -1412,10 +1411,10 @@ loop:
if (log_debug_writes) {
fprintf(stderr,
"Writing log from %lu %lu up to lsn %lu %lu\n",
- (ulong) ut_dulint_get_high
- (log_sys->written_to_all_lsn),
- (ulong) ut_dulint_get_low
- (log_sys->written_to_all_lsn),
+ (ulong) ut_dulint_get_high(
+ log_sys->written_to_all_lsn),
+ (ulong) ut_dulint_get_low(
+ log_sys->written_to_all_lsn),
(ulong) ut_dulint_get_high(log_sys->lsn),
(ulong) ut_dulint_get_low(log_sys->lsn));
}
@@ -1446,9 +1445,9 @@ loop:
log_sys->one_flushed = FALSE;
log_block_set_flush_bit(log_sys->buf + area_start, TRUE);
- log_block_set_checkpoint_no
- (log_sys->buf + area_end - OS_FILE_LOG_BLOCK_SIZE,
- log_sys->next_checkpoint_no);
+ log_block_set_checkpoint_no(
+ log_sys->buf + area_end - OS_FILE_LOG_BLOCK_SIZE,
+ log_sys->next_checkpoint_no);
/* Copy the last, incompletely written, log block a log block length
up, so that when the flush operation writes from the log buffer, the
@@ -1466,12 +1465,12 @@ loop:
/* Do the write to the log files */
while (group) {
- log_group_write_buf
- (group, log_sys->buf + area_start,
- area_end - area_start,
- ut_dulint_align_down(log_sys->written_to_all_lsn,
- OS_FILE_LOG_BLOCK_SIZE),
- start_offset - area_start);
+ log_group_write_buf(
+ group, log_sys->buf + area_start,
+ area_end - area_start,
+ ut_dulint_align_down(log_sys->written_to_all_lsn,
+ OS_FILE_LOG_BLOCK_SIZE),
+ start_offset - area_start);
log_group_set_fields(group, log_sys->write_lsn);
@@ -1730,8 +1729,8 @@ log_group_checkpoint(
log_sys->next_checkpoint_lsn);
mach_write_to_4(buf + LOG_CHECKPOINT_OFFSET,
- log_group_calc_lsn_offset
- (log_sys->next_checkpoint_lsn, group));
+ log_group_calc_lsn_offset(
+ log_sys->next_checkpoint_lsn, group));
mach_write_to_4(buf + LOG_CHECKPOINT_LOG_BUF_SIZE, log_sys->buf_size);
@@ -2355,9 +2354,9 @@ loop:
OS_DATA_FILE, &ret);
if (!ret && (open_mode == OS_FILE_CREATE)) {
- file_handle = os_file_create
- (name, OS_FILE_OPEN, OS_FILE_AIO,
- OS_DATA_FILE, &ret);
+ file_handle = os_file_create(
+ name, OS_FILE_OPEN, OS_FILE_AIO,
+ OS_DATA_FILE, &ret);
}
if (!ret) {
@@ -2388,10 +2387,10 @@ loop:
group->archive_space_id, FALSE);
if (next_offset % group->file_size == 0) {
- log_group_archive_file_header_write
- (group, n_files,
- group->archived_file_no + n_files,
- start_lsn);
+ log_group_archive_file_header_write(
+ group, n_files,
+ group->archived_file_no + n_files,
+ start_lsn);
next_offset += LOG_FILE_HDR_SIZE;
}
@@ -2513,10 +2512,10 @@ log_archive_write_complete_groups(void)
#endif /* UNIV_DEBUG */
/* Calculate the archive file space start lsn */
- start_lsn = ut_dulint_subtract
- (log_sys->next_archived_lsn,
- end_offset - LOG_FILE_HDR_SIZE + trunc_files
- * (group->file_size - LOG_FILE_HDR_SIZE));
+ start_lsn = ut_dulint_subtract(
+ log_sys->next_archived_lsn,
+ end_offset - LOG_FILE_HDR_SIZE + trunc_files
+ * (group->file_size - LOG_FILE_HDR_SIZE));
end_lsn = start_lsn;
for (i = 0; i < trunc_files; i++) {
@@ -2656,8 +2655,8 @@ loop:
if (ut_dulint_cmp(limit_lsn, log_sys->lsn) >= 0) {
- limit_lsn = ut_dulint_align_down
- (log_sys->lsn, OS_FILE_LOG_BLOCK_SIZE);
+ limit_lsn = ut_dulint_align_down(
+ log_sys->lsn, OS_FILE_LOG_BLOCK_SIZE);
}
}
@@ -2804,8 +2803,8 @@ log_archive_close_groups(
/* Write a notice to the headers of archived log
files that the file write has been completed */
- log_group_archive_completed_header_write
- (group, 0, log_sys->archived_lsn);
+ log_group_archive_completed_header_write(
+ group, 0, log_sys->archived_lsn);
fil_space_truncate_start(group->archive_space_id,
trunc_len);
diff --git a/storage/innobase/log/log0recv.c b/storage/innobase/log/log0recv.c
index 3a53e0eb6e5..280ebbb6bf2 100644
--- a/storage/innobase/log/log0recv.c
+++ b/storage/innobase/log/log0recv.c
@@ -239,12 +239,14 @@ recv_truncate_group(
archived_lsn = checkpoint_lsn;
}
- finish_lsn1 = ut_dulint_add(ut_dulint_align_down
- (archived_lsn, OS_FILE_LOG_BLOCK_SIZE),
+ finish_lsn1 = ut_dulint_add(ut_dulint_align_down(
+ archived_lsn,
+ OS_FILE_LOG_BLOCK_SIZE),
log_group_get_capacity(group));
- finish_lsn2 = ut_dulint_add(ut_dulint_align_up
- (recovered_lsn, OS_FILE_LOG_BLOCK_SIZE),
+ finish_lsn2 = ut_dulint_add(ut_dulint_align_up(
+ recovered_lsn,
+ OS_FILE_LOG_BLOCK_SIZE),
recv_sys->last_log_buf_size);
if (ut_dulint_cmp(limit_lsn, ut_dulint_max) != 0) {
@@ -274,8 +276,8 @@ recv_truncate_group(
ut_memcpy(log_sys->buf, recv_sys->last_block,
OS_FILE_LOG_BLOCK_SIZE);
- log_block_set_data_len(log_sys->buf, ut_dulint_minus
- (recovered_lsn, start_lsn));
+ log_block_set_data_len(log_sys->buf, ut_dulint_minus(
+ recovered_lsn, start_lsn));
}
if (ut_dulint_cmp(start_lsn, finish_lsn) >= 0) {
@@ -441,16 +443,16 @@ recv_check_cp_is_consistent(
fold = ut_fold_binary(buf, LOG_CHECKPOINT_CHECKSUM_1);
- if ((fold & 0xFFFFFFFFUL) != mach_read_from_4
- (buf + LOG_CHECKPOINT_CHECKSUM_1)) {
+ if ((fold & 0xFFFFFFFFUL) != mach_read_from_4(
+ buf + LOG_CHECKPOINT_CHECKSUM_1)) {
return(FALSE);
}
fold = ut_fold_binary(buf + LOG_CHECKPOINT_LSN,
LOG_CHECKPOINT_CHECKSUM_2 - LOG_CHECKPOINT_LSN);
- if ((fold & 0xFFFFFFFFUL) != mach_read_from_4
- (buf + LOG_CHECKPOINT_CHECKSUM_2)) {
+ if ((fold & 0xFFFFFFFFUL) != mach_read_from_4(
+ buf + LOG_CHECKPOINT_CHECKSUM_2)) {
return(FALSE);
}
@@ -498,9 +500,9 @@ recv_find_max_checkpoint(
" %lu at %lu invalid, %lu\n",
(ulong) group->id,
(ulong) field,
- (ulong) mach_read_from_4
- (buf
- + LOG_CHECKPOINT_CHECKSUM_1));
+ (ulong) mach_read_from_4(
+ buf
+ + LOG_CHECKPOINT_CHECKSUM_1));
}
#endif /* UNIV_DEBUG */
@@ -509,20 +511,20 @@ recv_find_max_checkpoint(
group->state = LOG_GROUP_OK;
- group->lsn = mach_read_from_8
- (buf + LOG_CHECKPOINT_LSN);
- group->lsn_offset = mach_read_from_4
- (buf + LOG_CHECKPOINT_OFFSET);
- checkpoint_no = mach_read_from_8
- (buf + LOG_CHECKPOINT_NO);
+ group->lsn = mach_read_from_8(
+ buf + LOG_CHECKPOINT_LSN);
+ group->lsn_offset = mach_read_from_4(
+ buf + LOG_CHECKPOINT_OFFSET);
+ checkpoint_no = mach_read_from_8(
+ buf + LOG_CHECKPOINT_NO);
#ifdef UNIV_DEBUG
if (log_debug_writes) {
fprintf(stderr,
"InnoDB: Checkpoint number %lu"
" found in group %lu\n",
- (ulong) ut_dulint_get_low
- (checkpoint_no),
+ (ulong) ut_dulint_get_low(
+ checkpoint_no),
(ulong) group->id);
}
#endif /* UNIV_DEBUG */
@@ -609,8 +611,8 @@ recv_read_cp_info_for_backup(
if (mach_read_from_4(cp_buf + LOG_CHECKPOINT_FSP_MAGIC_N)
== LOG_CHECKPOINT_FSP_MAGIC_N_VAL) {
- *fsp_limit = mach_read_from_4
- (cp_buf + LOG_CHECKPOINT_FSP_FREE_LIMIT);
+ *fsp_limit = mach_read_from_4(
+ cp_buf + LOG_CHECKPOINT_FSP_FREE_LIMIT);
if (*fsp_limit == 0) {
*fsp_limit = 1000000000;
@@ -779,10 +781,10 @@ recv_parse_or_apply_log_rec_body(
ptr = mlog_parse_nbytes(type, ptr, end_ptr, page);
break;
case MLOG_REC_INSERT: case MLOG_COMP_REC_INSERT:
- if (NULL != (ptr = mlog_parse_index
- (ptr, end_ptr,
- type == MLOG_COMP_REC_INSERT,
- &index))) {
+ if (NULL != (ptr = mlog_parse_index(
+ ptr, end_ptr,
+ type == MLOG_COMP_REC_INSERT,
+ &index))) {
ut_a(!page
|| (ibool)!!page_is_comp(page)
== dict_table_is_comp(index->table));
@@ -791,15 +793,15 @@ recv_parse_or_apply_log_rec_body(
}
break;
case MLOG_REC_CLUST_DELETE_MARK: case MLOG_COMP_REC_CLUST_DELETE_MARK:
- if (NULL != (ptr = mlog_parse_index
- (ptr, end_ptr,
- type == MLOG_COMP_REC_CLUST_DELETE_MARK,
- &index))) {
+ if (NULL != (ptr = mlog_parse_index(
+ ptr, end_ptr,
+ type == MLOG_COMP_REC_CLUST_DELETE_MARK,
+ &index))) {
ut_a(!page
|| (ibool)!!page_is_comp(page)
== dict_table_is_comp(index->table));
- ptr = btr_cur_parse_del_mark_set_clust_rec
- (ptr, end_ptr, index, page);
+ ptr = btr_cur_parse_del_mark_set_clust_rec(
+ ptr, end_ptr, index, page);
}
break;
case MLOG_COMP_REC_SEC_DELETE_MARK:
@@ -815,10 +817,10 @@ recv_parse_or_apply_log_rec_body(
ptr = btr_cur_parse_del_mark_set_sec_rec(ptr, end_ptr, page);
break;
case MLOG_REC_UPDATE_IN_PLACE: case MLOG_COMP_REC_UPDATE_IN_PLACE:
- if (NULL != (ptr = mlog_parse_index
- (ptr, end_ptr,
- type == MLOG_COMP_REC_UPDATE_IN_PLACE,
- &index))) {
+ if (NULL != (ptr = mlog_parse_index(
+ ptr, end_ptr,
+ type == MLOG_COMP_REC_UPDATE_IN_PLACE,
+ &index))) {
ut_a(!page
|| (ibool)!!page_is_comp(page)
== dict_table_is_comp(index->table));
@@ -828,11 +830,11 @@ recv_parse_or_apply_log_rec_body(
break;
case MLOG_LIST_END_DELETE: case MLOG_COMP_LIST_END_DELETE:
case MLOG_LIST_START_DELETE: case MLOG_COMP_LIST_START_DELETE:
- if (NULL != (ptr = mlog_parse_index
- (ptr, end_ptr,
- type == MLOG_COMP_LIST_END_DELETE
- || type == MLOG_COMP_LIST_START_DELETE,
- &index))) {
+ if (NULL != (ptr = mlog_parse_index(
+ ptr, end_ptr,
+ type == MLOG_COMP_LIST_END_DELETE
+ || type == MLOG_COMP_LIST_START_DELETE,
+ &index))) {
ut_a(!page
|| (ibool)!!page_is_comp(page)
== dict_table_is_comp(index->table));
@@ -841,22 +843,22 @@ recv_parse_or_apply_log_rec_body(
}
break;
case MLOG_LIST_END_COPY_CREATED: case MLOG_COMP_LIST_END_COPY_CREATED:
- if (NULL != (ptr = mlog_parse_index
- (ptr, end_ptr,
- type == MLOG_COMP_LIST_END_COPY_CREATED,
- &index))) {
+ if (NULL != (ptr = mlog_parse_index(
+ ptr, end_ptr,
+ type == MLOG_COMP_LIST_END_COPY_CREATED,
+ &index))) {
ut_a(!page
|| (ibool)!!page_is_comp(page)
== dict_table_is_comp(index->table));
- ptr = page_parse_copy_rec_list_to_created_page
- (ptr, end_ptr, index, page, mtr);
+ ptr = page_parse_copy_rec_list_to_created_page(
+ ptr, end_ptr, index, page, mtr);
}
break;
case MLOG_PAGE_REORGANIZE: case MLOG_COMP_PAGE_REORGANIZE:
- if (NULL != (ptr = mlog_parse_index
- (ptr, end_ptr,
- type == MLOG_COMP_PAGE_REORGANIZE,
- &index))) {
+ if (NULL != (ptr = mlog_parse_index(
+ ptr, end_ptr,
+ type == MLOG_COMP_PAGE_REORGANIZE,
+ &index))) {
ut_a(!page
|| (ibool)!!page_is_comp(page)
== dict_table_is_comp(index->table));
@@ -887,15 +889,15 @@ recv_parse_or_apply_log_rec_body(
page, mtr);
break;
case MLOG_REC_MIN_MARK: case MLOG_COMP_REC_MIN_MARK:
- ptr = btr_parse_set_min_rec_mark
- (ptr, end_ptr, type == MLOG_COMP_REC_MIN_MARK,
- page, mtr);
+ ptr = btr_parse_set_min_rec_mark(
+ ptr, end_ptr, type == MLOG_COMP_REC_MIN_MARK,
+ page, mtr);
break;
case MLOG_REC_DELETE: case MLOG_COMP_REC_DELETE:
- if (NULL != (ptr = mlog_parse_index
- (ptr, end_ptr,
- type == MLOG_COMP_REC_DELETE,
- &index))) {
+ if (NULL != (ptr = mlog_parse_index(
+ ptr, end_ptr,
+ type == MLOG_COMP_REC_DELETE,
+ &index))) {
ut_a(!page
|| (ibool)!!page_is_comp(page)
== dict_table_is_comp(index->table));
@@ -1430,8 +1432,8 @@ loop:
RW_X_LATCH, &mtr);
#ifdef UNIV_SYNC_DEBUG
- buf_page_dbg_add_level
- (page, SYNC_NO_ORDER_CHECK);
+ buf_page_dbg_add_level(
+ page, SYNC_NO_ORDER_CHECK);
#endif /* UNIV_SYNC_DEBUG */
recv_recover_page(FALSE, FALSE, page,
space, page_no);
@@ -1570,18 +1572,18 @@ recv_apply_log_recs_for_backup(void)
the block corresponding to buf_pool->frame_zero
(== page). */
- buf_page_init_for_backup_restore
- (recv_addr->space, recv_addr->page_no,
- buf_block_align(page));
+ buf_page_init_for_backup_restore(
+ recv_addr->space, recv_addr->page_no,
+ buf_block_align(page));
/* Extend the tablespace's last file if the page_no
does not fall inside its bounds; we assume the last
file is auto-extending, and ibbackup copied the file
when it still was smaller */
- success = fil_extend_space_to_desired_size
- (&actual_size,
- recv_addr->space, recv_addr->page_no + 1);
+ success = fil_extend_space_to_desired_size(
+ &actual_size,
+ recv_addr->space, recv_addr->page_no + 1);
if (!success) {
fprintf(stderr,
"InnoDB: Fatal error: cannot extend"
@@ -1615,9 +1617,9 @@ recv_apply_log_recs_for_backup(void)
/* Write the page back to the tablespace file using the
fil0fil.c routines */
- buf_flush_init_for_writing
- (page, mach_read_from_8(page + FIL_PAGE_LSN),
- recv_addr->space, recv_addr->page_no);
+ buf_flush_init_for_writing(
+ page, mach_read_from_8(page + FIL_PAGE_LSN),
+ recv_addr->space, recv_addr->page_no);
error = fil_io(OS_FILE_WRITE, TRUE, recv_addr->space,
recv_addr->page_no, 0, UNIV_PAGE_SIZE,
@@ -1916,8 +1918,9 @@ loop:
fil_path_to_mysql_datadir is set in ibbackup to
point to the datadir we should use there */
- if (NULL == fil_op_log_parse_or_replay
- (body, end_ptr, type, TRUE, space)) {
+ if (NULL == fil_op_log_parse_or_replay(
+ body, end_ptr, type, TRUE,
+ space)) {
fprintf(stderr,
"InnoDB: Error: file op"
" log record of type %lu"
@@ -1956,8 +1959,8 @@ loop:
if (recv_sys->found_corrupt_log) {
- recv_report_corrupt_log
- (ptr, type, space, page_no);
+ recv_report_corrupt_log(
+ ptr, type, space, page_no);
}
return(FALSE);
@@ -1998,8 +2001,8 @@ loop:
}
}
- new_recovered_lsn = recv_calc_lsn_on_data_add
- (recv_sys->recovered_lsn, total_len);
+ new_recovered_lsn = recv_calc_lsn_on_data_add(
+ recv_sys->recovered_lsn, total_len);
if (ut_dulint_cmp(new_recovered_lsn, recv_sys->scanned_lsn)
> 0) {
@@ -2202,22 +2205,21 @@ recv_scan_log_recs(
|| !log_block_checksum_is_ok_or_old_format(log_block)) {
if (no == log_block_convert_lsn_to_no(scanned_lsn)
- && !log_block_checksum_is_ok_or_old_format
- (log_block)) {
+ && !log_block_checksum_is_ok_or_old_format(
+ log_block)) {
fprintf(stderr,
"InnoDB: Log block no %lu at"
" lsn %lu %lu has\n"
"InnoDB: ok header, but checksum field"
" contains %lu, should be %lu\n",
(ulong) no,
- (ulong) ut_dulint_get_high
- (scanned_lsn),
- (ulong) ut_dulint_get_low
- (scanned_lsn),
- (ulong) log_block_get_checksum
- (log_block),
- (ulong) log_block_calc_checksum
- (log_block));
+ (ulong) ut_dulint_get_high(
+ scanned_lsn),
+ (ulong) ut_dulint_get_low(scanned_lsn),
+ (ulong) log_block_get_checksum(
+ log_block),
+ (ulong) log_block_calc_checksum(
+ log_block));
}
/* Garbage or an incompletely written log block */
@@ -2273,8 +2275,8 @@ recv_scan_log_recs(
recv_sys->parse_start_lsn
= ut_dulint_add(scanned_lsn,
- log_block_get_first_rec_group
- (log_block));
+ log_block_get_first_rec_group(
+ log_block));
recv_sys->scanned_lsn = recv_sys->parse_start_lsn;
recv_sys->recovered_lsn = recv_sys->parse_start_lsn;
}
@@ -2297,8 +2299,8 @@ recv_scan_log_recs(
recv_sys->found_corrupt_log = TRUE;
} else if (!recv_sys->found_corrupt_log) {
- more_data = recv_sys_add_to_parsing_buf
- (log_block, scanned_lsn);
+ more_data = recv_sys_add_to_parsing_buf(
+ log_block, scanned_lsn);
}
recv_sys->scanned_lsn = scanned_lsn;
@@ -2385,11 +2387,10 @@ recv_group_scan_log_recs(
log_group_read_log_seg(LOG_RECOVER, log_sys->buf,
group, start_lsn, end_lsn);
- finished = recv_scan_log_recs
- (TRUE, (buf_pool->n_frames - recv_n_pool_free_frames)
- * UNIV_PAGE_SIZE, TRUE, log_sys->buf,
- RECV_SCAN_SIZE, start_lsn,
- contiguous_lsn, group_scanned_lsn);
+ finished = recv_scan_log_recs(
+ TRUE, (buf_pool->n_frames - recv_n_pool_free_frames)
+ * UNIV_PAGE_SIZE, TRUE, log_sys->buf, RECV_SCAN_SIZE,
+ start_lsn, contiguous_lsn, group_scanned_lsn);
start_lsn = end_lsn;
}
@@ -2561,18 +2562,18 @@ recv_recovery_from_checkpoint_start(
"InnoDB: %lu %lu and %lu %lu.\n"
"InnoDB: #########################"
"#################################\n",
- (ulong) ut_dulint_get_high
- (checkpoint_lsn),
- (ulong) ut_dulint_get_low
- (checkpoint_lsn),
- (ulong) ut_dulint_get_high
- (min_flushed_lsn),
- (ulong) ut_dulint_get_low
- (min_flushed_lsn),
- (ulong) ut_dulint_get_high
- (max_flushed_lsn),
- (ulong) ut_dulint_get_low
- (max_flushed_lsn));
+ (ulong) ut_dulint_get_high(
+ checkpoint_lsn),
+ (ulong) ut_dulint_get_low(
+ checkpoint_lsn),
+ (ulong) ut_dulint_get_high(
+ min_flushed_lsn),
+ (ulong) ut_dulint_get_low(
+ min_flushed_lsn),
+ (ulong) ut_dulint_get_high(
+ max_flushed_lsn),
+ (ulong) ut_dulint_get_low(
+ max_flushed_lsn));
}
recv_needed_recovery = TRUE;
@@ -2602,8 +2603,8 @@ recv_recovery_from_checkpoint_start(
" half-written data pages from"
" the doublewrite\n"
"InnoDB: buffer...\n");
- trx_sys_doublewrite_init_or_restore_pages
- (TRUE);
+ trx_sys_doublewrite_init_or_restore_pages(
+ TRUE);
}
ut_print_timestamp(stderr);
@@ -2629,10 +2630,10 @@ recv_recovery_from_checkpoint_start(
group = recv_sys->archive_group;
capacity = log_group_get_capacity(group);
- if ((ut_dulint_cmp(recv_sys->scanned_lsn, ut_dulint_add
- (checkpoint_lsn, capacity)) > 0)
- || (ut_dulint_cmp(checkpoint_lsn, ut_dulint_add
- (recv_sys->scanned_lsn, capacity))
+ if ((ut_dulint_cmp(recv_sys->scanned_lsn, ut_dulint_add(
+ checkpoint_lsn, capacity)) > 0)
+ || (ut_dulint_cmp(checkpoint_lsn, ut_dulint_add(
+ recv_sys->scanned_lsn, capacity))
> 0)) {
mutex_exit(&(log_sys->mutex));
@@ -2756,10 +2757,10 @@ recv_recovery_from_checkpoint_start(
" lsn %lu %lu up to lsn %lu %lu\n",
(ulong) ut_dulint_get_high(checkpoint_lsn),
(ulong) ut_dulint_get_low(checkpoint_lsn),
- (ulong) ut_dulint_get_high
- (recv_sys->recovered_lsn),
- (ulong) ut_dulint_get_low
- (recv_sys->recovered_lsn));
+ (ulong) ut_dulint_get_high(
+ recv_sys->recovered_lsn),
+ (ulong) ut_dulint_get_low(
+ recv_sys->recovered_lsn));
}
} else {
srv_start_lsn = recv_sys->recovered_lsn;
@@ -3189,10 +3190,10 @@ ask_again:
group->archive_space_id, read_offset / UNIV_PAGE_SIZE,
read_offset % UNIV_PAGE_SIZE, len, buf, NULL);
- ret = recv_scan_log_recs
- (TRUE, (buf_pool->n_frames - recv_n_pool_free_frames)
- * UNIV_PAGE_SIZE, TRUE, buf, len, start_lsn,
- &dummy_lsn, &scanned_lsn);
+ ret = recv_scan_log_recs(
+ TRUE, (buf_pool->n_frames - recv_n_pool_free_frames)
+ * UNIV_PAGE_SIZE, TRUE, buf, len, start_lsn,
+ &dummy_lsn, &scanned_lsn);
if (ut_dulint_cmp(scanned_lsn, file_end_lsn) == 0) {
diff --git a/storage/innobase/mem/mem0dbg.c b/storage/innobase/mem/mem0dbg.c
index 3cab454e3ac..419f410cf1b 100644
--- a/storage/innobase/mem/mem0dbg.c
+++ b/storage/innobase/mem/mem0dbg.c
@@ -497,8 +497,8 @@ mem_heap_validate_or_print(
" %lx but trailer %lx\n",
(ulint)block,
(ulint)field, len, check_field,
- mem_field_trailer_get_check
- (user_field));
+ mem_field_trailer_get_check(
+ user_field));
return;
}
diff --git a/storage/innobase/mem/mem0pool.c b/storage/innobase/mem/mem0pool.c
index 91e7532aba8..6a419ff33ec 100644
--- a/storage/innobase/mem/mem0pool.c
+++ b/storage/innobase/mem/mem0pool.c
@@ -501,8 +501,8 @@ mem_area_free(
ulint next_size;
- next_size = mem_area_get_size
- ((mem_area_t*)(((byte*)area) + size));
+ next_size = mem_area_get_size(
+ (mem_area_t*)(((byte*)area) + size));
if (ut_2_power_up(next_size) != next_size) {
fprintf(stderr,
"InnoDB: Error: Memory area size %lu,"
diff --git a/storage/innobase/mtr/mtr0log.c b/storage/innobase/mtr/mtr0log.c
index ba5284d9169..cb03f207a56 100644
--- a/storage/innobase/mtr/mtr0log.c
+++ b/storage/innobase/mtr/mtr0log.c
@@ -445,21 +445,21 @@ mlog_open_and_write_index(
dict_index_get_n_unique_in_tree(index));
log_ptr += 2;
for (i = 0; i < n; i++) {
- dict_field_t* field;
- dtype_t* type;
- ulint len;
+ dict_field_t* field;
+ const dict_col_t* col;
+ ulint len;
+
field = dict_index_get_nth_field(index, i);
- type = dict_col_get_type(dict_field_get_col(field));
+ col = dict_field_get_col(field);
len = field->fixed_len;
ut_ad(len < 0x7fff);
if (len == 0
- && (dtype_get_len(type) > 255
- || dtype_get_mtype(type) == DATA_BLOB)) {
+ && (col->len > 255 || col->mtype == DATA_BLOB)) {
/* variable-length field
with maximum length > 255 */
len = 0x7fff;
}
- if (dtype_get_prtype(type) & DATA_NOT_NULL) {
+ if (col->prtype & DATA_NOT_NULL) {
len |= 0x8000;
}
if (log_ptr + 2 > log_end) {
@@ -541,14 +541,16 @@ mlog_parse_index(
/* The high-order bit of len is the NOT NULL flag;
the rest is 0 or 0x7fff for variable-length fields,
and 1..0x7ffe for fixed-length fields. */
- dict_mem_table_add_col
- (table, "DUMMY",
- ((len + 1) & 0x7fff) <= 1
- ? DATA_BINARY : DATA_FIXBINARY,
- len & 0x8000 ? DATA_NOT_NULL : 0,
- len & 0x7fff, 0);
- dict_index_add_col
- (ind, dict_table_get_nth_col(table, i), 0);
+ dict_mem_table_add_col(
+ table, "DUMMY",
+ ((len + 1) & 0x7fff) <= 1
+ ? DATA_BINARY : DATA_FIXBINARY,
+ len & 0x8000 ? DATA_NOT_NULL : 0,
+ len & 0x7fff);
+
+ dict_index_add_col(ind, table, (dict_col_t*)
+ dict_table_get_nth_col(table, i),
+ 0);
}
ptr += 2;
}
diff --git a/storage/innobase/mtr/mtr0mtr.c b/storage/innobase/mtr/mtr0mtr.c
index 13c579c646b..1a65da6e7f4 100644
--- a/storage/innobase/mtr/mtr0mtr.c
+++ b/storage/innobase/mtr/mtr0mtr.c
@@ -131,9 +131,9 @@ mtr_log_reserve_and_write(
}
if (mlog->heap == NULL) {
- mtr->end_lsn = log_reserve_and_write_fast
- (first_data, dyn_block_get_used(mlog),
- &(mtr->start_lsn), &success);
+ mtr->end_lsn = log_reserve_and_write_fast(
+ first_data, dyn_block_get_used(mlog),
+ &(mtr->start_lsn), &success);
if (success) {
return;
diff --git a/storage/innobase/os/os0file.c b/storage/innobase/os/os0file.c
index 65903717cfb..a4acb0cd485 100644
--- a/storage/innobase/os/os0file.c
+++ b/storage/innobase/os/os0file.c
@@ -3483,9 +3483,9 @@ try_again:
#endif
} else {
if (!wake_later) {
- os_aio_simulated_wake_handler_thread
- (os_aio_get_segment_no_from_slot
- (array, slot));
+ os_aio_simulated_wake_handler_thread(
+ os_aio_get_segment_no_from_slot(
+ array, slot));
}
}
} else if (type == OS_FILE_WRITE) {
@@ -3501,9 +3501,9 @@ try_again:
#endif
} else {
if (!wake_later) {
- os_aio_simulated_wake_handler_thread
- (os_aio_get_segment_no_from_slot
- (array, slot));
+ os_aio_simulated_wake_handler_thread(
+ os_aio_get_segment_no_from_slot(
+ array, slot));
}
}
} else {
diff --git a/storage/innobase/os/os0thread.c b/storage/innobase/os/os0thread.c
index 0c9434ccc7f..a0b1e51d359 100644
--- a/storage/innobase/os/os0thread.c
+++ b/storage/innobase/os/os0thread.c
@@ -142,8 +142,9 @@ os_thread_create(
AIX is always big enough. An empirical test on AIX-4.3 suggested
the size was 96 kB, though. */
- ret = pthread_attr_setstacksize
- (&attr, (size_t)(PTHREAD_STACK_MIN + 32 * 1024));
+ ret = pthread_attr_setstacksize(&attr,
+ (size_t)(PTHREAD_STACK_MIN
+ + 32 * 1024));
if (ret) {
fprintf(stderr,
"InnoDB: Error: pthread_attr_setstacksize"
diff --git a/storage/innobase/page/page0cur.c b/storage/innobase/page/page0cur.c
index 2a440c4f479..a297eb545a0 100644
--- a/storage/innobase/page/page0cur.c
+++ b/storage/innobase/page/page0cur.c
@@ -259,11 +259,11 @@ page_cur_search_with_match(
&& (page_header_get_ptr(page, PAGE_LAST_INSERT))
&& (page_header_get_field(page, PAGE_DIRECTION) == PAGE_RIGHT)) {
- if (page_cur_try_search_shortcut
- (page, index, tuple,
- iup_matched_fields, iup_matched_bytes,
- ilow_matched_fields, ilow_matched_bytes,
- cursor)) {
+ if (page_cur_try_search_shortcut(
+ page, index, tuple,
+ iup_matched_fields, iup_matched_bytes,
+ ilow_matched_fields, ilow_matched_bytes,
+ cursor)) {
return;
}
}
@@ -326,8 +326,9 @@ low_slot_match:
} else if (UNIV_EXPECT(cmp, -1)) {
#ifdef PAGE_CUR_LE_OR_EXTENDS
if (mode == PAGE_CUR_LE_OR_EXTENDS
- && page_cur_rec_field_extends
- (tuple, mid_rec, offsets, cur_matched_fields)) {
+ && page_cur_rec_field_extends(
+ tuple, mid_rec, offsets,
+ cur_matched_fields)) {
goto low_slot_match;
}
@@ -382,8 +383,9 @@ low_rec_match:
} else if (UNIV_EXPECT(cmp, -1)) {
#ifdef PAGE_CUR_LE_OR_EXTENDS
if (mode == PAGE_CUR_LE_OR_EXTENDS
- && page_cur_rec_field_extends
- (tuple, mid_rec, offsets, cur_matched_fields)) {
+ && page_cur_rec_field_extends(
+ tuple, mid_rec, offsets,
+ cur_matched_fields)) {
goto low_rec_match;
}
@@ -645,9 +647,9 @@ page_cur_insert_rec_write_log(
+ extra_info_yes);
if (extra_info_yes) {
/* Write the info bits */
- mach_write_to_1
- (log_ptr,
- rec_get_info_and_status_bits(insert_rec, comp));
+ mach_write_to_1(log_ptr,
+ rec_get_info_and_status_bits(insert_rec,
+ comp));
log_ptr++;
/* Write the record origin offset */
@@ -796,8 +798,8 @@ page_cur_parse_insert_rec(
ULINT_UNDEFINED, &heap);
if (extra_info_yes == 0) {
- info_and_status_bits = rec_get_info_and_status_bits
- (cursor_rec, page_is_comp(page));
+ info_and_status_bits = rec_get_info_and_status_bits(
+ cursor_rec, page_is_comp(page));
origin_offset = rec_offs_extra_size(offsets);
mismatch_index = rec_offs_size(offsets) - end_seg_len;
}
@@ -975,8 +977,8 @@ page_cur_insert_rec_low(
page_header_set_field(page, PAGE_DIRECTION, PAGE_RIGHT);
page_header_set_field(page, PAGE_N_DIRECTION,
- page_header_get_field
- (page, PAGE_N_DIRECTION) + 1);
+ page_header_get_field(
+ page, PAGE_N_DIRECTION) + 1);
} else if ((page_rec_get_next(insert_rec) == last_insert)
&& (page_header_get_field(page, PAGE_DIRECTION)
@@ -984,8 +986,8 @@ page_cur_insert_rec_low(
page_header_set_field(page, PAGE_DIRECTION, PAGE_LEFT);
page_header_set_field(page, PAGE_N_DIRECTION,
- page_header_get_field
- (page, PAGE_N_DIRECTION) + 1);
+ page_header_get_field(
+ page, PAGE_N_DIRECTION) + 1);
} else {
page_header_set_field(page, PAGE_DIRECTION, PAGE_NO_DIRECTION);
page_header_set_field(page, PAGE_N_DIRECTION, 0);
@@ -1278,7 +1280,7 @@ page_cur_delete_rec_write_log(
}
/* Write the cursor rec offset as a 2-byte ulint */
- mach_write_to_2(log_ptr, ut_align_offset(rec, UNIV_PAGE_SIZE));
+ mach_write_to_2(log_ptr, page_offset(rec));
mlog_close(mtr, log_ptr + 2);
}
diff --git a/storage/innobase/page/page0page.c b/storage/innobase/page/page0page.c
index 0c869445546..4212df7a631 100644
--- a/storage/innobase/page/page0page.c
+++ b/storage/innobase/page/page0page.c
@@ -381,7 +381,7 @@ page_create(
dfield_set_data(field, "infimum", 8);
dtype_set(dfield_get_type(field),
- DATA_VARCHAR, DATA_ENGLISH | DATA_NOT_NULL, 8, 0);
+ DATA_VARCHAR, DATA_ENGLISH | DATA_NOT_NULL, 8);
/* Set the corresponding physical record to its place in the page
record heap */
@@ -407,7 +407,7 @@ page_create(
dfield_set_data(field, "supremum", comp ? 8 : 9);
dtype_set(dfield_get_type(field),
- DATA_VARCHAR, DATA_ENGLISH | DATA_NOT_NULL, comp ? 8 : 9, 0);
+ DATA_VARCHAR, DATA_ENGLISH | DATA_NOT_NULL, comp ? 8 : 9);
supremum_rec = rec_convert_dtuple_to_rec(heap_top, index, tuple);
@@ -650,7 +650,7 @@ page_delete_rec_list_write_log(
log_ptr = mlog_open_and_write_index(mtr, rec, index, type, 2);
if (log_ptr) {
/* Write the parameter as a 2-byte ulint */
- mach_write_to_2(log_ptr, ut_align_offset(rec, UNIV_PAGE_SIZE));
+ mach_write_to_2(log_ptr, page_offset(rec));
mlog_close(mtr, log_ptr + 2);
}
}
diff --git a/storage/innobase/pars/pars0opt.c b/storage/innobase/pars/pars0opt.c
index 7c564d3ee4c..2abe6720235 100644
--- a/storage/innobase/pars/pars0opt.c
+++ b/storage/innobase/pars/pars0opt.c
@@ -333,9 +333,9 @@ opt_calc_index_goodness(
col_no = dict_index_get_nth_col_no(index, j);
- exp = opt_look_for_col_in_cond_before
- (OPT_EQUAL, col_no, sel_node->search_cond,
- sel_node, nth_table, &op);
+ exp = opt_look_for_col_in_cond_before(
+ OPT_EQUAL, col_no, sel_node->search_cond,
+ sel_node, nth_table, &op);
if (exp) {
/* The value for this column is exactly known already
at this stage of the join */
@@ -346,9 +346,9 @@ opt_calc_index_goodness(
} else {
/* Look for non-equality comparisons */
- exp = opt_look_for_col_in_cond_before
- (OPT_COMPARISON, col_no, sel_node->search_cond,
- sel_node, nth_table, &op);
+ exp = opt_look_for_col_in_cond_before(
+ OPT_COMPARISON, col_no, sel_node->search_cond,
+ sel_node, nth_table, &op);
if (exp) {
index_plan[j] = exp;
*last_op = op;
@@ -675,10 +675,11 @@ opt_classify_comparison(
access the table, it is classified as OPT_END_COND */
if ((dict_index_get_n_fields(plan->index) > plan->n_exact_match)
- && opt_look_for_col_in_comparison_before
- (OPT_COMPARISON,
- dict_index_get_nth_col_no(plan->index, plan->n_exact_match),
- cond, sel_node, i, &op)) {
+ && opt_look_for_col_in_comparison_before(
+ OPT_COMPARISON,
+ dict_index_get_nth_col_no(plan->index,
+ plan->n_exact_match),
+ cond, sel_node, i, &op)) {
if (sel_node->asc && ((op == '<') || (op == PARS_LE_TOKEN))) {
@@ -903,8 +904,8 @@ opt_find_all_cols(
/* Fill in the field_no fields in sym_node */
- sym_node->field_nos[SYM_CLUST_FIELD_NO] = dict_index_get_nth_col_pos
- (dict_table_get_first_index(index->table), sym_node->col_no);
+ sym_node->field_nos[SYM_CLUST_FIELD_NO] = dict_index_get_nth_col_pos(
+ dict_table_get_first_index(index->table), sym_node->col_no);
if (!(index->type & DICT_CLUSTERED)) {
ut_a(plan);
diff --git a/storage/innobase/pars/pars0pars.c b/storage/innobase/pars/pars0pars.c
index 214fff68c55..6861844870c 100644
--- a/storage/innobase/pars/pars0pars.c
+++ b/storage/innobase/pars/pars0pars.c
@@ -254,43 +254,43 @@ pars_resolve_func_data_type(
== DATA_INT);
} else if (func == PARS_COUNT_TOKEN) {
ut_a(arg);
- dtype_set(que_node_get_data_type(node), DATA_INT, 0, 4, 0);
+ dtype_set(que_node_get_data_type(node), DATA_INT, 0, 4);
} else if (func == PARS_TO_CHAR_TOKEN) {
ut_a(dtype_get_mtype(que_node_get_data_type(arg)) == DATA_INT);
dtype_set(que_node_get_data_type(node), DATA_VARCHAR,
- DATA_ENGLISH, 0, 0);
+ DATA_ENGLISH, 0);
} else if (func == PARS_TO_BINARY_TOKEN) {
if (dtype_get_mtype(que_node_get_data_type(arg)) == DATA_INT) {
dtype_set(que_node_get_data_type(node), DATA_VARCHAR,
- DATA_ENGLISH, 0, 0);
+ DATA_ENGLISH, 0);
} else {
dtype_set(que_node_get_data_type(node), DATA_BINARY,
- 0, 0, 0);
+ 0, 0);
}
} else if (func == PARS_TO_NUMBER_TOKEN) {
ut_a(dtype_get_mtype(que_node_get_data_type(arg))
== DATA_VARCHAR);
- dtype_set(que_node_get_data_type(node), DATA_INT, 0, 4, 0);
+ dtype_set(que_node_get_data_type(node), DATA_INT, 0, 4);
} else if (func == PARS_BINARY_TO_NUMBER_TOKEN) {
ut_a(dtype_get_mtype(que_node_get_data_type(arg))
== DATA_VARCHAR);
- dtype_set(que_node_get_data_type(node), DATA_INT, 0, 4, 0);
+ dtype_set(que_node_get_data_type(node), DATA_INT, 0, 4);
} else if (func == PARS_LENGTH_TOKEN) {
ut_a(dtype_get_mtype(que_node_get_data_type(arg))
== DATA_VARCHAR);
- dtype_set(que_node_get_data_type(node), DATA_INT, 0, 4, 0);
+ dtype_set(que_node_get_data_type(node), DATA_INT, 0, 4);
} else if (func == PARS_INSTR_TOKEN) {
ut_a(dtype_get_mtype(que_node_get_data_type(arg))
== DATA_VARCHAR);
- dtype_set(que_node_get_data_type(node), DATA_INT, 0, 4, 0);
+ dtype_set(que_node_get_data_type(node), DATA_INT, 0, 4);
} else if (func == PARS_SYSDATE_TOKEN) {
ut_a(arg == NULL);
- dtype_set(que_node_get_data_type(node), DATA_INT, 0, 4, 0);
+ dtype_set(que_node_get_data_type(node), DATA_INT, 0, 4);
} else if ((func == PARS_SUBSTR_TOKEN)
|| (func == PARS_CONCAT_TOKEN)) {
@@ -298,7 +298,7 @@ pars_resolve_func_data_type(
ut_a(dtype_get_mtype(que_node_get_data_type(arg))
== DATA_VARCHAR);
dtype_set(que_node_get_data_type(node), DATA_VARCHAR,
- DATA_ENGLISH, 0, 0);
+ DATA_ENGLISH, 0);
} else if ((func == '>') || (func == '<') || (func == '=')
|| (func == PARS_GE_TOKEN)
@@ -310,18 +310,18 @@ pars_resolve_func_data_type(
|| (func == PARS_NOTFOUND_TOKEN)) {
/* We currently have no iboolean type: use integer type */
- dtype_set(que_node_get_data_type(node), DATA_INT, 0, 4, 0);
+ dtype_set(que_node_get_data_type(node), DATA_INT, 0, 4);
} else if (func == PARS_RND_TOKEN) {
ut_a(dtype_get_mtype(que_node_get_data_type(arg)) == DATA_INT);
- dtype_set(que_node_get_data_type(node), DATA_INT, 0, 4, 0);
+ dtype_set(que_node_get_data_type(node), DATA_INT, 0, 4);
} else if (func == PARS_RND_STR_TOKEN) {
ut_a(dtype_get_mtype(que_node_get_data_type(arg)) == DATA_INT);
dtype_set(que_node_get_data_type(node), DATA_VARCHAR,
- DATA_ENGLISH, 0, 0);
+ DATA_ENGLISH, 0);
} else {
ut_error;
}
@@ -450,7 +450,6 @@ pars_resolve_exp_columns(
sym_node_t* sym_node;
dict_table_t* table;
sym_node_t* t_node;
- dict_col_t* col;
ulint n_cols;
ulint i;
@@ -490,10 +489,13 @@ pars_resolve_exp_columns(
n_cols = dict_table_get_n_cols(table);
for (i = 0; i < n_cols; i++) {
- col = dict_table_get_nth_col(table, i);
+ const dict_col_t* col
+ = dict_table_get_nth_col(table, i);
+ const char* col_name
+ = dict_table_get_col_name(table, i);
- if ((sym_node->name_len == ut_strlen(col->name))
- && (0 == ut_memcmp(sym_node->name, col->name,
+ if ((sym_node->name_len == ut_strlen(col_name))
+ && (0 == ut_memcmp(sym_node->name, col_name,
sym_node->name_len))) {
/* Found */
sym_node->resolved = TRUE;
@@ -502,8 +504,10 @@ pars_resolve_exp_columns(
sym_node->col_no = i;
sym_node->prefetch_buf = NULL;
- dfield_set_type(&(sym_node->common.val),
- dict_col_get_type(col));
+ dict_col_copy_type(
+ col,
+ dfield_get_type(&sym_node
+ ->common.val));
return;
}
@@ -592,7 +596,6 @@ pars_select_all_columns(
sym_node_t* col_node;
sym_node_t* table_node;
dict_table_t* table;
- dict_col_t* col;
ulint i;
select_node->select_list = NULL;
@@ -603,15 +606,15 @@ pars_select_all_columns(
table = table_node->table;
for (i = 0; i < dict_table_get_n_user_cols(table); i++) {
-
- col = dict_table_get_nth_col(table, i);
+ const char* col_name = dict_table_get_col_name(
+ table, i);
col_node = sym_tab_add_id(pars_sym_tab_global,
- (byte*)col->name,
- ut_strlen(col->name));
- select_node->select_list
- = que_node_list_add_last
- (select_node->select_list, col_node);
+ (byte*)col_name,
+ ut_strlen(col_name));
+
+ select_node->select_list = que_node_list_add_last(
+ select_node->select_list, col_node);
}
table_node = que_node_get_next(table_node);
@@ -888,10 +891,12 @@ pars_process_assign_list(
pars_resolve_exp_columns(table_sym, assign_node->val);
pars_resolve_exp_variables_and_types(NULL, assign_node->val);
#if 0
- ut_a(dtype_get_mtype
- (dfield_get_type(que_node_get_val(assign_node->col)))
- == dtype_get_mtype
- (dfield_get_type(que_node_get_val(assign_node->val))));
+ ut_a(dtype_get_mtype(
+ dfield_get_type(que_node_get_val(
+ assign_node->col)))
+ == dtype_get_mtype(
+ dfield_get_type(que_node_get_val(
+ assign_node->val))));
#endif
/* Add to the update node all the columns found in assignment
@@ -915,13 +920,14 @@ pars_process_assign_list(
col_sym = assign_node->col;
- upd_field_set_field_no(upd_field, dict_index_get_nth_col_pos
- (clust_index, col_sym->col_no),
+ upd_field_set_field_no(upd_field, dict_index_get_nth_col_pos(
+ clust_index, col_sym->col_no),
clust_index, NULL);
upd_field->exp = assign_node->val;
- if (!dtype_is_fixed_size(dict_index_get_nth_type
- (clust_index, upd_field->field_no))) {
+ if (!dict_col_get_fixed_size(
+ dict_index_get_nth_col(clust_index,
+ upd_field->field_no))) {
changes_field_size = 0;
}
@@ -1126,23 +1132,23 @@ pars_set_dfield_type(
if (type == &pars_int_token) {
ut_a(len == 0);
- dtype_set(dfield_get_type(dfield), DATA_INT, flags, 4, 0);
+ dtype_set(dfield_get_type(dfield), DATA_INT, flags, 4);
} else if (type == &pars_char_token) {
ut_a(len == 0);
dtype_set(dfield_get_type(dfield), DATA_VARCHAR,
- DATA_ENGLISH | flags, 0, 0);
+ DATA_ENGLISH | flags, 0);
} else if (type == &pars_binary_token) {
ut_a(len != 0);
dtype_set(dfield_get_type(dfield), DATA_FIXBINARY,
- DATA_BINARY_TYPE | flags, len, 0);
+ DATA_BINARY_TYPE | flags, len);
} else if (type == &pars_blob_token) {
ut_a(len == 0);
dtype_set(dfield_get_type(dfield), DATA_BLOB,
- DATA_BINARY_TYPE | flags, 0, 0);
+ DATA_BINARY_TYPE | flags, 0);
} else {
ut_error;
}
@@ -1599,7 +1605,8 @@ pars_create_table(
sym_node_t* table_sym, /* in: table name node in the symbol
table */
sym_node_t* column_defs, /* in: list of column names */
- void* not_fit_in_memory)/* in: a non-NULL pointer means that
+ void* not_fit_in_memory __attribute__((unused)))
+ /* in: a non-NULL pointer means that
this is a table which in simulations
should be simulated as not fitting
in memory; thread is put to sleep
@@ -1623,18 +1630,18 @@ pars_create_table(
create tables in the old (not compact) record format. */
table = dict_mem_table_create(table_sym->name, 0, n_cols, 0);
+#ifdef UNIV_DEBUG
if (not_fit_in_memory != NULL) {
table->does_not_fit_in_memory = TRUE;
}
-
+#endif /* UNIV_DEBUG */
column = column_defs;
while (column) {
dtype = dfield_get_type(que_node_get_val(column));
dict_mem_table_add_col(table, column->name, dtype->mtype,
- dtype->prtype, dtype->len,
- dtype->prec);
+ dtype->prtype, dtype->len);
column->resolved = TRUE;
column->token_type = SYM_COLUMN;
@@ -1859,8 +1866,8 @@ pars_sql(
pars_sym_tab_global = sym_tab_create(heap);
pars_sym_tab_global->string_len = strlen(str);
- pars_sym_tab_global->sql_string = mem_heap_dup
- (heap, str, pars_sym_tab_global->string_len + 1);
+ pars_sym_tab_global->sql_string = mem_heap_dup(
+ heap, str, pars_sym_tab_global->string_len + 1);
pars_sym_tab_global->next_char_pos = 0;
pars_sym_tab_global->info = info;
diff --git a/storage/innobase/pars/pars0sym.c b/storage/innobase/pars/pars0sym.c
index 8d691febb14..2d56fff2d42 100644
--- a/storage/innobase/pars/pars0sym.c
+++ b/storage/innobase/pars/pars0sym.c
@@ -102,7 +102,7 @@ sym_tab_add_int_lit(
node->indirection = NULL;
- dtype_set(&(node->common.val.type), DATA_INT, 0, 4, 0);
+ dtype_set(&(node->common.val.type), DATA_INT, 0, 4);
data = mem_heap_alloc(sym_tab->heap, 4);
mach_write_to_4(data, val);
@@ -144,7 +144,7 @@ sym_tab_add_str_lit(
node->indirection = NULL;
- dtype_set(&(node->common.val.type), DATA_VARCHAR, DATA_ENGLISH, 0, 0);
+ dtype_set(&(node->common.val.type), DATA_VARCHAR, DATA_ENGLISH, 0);
if (len) {
data = mem_heap_alloc(sym_tab->heap, len);
@@ -226,7 +226,7 @@ sym_tab_add_bound_lit(
ut_error;
}
- dtype_set(&(node->common.val.type), blit->type, blit->prtype, len, 0);
+ dtype_set(&(node->common.val.type), blit->type, blit->prtype, len);
dfield_set_data(&(node->common.val), blit->address, blit->length);
diff --git a/storage/innobase/read/read0read.c b/storage/innobase/read/read0read.c
index 4b9a116c3c1..2375c35190a 100644
--- a/storage/innobase/read/read0read.c
+++ b/storage/innobase/read/read0read.c
@@ -200,8 +200,9 @@ read_view_oldest_copy_or_open_new(
insert_done = 1;
} else {
read_view_set_nth_trx_id(view_copy, i,
- read_view_get_nth_trx_id
- (old_view, i - insert_done));
+ read_view_get_nth_trx_id(
+ old_view,
+ i - insert_done));
}
i++;
@@ -216,8 +217,8 @@ read_view_oldest_copy_or_open_new(
if (n > 0) {
/* The last active transaction has the smallest id: */
- view_copy->up_limit_id = read_view_get_nth_trx_id
- (view_copy, n - 1);
+ view_copy->up_limit_id = read_view_get_nth_trx_id(
+ view_copy, n - 1);
} else {
view_copy->up_limit_id = old_view->up_limit_id;
}
@@ -379,10 +380,10 @@ read_view_print(
for (i = 0; i < n_ids; i++) {
fprintf(stderr, "Read view trx id %lu %lu\n",
- (ulong) ut_dulint_get_high
- (read_view_get_nth_trx_id(view, i)),
- (ulong) ut_dulint_get_low
- (read_view_get_nth_trx_id(view, i)));
+ (ulong) ut_dulint_get_high(
+ read_view_get_nth_trx_id(view, i)),
+ (ulong) ut_dulint_get_low(
+ read_view_get_nth_trx_id(view, i)));
}
}
@@ -420,8 +421,8 @@ read_cursor_view_create_for_mysql(
mutex_enter(&kernel_mutex);
- curview->read_view = read_view_create_low
- (UT_LIST_GET_LEN(trx_sys->trx_list), curview->heap);
+ curview->read_view = read_view_create_low(
+ UT_LIST_GET_LEN(trx_sys->trx_list), curview->heap);
view = curview->read_view;
view->creator_trx_id = cr_trx->id;
diff --git a/storage/innobase/rem/rem0cmp.c b/storage/innobase/rem/rem0cmp.c
index 57a028352fc..07e5b64c157 100644
--- a/storage/innobase/rem/rem0cmp.c
+++ b/storage/innobase/rem/rem0cmp.c
@@ -92,47 +92,48 @@ cmp_collate(
}
/*****************************************************************
-Returns TRUE if two types are equal for comparison purposes. */
+Returns TRUE if two columns are equal for comparison purposes. */
ibool
-cmp_types_are_equal(
-/*================*/
- /* out: TRUE if the types are considered
- equal in comparisons */
- dtype_t* type1, /* in: type 1 */
- dtype_t* type2, /* in: type 2 */
- ibool check_charsets) /* in: whether to check charsets */
+cmp_cols_are_equal(
+/*===============*/
+ /* out: TRUE if the columns are
+ considered equal in comparisons */
+ const dict_col_t* col1, /* in: column 1 */
+ const dict_col_t* col2, /* in: column 2 */
+ ibool check_charsets)
+ /* in: whether to check charsets */
{
- if (dtype_is_non_binary_string_type(type1->mtype, type1->prtype)
- && dtype_is_non_binary_string_type(type2->mtype, type2->prtype)) {
+ if (dtype_is_non_binary_string_type(col1->mtype, col1->prtype)
+ && dtype_is_non_binary_string_type(col2->mtype, col2->prtype)) {
/* Both are non-binary string types: they can be compared if
and only if the charset-collation is the same */
if (check_charsets) {
- return(dtype_get_charset_coll(type1->prtype)
- == dtype_get_charset_coll(type2->prtype));
+ return(dtype_get_charset_coll(col1->prtype)
+ == dtype_get_charset_coll(col2->prtype));
} else {
return(TRUE);
}
}
- if (dtype_is_binary_string_type(type1->mtype, type1->prtype)
- && dtype_is_binary_string_type(type2->mtype, type2->prtype)) {
+ if (dtype_is_binary_string_type(col1->mtype, col1->prtype)
+ && dtype_is_binary_string_type(col2->mtype, col2->prtype)) {
/* Both are binary string types: they can be compared */
return(TRUE);
}
- if (type1->mtype != type2->mtype) {
+ if (col1->mtype != col2->mtype) {
return(FALSE);
}
- if (type1->mtype == DATA_INT
- && (type1->prtype & DATA_UNSIGNED)
- != (type2->prtype & DATA_UNSIGNED)) {
+ if (col1->mtype == DATA_INT
+ && (col1->prtype & DATA_UNSIGNED)
+ != (col2->prtype & DATA_UNSIGNED)) {
/* The storage format of an unsigned integer is different
from a signed integer: in a signed integer we OR
@@ -141,12 +142,7 @@ cmp_types_are_equal(
return(FALSE);
}
- if (type1->mtype == DATA_INT && type1->len != type2->len) {
-
- return(FALSE);
- }
-
- return(TRUE);
+ return(col1->mtype != DATA_INT || col1->len == col2->len);
}
#ifndef UNIV_HOTBACKUP
@@ -159,7 +155,8 @@ cmp_whole_field(
/*============*/
/* out: 1, 0, -1, if a is greater,
equal, less than b, respectively */
- dtype_t* type, /* in: data type */
+ ulint mtype, /* in: main type */
+ ulint prtype, /* in: precise type */
unsigned char* a, /* in: data field */
unsigned int a_length, /* in: data field length,
not UNIV_SQL_NULL */
@@ -172,11 +169,8 @@ cmp_whole_field(
double d_1;
double d_2;
int swap_flag = 1;
- ulint data_type;
- data_type = type->mtype;
-
- switch (data_type) {
+ switch (mtype) {
case DATA_DECIMAL:
/* Remove preceding spaces */
@@ -253,11 +247,8 @@ cmp_whole_field(
}
return(0);
- case DATA_VARMYSQL:
- case DATA_MYSQL:
case DATA_BLOB:
- if (data_type == DATA_BLOB
- && 0 != (type->prtype & DATA_BINARY_TYPE)) {
+ if (prtype & DATA_BINARY_TYPE) {
ut_print_timestamp(stderr);
fprintf(stderr,
@@ -265,15 +256,17 @@ cmp_whole_field(
" with a character set sensitive\n"
"InnoDB: comparison!\n");
}
-
- return(innobase_mysql_cmp
- ((int)(type->prtype & DATA_MYSQL_TYPE_MASK),
- (uint)dtype_get_charset_coll(type->prtype),
- a, a_length, b, b_length));
+ /* fall through */
+ case DATA_VARMYSQL:
+ case DATA_MYSQL:
+ return(innobase_mysql_cmp(
+ (int)(prtype & DATA_MYSQL_TYPE_MASK),
+ (uint)dtype_get_charset_coll(prtype),
+ a, a_length, b, b_length));
default:
fprintf(stderr,
"InnoDB: unknown type number %lu\n",
- (ulong) data_type);
+ (ulong) mtype);
ut_error;
}
@@ -290,7 +283,8 @@ cmp_data_data_slow(
/*===============*/
/* out: 1, 0, -1, if data1 is greater, equal,
less than data2, respectively */
- dtype_t* cur_type,/* in: data type of the fields */
+ ulint mtype, /* in: main type */
+ ulint prtype, /* in: precise type */
byte* data1, /* in: data field (== a pointer to a memory
buffer) */
ulint len1, /* in: data field length or UNIV_SQL_NULL */
@@ -303,8 +297,6 @@ cmp_data_data_slow(
ulint data2_byte;
ulint cur_bytes;
- ut_ad(dtype_validate(cur_type));
-
if (len1 == UNIV_SQL_NULL || len2 == UNIV_SQL_NULL) {
if (len1 == len2) {
@@ -322,13 +314,13 @@ cmp_data_data_slow(
return(1);
}
- if (cur_type->mtype >= DATA_FLOAT
- || (cur_type->mtype == DATA_BLOB
- && 0 == (cur_type->prtype & DATA_BINARY_TYPE)
- && dtype_get_charset_coll(cur_type->prtype)
+ if (mtype >= DATA_FLOAT
+ || (mtype == DATA_BLOB
+ && 0 == (prtype & DATA_BINARY_TYPE)
+ && dtype_get_charset_coll(prtype)
!= DATA_MYSQL_LATIN1_SWEDISH_CHARSET_COLL)) {
- return(cmp_whole_field(cur_type,
+ return(cmp_whole_field(mtype, prtype,
data1, (unsigned) len1,
data2, (unsigned) len2));
}
@@ -344,7 +336,7 @@ cmp_data_data_slow(
return(0);
}
- data1_byte = dtype_get_pad_char(cur_type);
+ data1_byte = dtype_get_pad_char(mtype, prtype);
if (data1_byte == ULINT_UNDEFINED) {
@@ -355,7 +347,7 @@ cmp_data_data_slow(
}
if (len2 <= cur_bytes) {
- data2_byte = dtype_get_pad_char(cur_type);
+ data2_byte = dtype_get_pad_char(mtype, prtype);
if (data2_byte == ULINT_UNDEFINED) {
@@ -372,9 +364,9 @@ cmp_data_data_slow(
goto next_byte;
}
- if (cur_type->mtype <= DATA_CHAR
- || (cur_type->mtype == DATA_BLOB
- && 0 == (cur_type->prtype & DATA_BINARY_TYPE))) {
+ if (mtype <= DATA_CHAR
+ || (mtype == DATA_BLOB
+ && 0 == (prtype & DATA_BINARY_TYPE))) {
data1_byte = cmp_collate(data1_byte);
data2_byte = cmp_collate(data2_byte);
@@ -435,8 +427,6 @@ cmp_dtuple_rec_with_match(
value for current comparison */
{
#ifndef UNIV_HOTBACKUP
- dtype_t* cur_type; /* pointer to type of the current
- field in dtuple */
dfield_t* dtuple_field; /* current field in logical record */
ulint dtuple_f_len; /* the length of the current field
in the logical record */
@@ -483,8 +473,17 @@ cmp_dtuple_rec_with_match(
while (cur_field < dtuple_get_n_fields_cmp(dtuple)) {
+ ulint mtype;
+ ulint prtype;
+
dtuple_field = dtuple_get_nth_field(dtuple, cur_field);
- cur_type = dfield_get_type(dtuple_field);
+ {
+ const dtype_t* type
+ = dfield_get_type(dtuple_field);
+
+ mtype = type->mtype;
+ prtype = type->prtype;
+ }
dtuple_f_len = dfield_get_len(dtuple_field);
@@ -524,13 +523,13 @@ cmp_dtuple_rec_with_match(
}
}
- if (cur_type->mtype >= DATA_FLOAT
- || (cur_type->mtype == DATA_BLOB
- && 0 == (cur_type->prtype & DATA_BINARY_TYPE)
- && dtype_get_charset_coll(cur_type->prtype)
+ if (mtype >= DATA_FLOAT
+ || (mtype == DATA_BLOB
+ && 0 == (prtype & DATA_BINARY_TYPE)
+ && dtype_get_charset_coll(prtype)
!= DATA_MYSQL_LATIN1_SWEDISH_CHARSET_COLL)) {
- ret = cmp_whole_field(cur_type,
+ ret = cmp_whole_field(mtype, prtype,
dfield_get_data(dtuple_field),
(unsigned) dtuple_f_len,
rec_b_ptr, (unsigned) rec_f_len);
@@ -558,7 +557,7 @@ cmp_dtuple_rec_with_match(
goto next_field;
}
- rec_byte = dtype_get_pad_char(cur_type);
+ rec_byte = dtype_get_pad_char(mtype, prtype);
if (rec_byte == ULINT_UNDEFINED) {
ret = 1;
@@ -570,7 +569,8 @@ cmp_dtuple_rec_with_match(
}
if (UNIV_UNLIKELY(dtuple_f_len <= cur_bytes)) {
- dtuple_byte = dtype_get_pad_char(cur_type);
+ dtuple_byte = dtype_get_pad_char(mtype,
+ prtype);
if (dtuple_byte == ULINT_UNDEFINED) {
ret = -1;
@@ -589,9 +589,9 @@ cmp_dtuple_rec_with_match(
goto next_byte;
}
- if (cur_type->mtype <= DATA_CHAR
- || (cur_type->mtype == DATA_BLOB
- && !(cur_type->prtype & DATA_BINARY_TYPE))) {
+ if (mtype <= DATA_CHAR
+ || (mtype == DATA_BLOB
+ && !(prtype & DATA_BINARY_TYPE))) {
rec_byte = cmp_collate(rec_byte);
dtuple_byte = cmp_collate(dtuple_byte);
@@ -696,8 +696,8 @@ cmp_dtuple_is_prefix_of_rec(
}
if (matched_fields == n_fields - 1
- && matched_bytes == dfield_get_len
- (dtuple_get_nth_field(dtuple, n_fields - 1))) {
+ && matched_bytes == dfield_get_len(
+ dtuple_get_nth_field(dtuple, n_fields - 1))) {
return(TRUE);
}
@@ -730,8 +730,6 @@ cmp_rec_rec_with_match(
the value for the current comparison */
{
#ifndef UNIV_HOTBACKUP
- dtype_t* cur_type; /* pointer to type struct of the
- current field in index */
ulint rec1_n_fields; /* the number of fields in rec */
ulint rec1_f_len; /* length of current field in rec */
byte* rec1_b_ptr; /* pointer to the current byte in rec field */
@@ -764,12 +762,19 @@ cmp_rec_rec_with_match(
while ((cur_field < rec1_n_fields) && (cur_field < rec2_n_fields)) {
- if (index->type & DICT_UNIVERSAL) {
- cur_type = dtype_binary;
+ ulint mtype;
+ ulint prtype;
+
+ if (UNIV_UNLIKELY(index->type & DICT_UNIVERSAL)) {
+ /* This is for the insert buffer B-tree. */
+ mtype = DATA_BINARY;
+ prtype = 0;
} else {
- cur_type = dict_col_get_type
- (dict_field_get_col(dict_index_get_nth_field
- (index, cur_field)));
+ const dict_col_t* col
+ = dict_index_get_nth_col(index, cur_field);
+
+ mtype = col->mtype;
+ prtype = col->prtype;
}
rec1_b_ptr = rec_get_nth_field(rec1, offsets1,
@@ -834,13 +839,13 @@ cmp_rec_rec_with_match(
}
}
- if (cur_type->mtype >= DATA_FLOAT
- || (cur_type->mtype == DATA_BLOB
- && 0 == (cur_type->prtype & DATA_BINARY_TYPE)
- && dtype_get_charset_coll(cur_type->prtype)
+ if (mtype >= DATA_FLOAT
+ || (mtype == DATA_BLOB
+ && 0 == (prtype & DATA_BINARY_TYPE)
+ && dtype_get_charset_coll(prtype)
!= DATA_MYSQL_LATIN1_SWEDISH_CHARSET_COLL)) {
- ret = cmp_whole_field(cur_type,
+ ret = cmp_whole_field(mtype, prtype,
rec1_b_ptr,
(unsigned) rec1_f_len,
rec2_b_ptr,
@@ -867,7 +872,7 @@ cmp_rec_rec_with_match(
goto next_field;
}
- rec2_byte = dtype_get_pad_char(cur_type);
+ rec2_byte = dtype_get_pad_char(mtype, prtype);
if (rec2_byte == ULINT_UNDEFINED) {
ret = 1;
@@ -879,7 +884,7 @@ cmp_rec_rec_with_match(
}
if (rec1_f_len <= cur_bytes) {
- rec1_byte = dtype_get_pad_char(cur_type);
+ rec1_byte = dtype_get_pad_char(mtype, prtype);
if (rec1_byte == ULINT_UNDEFINED) {
ret = -1;
@@ -898,9 +903,9 @@ cmp_rec_rec_with_match(
goto next_byte;
}
- if (cur_type->mtype <= DATA_CHAR
- || (cur_type->mtype == DATA_BLOB
- && !(cur_type->prtype & DATA_BINARY_TYPE))) {
+ if (mtype <= DATA_CHAR
+ || (mtype == DATA_BLOB
+ && !(prtype & DATA_BINARY_TYPE))) {
rec1_byte = cmp_collate(rec1_byte);
rec2_byte = cmp_collate(rec2_byte);
@@ -972,8 +977,6 @@ cmp_debug_dtuple_rec_with_match(
returns, contains the value for current
comparison */
{
- dtype_t* cur_type; /* pointer to type of the current
- field in dtuple */
dfield_t* dtuple_field; /* current field in logical record */
ulint dtuple_f_len; /* the length of the current field
in the logical record */
@@ -1014,9 +1017,17 @@ cmp_debug_dtuple_rec_with_match(
while (cur_field < dtuple_get_n_fields_cmp(dtuple)) {
+ ulint mtype;
+ ulint prtype;
+
dtuple_field = dtuple_get_nth_field(dtuple, cur_field);
+ {
+ const dtype_t* type
+ = dfield_get_type(dtuple_field);
- cur_type = dfield_get_type(dtuple_field);
+ mtype = type->mtype;
+ prtype = type->prtype;
+ }
dtuple_f_data = dfield_get_data(dtuple_field);
dtuple_f_len = dfield_get_len(dtuple_field);
@@ -1032,7 +1043,7 @@ cmp_debug_dtuple_rec_with_match(
goto order_resolved;
}
- ret = cmp_data_data(cur_type, dtuple_f_data, dtuple_f_len,
+ ret = cmp_data_data(mtype, prtype, dtuple_f_data, dtuple_f_len,
rec_f_data, rec_f_len);
if (ret != 0) {
goto order_resolved;
diff --git a/storage/innobase/rem/rem0rec.c b/storage/innobase/rem/rem0rec.c
index c57a19f0230..549b5ee8b28 100644
--- a/storage/innobase/rem/rem0rec.c
+++ b/storage/innobase/rem/rem0rec.c
@@ -202,8 +202,7 @@ rec_init_offsets(
}
field = dict_index_get_nth_field(index, i);
- if (!(dtype_get_prtype(dict_col_get_type
- (dict_field_get_col(field)))
+ if (!(dict_field_get_col(field)->prtype
& DATA_NOT_NULL)) {
/* nullable field => read the null flag */
@@ -226,11 +225,11 @@ rec_init_offsets(
if (UNIV_UNLIKELY(!field->fixed_len)) {
/* Variable-length field: read the length */
- dtype_t* type = dict_col_get_type
- (dict_field_get_col(field));
+ const dict_col_t* col
+ = dict_field_get_col(field);
len = *lens--;
- if (UNIV_UNLIKELY(dtype_get_len(type) > 255)
- || UNIV_UNLIKELY(dtype_get_mtype(type)
+ if (UNIV_UNLIKELY(col->len > 255)
+ || UNIV_UNLIKELY(col->mtype
== DATA_BLOB)) {
if (len & 0x80) {
/* 1exxxxxxx xxxxxxxx */
@@ -442,8 +441,6 @@ rec_get_converted_size_new(
{
ulint size = REC_N_NEW_EXTRA_BYTES
+ (index->n_nullable + 7) / 8;
- dict_field_t* field;
- dtype_t* type;
ulint i;
ulint n_fields;
ut_ad(index && dtuple);
@@ -471,25 +468,27 @@ rec_get_converted_size_new(
/* read the lengths of fields 0..n */
for (i = 0; i < n_fields; i++) {
- ulint len = dtuple_get_nth_field(dtuple, i)->len;
+ dict_field_t* field;
+ ulint len;
+ const dict_col_t* col;
+
field = dict_index_get_nth_field(index, i);
- type = dict_col_get_type(dict_field_get_col(field));
- ut_ad(len != UNIV_SQL_NULL
- || !(dtype_get_prtype(type) & DATA_NOT_NULL));
+ len = dtuple_get_nth_field(dtuple, i)->len;
+ col = dict_field_get_col(field);
+
+ ut_ad(len != UNIV_SQL_NULL || !(col->prtype & DATA_NOT_NULL));
if (len == UNIV_SQL_NULL) {
/* No length is stored for NULL fields. */
continue;
}
- ut_ad(len <= dtype_get_len(type)
- || dtype_get_mtype(type) == DATA_BLOB);
+ ut_ad(len <= col->len || col->mtype == DATA_BLOB);
ut_ad(!field->fixed_len || len == field->fixed_len);
if (field->fixed_len) {
} else if (len < 128
- || (dtype_get_len(type) < 256
- && dtype_get_mtype(type) != DATA_BLOB)) {
+ || (col->len < 256 && col->mtype != DATA_BLOB)) {
size++;
} else {
size += 2;
@@ -588,8 +587,6 @@ rec_set_nth_field_extern_bit_new(
{
byte* nulls = rec - (REC_N_NEW_EXTRA_BYTES + 1);
byte* lens = nulls - (index->n_nullable + 7) / 8;
- dict_field_t* field;
- dtype_t* type;
ulint i;
ulint n_fields;
ulint null_mask = 1;
@@ -603,9 +600,13 @@ rec_set_nth_field_extern_bit_new(
/* read the lengths of fields 0..n */
for (i = 0; i < n_fields; i++) {
+ const dict_field_t* field;
+ const dict_col_t* col;
+
field = dict_index_get_nth_field(index, i);
- type = dict_col_get_type(dict_field_get_col(field));
- if (!(dtype_get_prtype(type) & DATA_NOT_NULL)) {
+ col = dict_field_get_col(field);
+
+ if (!(col->prtype & DATA_NOT_NULL)) {
if (UNIV_UNLIKELY(!(byte) null_mask)) {
nulls--;
null_mask = 1;
@@ -629,8 +630,7 @@ rec_set_nth_field_extern_bit_new(
continue;
}
lens--;
- if (dtype_get_len(type) > 255
- || dtype_get_mtype(type) == DATA_BLOB) {
+ if (col->len > 255 || col->mtype == DATA_BLOB) {
ulint len = lens[1];
if (len & 0x80) { /* 1exxxxxx: 2-byte length */
if (i == ith) {
@@ -640,9 +640,10 @@ rec_set_nth_field_extern_bit_new(
/* toggle the extern bit */
len ^= 0x40;
if (mtr) {
- mlog_write_ulint
- (lens + 1, len,
- MLOG_1BYTE, mtr);
+ mlog_write_ulint(lens + 1,
+ len,
+ MLOG_1BYTE,
+ mtr);
} else {
lens[1] = (byte) len;
}
@@ -767,8 +768,8 @@ rec_convert_dtuple_to_rec_old(
len = dfield_get_len(field);
if (len == UNIV_SQL_NULL) {
- len = dtype_get_sql_null_size
- (dfield_get_type(field));
+ len = dtype_get_sql_null_size(
+ dfield_get_type(field));
data_write_sql_null(rec + end_offset, len);
end_offset += len;
@@ -795,8 +796,8 @@ rec_convert_dtuple_to_rec_old(
len = dfield_get_len(field);
if (len == UNIV_SQL_NULL) {
- len = dtype_get_sql_null_size
- (dfield_get_type(field));
+ len = dtype_get_sql_null_size(
+ dfield_get_type(field));
data_write_sql_null(rec + end_offset, len);
end_offset += len;
@@ -1057,8 +1058,8 @@ rec_copy_prefix_to_dtuple(
ut_ad(rec_validate(rec, offsets));
ut_ad(dtuple_check_typed(tuple));
- dtuple_set_info_bits(tuple, rec_get_info_bits
- (rec, dict_table_is_comp(index->table)));
+ dtuple_set_info_bits(tuple, rec_get_info_bits(
+ rec, dict_table_is_comp(index->table)));
for (i = 0; i < n_fields; i++) {
@@ -1137,8 +1138,6 @@ rec_copy_prefix_to_buf(
{
byte* nulls;
byte* lens;
- dict_field_t* field;
- dtype_t* type;
ulint i;
ulint prefix_len;
ulint null_mask;
@@ -1148,10 +1147,10 @@ rec_copy_prefix_to_buf(
if (!dict_table_is_comp(index->table)) {
ut_ad(rec_validate_old(rec));
- return(rec_copy_prefix_to_buf_old
- (rec, n_fields,
- rec_get_field_start_offs(rec, n_fields),
- buf, buf_size));
+ return(rec_copy_prefix_to_buf_old(
+ rec, n_fields,
+ rec_get_field_start_offs(rec, n_fields),
+ buf, buf_size));
}
status = rec_get_status(rec);
@@ -1180,9 +1179,13 @@ rec_copy_prefix_to_buf(
/* read the lengths of fields 0..n */
for (i = 0; i < n_fields; i++) {
+ const dict_field_t* field;
+ const dict_col_t* col;
+
field = dict_index_get_nth_field(index, i);
- type = dict_col_get_type(dict_field_get_col(field));
- if (!(dtype_get_prtype(type) & DATA_NOT_NULL)) {
+ col = dict_field_get_col(field);
+
+ if (!(col->prtype & DATA_NOT_NULL)) {
/* nullable field => read the null flag */
if (UNIV_UNLIKELY(!(byte) null_mask)) {
nulls--;
@@ -1201,8 +1204,7 @@ rec_copy_prefix_to_buf(
prefix_len += field->fixed_len;
} else {
ulint len = *lens--;
- if (dtype_get_len(type) > 255
- || dtype_get_mtype(type) == DATA_BLOB) {
+ if (col->len > 255 || col->mtype == DATA_BLOB) {
if (len & 0x80) {
/* 1exxxxxx */
len &= 0x3f;
diff --git a/storage/innobase/row/row0ins.c b/storage/innobase/row/row0ins.c
index 352519f5d56..aeaa83daa4d 100644
--- a/storage/innobase/row/row0ins.c
+++ b/storage/innobase/row/row0ins.c
@@ -135,12 +135,12 @@ row_ins_alloc_sys_fields(
/*=====================*/
ins_node_t* node) /* in: insert node */
{
- dtuple_t* row;
- dict_table_t* table;
- mem_heap_t* heap;
- dict_col_t* col;
- dfield_t* dfield;
- byte* ptr;
+ dtuple_t* row;
+ dict_table_t* table;
+ mem_heap_t* heap;
+ const dict_col_t* col;
+ dfield_t* dfield;
+ byte* ptr;
row = node->row;
table = node->table;
@@ -251,8 +251,8 @@ row_ins_sec_index_entry_by_modify(
heap = mem_heap_create(1024);
- update = row_upd_build_sec_rec_difference_binary
- (cursor->index, entry, rec, thr_get_trx(thr), heap);
+ update = row_upd_build_sec_rec_difference_binary(
+ cursor->index, entry, rec, thr_get_trx(thr), heap);
if (mode == BTR_MODIFY_LEAF) {
/* Try an optimistic updating of the record, keeping changes
within the page */
@@ -445,7 +445,6 @@ row_ins_cascade_calc_update_vec(
upd_field_t* parent_ufield;
ulint n_fields_updated;
ulint parent_field_no;
- dtype_t* type;
ulint i;
ulint j;
@@ -470,16 +469,19 @@ row_ins_cascade_calc_update_vec(
for (i = 0; i < foreign->n_fields; i++) {
- parent_field_no = dict_table_get_nth_col_pos
- (parent_table,
- dict_index_get_nth_col_no(parent_index, i));
+ parent_field_no = dict_table_get_nth_col_pos(
+ parent_table,
+ dict_index_get_nth_col_no(parent_index, i));
for (j = 0; j < parent_update->n_fields; j++) {
parent_ufield = parent_update->fields + j;
if (parent_ufield->field_no == parent_field_no) {
- ulint min_size;
+ ulint min_size;
+ const dict_col_t* col;
+
+ col = dict_index_get_nth_col(index, i);
/* A field in the parent index record is
updated. Let us make the update vector
@@ -488,20 +490,17 @@ row_ins_cascade_calc_update_vec(
ufield = update->fields + n_fields_updated;
ufield->field_no
- = dict_table_get_nth_col_pos
- (table,
- dict_index_get_nth_col_no(index, i));
+ = dict_table_get_nth_col_pos(
+ table, dict_col_get_no(col));
ufield->exp = NULL;
ufield->new_val = parent_ufield->new_val;
- type = dict_index_get_nth_type(index, i);
-
/* Do not allow a NOT NULL column to be
updated as NULL */
if (ufield->new_val.len == UNIV_SQL_NULL
- && (type->prtype & DATA_NOT_NULL)) {
+ && (col->prtype & DATA_NOT_NULL)) {
return(ULINT_UNDEFINED);
}
@@ -510,9 +509,12 @@ row_ins_cascade_calc_update_vec(
column, do not allow the update */
if (ufield->new_val.len != UNIV_SQL_NULL
- && dtype_get_at_most_n_mbchars
- (type, dtype_get_len(type),
- ufield->new_val.len, ufield->new_val.data)
+ && dtype_get_at_most_n_mbchars(
+ col->prtype,
+ col->mbminlen, col->mbmaxlen,
+ col->len,
+ ufield->new_val.len,
+ ufield->new_val.data)
< ufield->new_val.len) {
return(ULINT_UNDEFINED);
@@ -523,7 +525,7 @@ row_ins_cascade_calc_update_vec(
need to pad with spaces the new value of the
child column */
- min_size = dtype_get_min_size(type);
+ min_size = dict_col_get_min_size(col);
if (min_size
&& ufield->new_val.len != UNIV_SQL_NULL
@@ -531,8 +533,8 @@ row_ins_cascade_calc_update_vec(
char* pad_start;
const char* pad_end;
- ufield->new_val.data = mem_heap_alloc
- (heap, min_size);
+ ufield->new_val.data = mem_heap_alloc(
+ heap, min_size);
pad_start = ((char*) ufield
->new_val.data)
+ ufield->new_val.len;
@@ -544,14 +546,13 @@ row_ins_cascade_calc_update_vec(
parent_ufield->new_val.data,
parent_ufield->new_val.len);
- switch (UNIV_EXPECT(dtype_get_mbminlen
- (type), 1)) {
+ switch (UNIV_EXPECT(col->mbminlen,1)) {
default:
ut_error;
case 1:
if (UNIV_UNLIKELY
- (dtype_get_charset_coll
- (dtype_get_prtype(type))
+ (dtype_get_charset_coll(
+ col->prtype)
== DATA_MYSQL_BINARY_CHARSET_COLL)) {
/* Do not pad BINARY
columns. */
@@ -603,8 +604,8 @@ row_ins_set_detailed(
if (os_file_set_eof(srv_misc_tmpfile)) {
ut_print_name(srv_misc_tmpfile, trx, TRUE,
foreign->foreign_table_name);
- dict_print_info_on_foreign_key_in_create_format
- (srv_misc_tmpfile, trx, foreign, FALSE);
+ dict_print_info_on_foreign_key_in_create_format(
+ srv_misc_tmpfile, trx, foreign, FALSE);
trx_set_detailed_error_from_file(trx, srv_misc_tmpfile);
} else {
trx_set_detailed_error(trx, "temp file operation failed");
@@ -834,8 +835,8 @@ row_ins_foreign_check_on_constraint(
operation. */
node->cascade_heap = mem_heap_create(128);
- node->cascade_node = row_create_update_node_for_mysql
- (table, node->cascade_heap);
+ node->cascade_node = row_create_update_node_for_mysql(
+ table, node->cascade_heap);
que_node_set_parent(node->cascade_node, node);
}
@@ -881,11 +882,11 @@ row_ins_foreign_check_on_constraint(
err = DB_ROW_IS_REFERENCED;
- row_ins_foreign_report_err
- ("Trying an update, possibly causing a cyclic"
- " cascaded update\n"
- "in the child table,", thr, foreign,
- btr_pcur_get_rec(pcur), entry);
+ row_ins_foreign_report_err(
+ "Trying an update, possibly causing a cyclic"
+ " cascaded update\n"
+ "in the child table,", thr, foreign,
+ btr_pcur_get_rec(pcur), entry);
goto nonstandard_exit_func;
}
@@ -893,9 +894,9 @@ row_ins_foreign_check_on_constraint(
if (row_ins_cascade_n_ancestors(cascade) >= 15) {
err = DB_ROW_IS_REFERENCED;
- row_ins_foreign_report_err
- ("Trying a too deep cascaded delete or update\n",
- thr, foreign, btr_pcur_get_rec(pcur), entry);
+ row_ins_foreign_report_err(
+ "Trying a too deep cascaded delete or update\n",
+ thr, foreign, btr_pcur_get_rec(pcur), entry);
goto nonstandard_exit_func;
}
@@ -961,9 +962,9 @@ row_ins_foreign_check_on_constraint(
we already have a normal shared lock on the appropriate
gap if the search criterion was not unique */
- err = lock_clust_rec_read_check_and_lock_alt
- (0, clust_rec, clust_index,
- LOCK_X, LOCK_REC_NOT_GAP, thr);
+ err = lock_clust_rec_read_check_and_lock_alt(
+ 0, clust_rec, clust_index, LOCK_X, LOCK_REC_NOT_GAP,
+ thr);
}
if (err != DB_SUCCESS) {
@@ -995,8 +996,9 @@ row_ins_foreign_check_on_constraint(
for (i = 0; i < foreign->n_fields; i++) {
(update->fields + i)->field_no
- = dict_table_get_nth_col_pos
- (table, dict_index_get_nth_col_no(index, i));
+ = dict_table_get_nth_col_pos(
+ table,
+ dict_index_get_nth_col_no(index, i));
(update->fields + i)->exp = NULL;
(update->fields + i)->new_val.len = UNIV_SQL_NULL;
(update->fields + i)->new_val.data = NULL;
@@ -1017,14 +1019,14 @@ row_ins_foreign_check_on_constraint(
if (n_to_update == ULINT_UNDEFINED) {
err = DB_ROW_IS_REFERENCED;
- row_ins_foreign_report_err
- ("Trying a cascaded update where the"
- " updated value in the child\n"
- "table would not fit in the length"
- " of the column, or the value would\n"
- "be NULL and the column is"
- " declared as not NULL in the child table,",
- thr, foreign, btr_pcur_get_rec(pcur), entry);
+ row_ins_foreign_report_err(
+ "Trying a cascaded update where the"
+ " updated value in the child\n"
+ "table would not fit in the length"
+ " of the column, or the value would\n"
+ "be NULL and the column is"
+ " declared as not NULL in the child table,",
+ thr, foreign, btr_pcur_get_rec(pcur), entry);
goto nonstandard_exit_func;
}
@@ -1133,11 +1135,11 @@ row_ins_set_shared_rec_lock(
ut_ad(rec_offs_validate(rec, index, offsets));
if (index->type & DICT_CLUSTERED) {
- err = lock_clust_rec_read_check_and_lock
- (0, rec, index, offsets, LOCK_S, type, thr);
+ err = lock_clust_rec_read_check_and_lock(
+ 0, rec, index, offsets, LOCK_S, type, thr);
} else {
- err = lock_sec_rec_read_check_and_lock
- (0, rec, index, offsets, LOCK_S, type, thr);
+ err = lock_sec_rec_read_check_and_lock(
+ 0, rec, index, offsets, LOCK_S, type, thr);
}
return(err);
@@ -1164,11 +1166,11 @@ row_ins_set_exclusive_rec_lock(
ut_ad(rec_offs_validate(rec, index, offsets));
if (index->type & DICT_CLUSTERED) {
- err = lock_clust_rec_read_check_and_lock
- (0, rec, index, offsets, LOCK_X, type, thr);
+ err = lock_clust_rec_read_check_and_lock(
+ 0, rec, index, offsets, LOCK_X, type, thr);
} else {
- err = lock_sec_rec_read_check_and_lock
- (0, rec, index, offsets, LOCK_X, type, thr);
+ err = lock_sec_rec_read_check_and_lock(
+ 0, rec, index, offsets, LOCK_X, type, thr);
}
return(err);
@@ -1232,8 +1234,8 @@ run_again:
for example */
for (i = 0; i < foreign->n_fields; i++) {
- if (UNIV_SQL_NULL == dfield_get_len
- (dtuple_get_nth_field(entry, i))) {
+ if (UNIV_SQL_NULL == dfield_get_len(
+ dtuple_get_nth_field(entry, i))) {
goto exit_func;
}
@@ -1286,8 +1288,8 @@ run_again:
ut_print_name(ef, trx, TRUE,
foreign->foreign_table_name);
fputs(":\n", ef);
- dict_print_info_on_foreign_key_in_create_format
- (ef, trx, foreign, TRUE);
+ dict_print_info_on_foreign_key_in_create_format(
+ ef, trx, foreign, TRUE);
fputs("\nTrying to add to index ", ef);
ut_print_name(ef, trx, FALSE,
foreign->foreign_index->name);
@@ -1348,9 +1350,8 @@ run_again:
if (rec == page_get_supremum_rec(page)) {
- err = row_ins_set_shared_rec_lock
- (LOCK_ORDINARY, rec,
- check_index, offsets, thr);
+ err = row_ins_set_shared_rec_lock(
+ LOCK_ORDINARY, rec, check_index, offsets, thr);
if (err != DB_SUCCESS) {
break;
@@ -1364,9 +1365,9 @@ run_again:
if (cmp == 0) {
if (rec_get_deleted_flag(rec,
rec_offs_comp(offsets))) {
- err = row_ins_set_shared_rec_lock
- (LOCK_ORDINARY, rec,
- check_index, offsets, thr);
+ err = row_ins_set_shared_rec_lock(
+ LOCK_ORDINARY, rec, check_index,
+ offsets, thr);
if (err != DB_SUCCESS) {
break;
@@ -1376,9 +1377,9 @@ run_again:
a record because we can allow inserts
into gaps */
- err = row_ins_set_shared_rec_lock
- (LOCK_REC_NOT_GAP, rec,
- check_index, offsets, thr);
+ err = row_ins_set_shared_rec_lock(
+ LOCK_REC_NOT_GAP, rec, check_index,
+ offsets, thr);
if (err != DB_SUCCESS) {
@@ -1394,9 +1395,9 @@ run_again:
condition: check them in a separate
function */
- err = row_ins_foreign_check_on_constraint
- (thr, foreign, &pcur,
- entry, &mtr);
+ err = row_ins_foreign_check_on_constraint(
+ thr, foreign, &pcur, entry,
+ &mtr);
if (err != DB_SUCCESS) {
/* Since reporting a plain
"duplicate key" error
@@ -1417,9 +1418,9 @@ run_again:
break;
}
} else {
- row_ins_foreign_report_err
- ("Trying to delete or update",
- thr, foreign, rec, entry);
+ row_ins_foreign_report_err(
+ "Trying to delete or update",
+ thr, foreign, rec, entry);
err = DB_ROW_IS_REFERENCED;
break;
@@ -1428,8 +1429,8 @@ run_again:
}
if (cmp < 0) {
- err = row_ins_set_shared_rec_lock
- (LOCK_GAP, rec, check_index, offsets, thr);
+ err = row_ins_set_shared_rec_lock(
+ LOCK_GAP, rec, check_index, offsets, thr);
if (err != DB_SUCCESS) {
break;
@@ -1437,8 +1438,8 @@ run_again:
if (check_ref) {
err = DB_NO_REFERENCED_ROW;
- row_ins_foreign_report_add_err
- (trx, foreign, rec, entry);
+ row_ins_foreign_report_add_err(
+ trx, foreign, rec, entry);
} else {
err = DB_SUCCESS;
}
@@ -1453,8 +1454,8 @@ next_rec:
if (!moved) {
if (check_ref) {
rec = btr_pcur_get_rec(&pcur);
- row_ins_foreign_report_add_err
- (trx, foreign, rec, entry);
+ row_ins_foreign_report_add_err(
+ trx, foreign, rec, entry);
err = DB_NO_REFERENCED_ROW;
} else {
err = DB_SUCCESS;
@@ -1546,8 +1547,8 @@ row_ins_check_foreign_constraints(
But the counter on the table protects the referenced
table from being dropped while the check is running. */
- err = row_ins_check_foreign_constraint
- (TRUE, foreign, table, entry, thr);
+ err = row_ins_check_foreign_constraint(
+ TRUE, foreign, table, entry, thr);
if (foreign->referenced_table) {
mutex_enter(&(dict_sys->mutex));
@@ -1617,8 +1618,8 @@ row_ins_dupl_error_with_rec(
if (!(index->type & DICT_CLUSTERED)) {
for (i = 0; i < n_unique; i++) {
- if (UNIV_SQL_NULL == dfield_get_len
- (dtuple_get_nth_field(entry, i))) {
+ if (UNIV_SQL_NULL == dfield_get_len(
+ dtuple_get_nth_field(entry, i))) {
return(FALSE);
}
@@ -1665,8 +1666,8 @@ row_ins_scan_sec_index_for_duplicate(
since we define NULL != NULL in this case */
for (i = 0; i < n_unique; i++) {
- if (UNIV_SQL_NULL == dfield_get_len
- (dtuple_get_nth_field(entry, i))) {
+ if (UNIV_SQL_NULL == dfield_get_len(
+ dtuple_get_nth_field(entry, i))) {
return(DB_SUCCESS);
}
@@ -1702,12 +1703,12 @@ row_ins_scan_sec_index_for_duplicate(
duplicates ( REPLACE, LOAD DATAFILE REPLACE,
INSERT ON DUPLICATE KEY UPDATE). */
- err = row_ins_set_exclusive_rec_lock
- (LOCK_ORDINARY, rec, index, offsets, thr);
+ err = row_ins_set_exclusive_rec_lock(
+ LOCK_ORDINARY, rec, index, offsets, thr);
} else {
- err = row_ins_set_shared_rec_lock
- (LOCK_ORDINARY, rec, index, offsets, thr);
+ err = row_ins_set_shared_rec_lock(
+ LOCK_ORDINARY, rec, index, offsets, thr);
}
if (err != DB_SUCCESS) {
@@ -1831,22 +1832,22 @@ row_ins_duplicate_error_in_clust(
duplicates ( REPLACE, LOAD DATAFILE REPLACE,
INSERT ON DUPLICATE KEY UPDATE). */
- err = row_ins_set_exclusive_rec_lock
- (LOCK_REC_NOT_GAP, rec,
- cursor->index, offsets, thr);
+ err = row_ins_set_exclusive_rec_lock(
+ LOCK_REC_NOT_GAP, rec,
+ cursor->index, offsets, thr);
} else {
- err = row_ins_set_shared_rec_lock
- (LOCK_REC_NOT_GAP, rec,
- cursor->index, offsets, thr);
+ err = row_ins_set_shared_rec_lock(
+ LOCK_REC_NOT_GAP, rec,
+ cursor->index, offsets, thr);
}
if (err != DB_SUCCESS) {
goto func_exit;
}
- if (row_ins_dupl_error_with_rec
- (rec, entry, cursor->index, offsets)) {
+ if (row_ins_dupl_error_with_rec(
+ rec, entry, cursor->index, offsets)) {
trx->error_info = cursor->index;
err = DB_DUPLICATE_KEY;
goto func_exit;
@@ -1869,22 +1870,22 @@ row_ins_duplicate_error_in_clust(
duplicates ( REPLACE, LOAD DATAFILE REPLACE,
INSERT ON DUPLICATE KEY UPDATE). */
- err = row_ins_set_exclusive_rec_lock
- (LOCK_REC_NOT_GAP, rec,
- cursor->index, offsets, thr);
+ err = row_ins_set_exclusive_rec_lock(
+ LOCK_REC_NOT_GAP, rec,
+ cursor->index, offsets, thr);
} else {
- err = row_ins_set_shared_rec_lock
- (LOCK_REC_NOT_GAP, rec,
- cursor->index, offsets, thr);
+ err = row_ins_set_shared_rec_lock(
+ LOCK_REC_NOT_GAP, rec,
+ cursor->index, offsets, thr);
}
if (err != DB_SUCCESS) {
goto func_exit;
}
- if (row_ins_dupl_error_with_rec
- (rec, entry, cursor->index, offsets)) {
+ if (row_ins_dupl_error_with_rec(
+ rec, entry, cursor->index, offsets)) {
trx->error_info = cursor->index;
err = DB_DUPLICATE_KEY;
goto func_exit;
@@ -2021,8 +2022,8 @@ row_ins_index_entry_low(
#ifdef UNIV_DEBUG
{
page_t* page = btr_cur_get_page(&cursor);
- rec_t* first_rec = page_rec_get_next
- (page_get_infimum_rec(page));
+ rec_t* first_rec = page_rec_get_next(
+ page_get_infimum_rec(page));
if (UNIV_LIKELY(first_rec != page_get_supremum_rec(page))) {
ut_a(rec_get_n_fields(first_rec, index)
@@ -2040,16 +2041,16 @@ row_ins_index_entry_low(
/* Note that the following may return also
DB_LOCK_WAIT */
- err = row_ins_duplicate_error_in_clust
- (&cursor, entry, thr, &mtr);
+ err = row_ins_duplicate_error_in_clust(
+ &cursor, entry, thr, &mtr);
if (err != DB_SUCCESS) {
goto function_exit;
}
} else {
mtr_commit(&mtr);
- err = row_ins_scan_sec_index_for_duplicate
- (index, entry, thr);
+ err = row_ins_scan_sec_index_for_duplicate(
+ index, entry, thr);
mtr_start(&mtr);
if (err != DB_SUCCESS) {
@@ -2084,19 +2085,19 @@ row_ins_index_entry_low(
}
if (index->type & DICT_CLUSTERED) {
- err = row_ins_clust_index_entry_by_modify
- (mode, &cursor, &big_rec, entry,
- ext_vec, n_ext_vec, thr, &mtr);
+ err = row_ins_clust_index_entry_by_modify(
+ mode, &cursor, &big_rec, entry,
+ ext_vec, n_ext_vec, thr, &mtr);
} else {
- err = row_ins_sec_index_entry_by_modify
- (mode, &cursor, entry, thr, &mtr);
+ err = row_ins_sec_index_entry_by_modify(
+ mode, &cursor, entry, thr, &mtr);
}
} else {
if (mode == BTR_MODIFY_LEAF) {
- err = btr_cur_optimistic_insert
- (0, &cursor, entry,
- &insert_rec, &big_rec, thr, &mtr);
+ err = btr_cur_optimistic_insert(
+ 0, &cursor, entry, &insert_rec, &big_rec,
+ thr, &mtr);
} else {
ut_a(mode == BTR_MODIFY_TREE);
if (buf_LRU_buf_pool_running_out()) {
@@ -2105,9 +2106,9 @@ row_ins_index_entry_low(
goto function_exit;
}
- err = btr_cur_pessimistic_insert
- (0, &cursor, entry,
- &insert_rec, &big_rec, thr, &mtr);
+ err = btr_cur_pessimistic_insert(
+ 0, &cursor, entry, &insert_rec, &big_rec,
+ thr, &mtr);
}
if (err == DB_SUCCESS) {
@@ -2211,7 +2212,6 @@ row_ins_index_entry_set_vals(
dfield_t* row_field;
ulint n_fields;
ulint i;
- dtype_t* cur_type;
ut_ad(entry && row);
@@ -2227,12 +2227,13 @@ row_ins_index_entry_set_vals(
if (ind_field->prefix_len > 0
&& dfield_get_len(row_field) != UNIV_SQL_NULL) {
- cur_type = dict_col_get_type
- (dict_field_get_col(ind_field));
+ const dict_col_t* col
+ = dict_field_get_col(ind_field);
- field->len = dtype_get_at_most_n_mbchars
- (cur_type, ind_field->prefix_len,
- dfield_get_len(row_field), row_field->data);
+ field->len = dtype_get_at_most_n_mbchars(
+ col->prtype, col->mbminlen, col->mbmaxlen,
+ ind_field->prefix_len,
+ row_field->len, row_field->data);
} else {
field->len = row_field->len;
}
diff --git a/storage/innobase/row/row0mysql.c b/storage/innobase/row/row0mysql.c
index af3f80fa53b..a2895bae71a 100644
--- a/storage/innobase/row/row0mysql.c
+++ b/storage/innobase/row/row0mysql.c
@@ -417,13 +417,13 @@ row_mysql_convert_row_to_innobase(
}
}
- row_mysql_store_col_in_innobase_format
- (dfield,
- prebuilt->ins_upd_rec_buff + templ->mysql_col_offset,
- TRUE, /* MySQL row format data */
- mysql_rec + templ->mysql_col_offset,
- templ->mysql_col_len,
- dict_table_is_comp(prebuilt->table));
+ row_mysql_store_col_in_innobase_format(
+ dfield,
+ prebuilt->ins_upd_rec_buff + templ->mysql_col_offset,
+ TRUE, /* MySQL row format data */
+ mysql_rec + templ->mysql_col_offset,
+ templ->mysql_col_len,
+ dict_table_is_comp(prebuilt->table));
next_column:
;
}
@@ -619,8 +619,8 @@ row_create_prebuilt(
prebuilt->sel_graph = NULL;
- prebuilt->search_tuple = dtuple_create
- (heap, 2 * dict_table_get_n_cols(table));
+ prebuilt->search_tuple = dtuple_create(
+ heap, 2 * dict_table_get_n_cols(table));
clust_index = dict_table_get_first_index(table);
@@ -707,16 +707,16 @@ row_prebuilt_free(
for (i = 0; i < MYSQL_FETCH_CACHE_SIZE; i++) {
if (prebuilt->fetch_cache[i] != NULL) {
- if ((ROW_PREBUILT_FETCH_MAGIC_N != mach_read_from_4
- ((prebuilt->fetch_cache[i]) - 4))
- || (ROW_PREBUILT_FETCH_MAGIC_N != mach_read_from_4
- ((prebuilt->fetch_cache[i])
- + prebuilt->mysql_row_len))) {
+ if ((ROW_PREBUILT_FETCH_MAGIC_N != mach_read_from_4(
+ (prebuilt->fetch_cache[i]) - 4))
+ || (ROW_PREBUILT_FETCH_MAGIC_N != mach_read_from_4(
+ (prebuilt->fetch_cache[i])
+ + prebuilt->mysql_row_len))) {
fputs("InnoDB: Error: trying to free"
" a corrupt fetch buffer.\n", stderr);
- mem_analyze_corruption
- (prebuilt->fetch_cache[i]);
+ mem_analyze_corruption(
+ prebuilt->fetch_cache[i]);
ut_error;
}
@@ -811,8 +811,8 @@ row_get_prebuilt_insert_row(
prebuilt->ins_node = node;
if (prebuilt->ins_upd_rec_buff == NULL) {
- prebuilt->ins_upd_rec_buff = mem_heap_alloc
- (prebuilt->heap, prebuilt->mysql_row_len);
+ prebuilt->ins_upd_rec_buff = mem_heap_alloc(
+ prebuilt->heap, prebuilt->mysql_row_len);
}
row = dtuple_create(prebuilt->heap,
@@ -830,10 +830,10 @@ row_get_prebuilt_insert_row(
ins_node_set_new_row(node, row);
- prebuilt->ins_graph = que_node_get_parent
- (pars_complete_graph_for_exec(node,
- prebuilt->trx,
- prebuilt->heap));
+ prebuilt->ins_graph = que_node_get_parent(
+ pars_complete_graph_for_exec(node,
+ prebuilt->trx,
+ prebuilt->heap));
prebuilt->ins_graph->state = QUE_FORK_ACTIVE;
}
@@ -1188,10 +1188,10 @@ row_prebuild_sel_graph(
node = sel_node_create(prebuilt->heap);
- prebuilt->sel_graph = que_node_get_parent
- (pars_complete_graph_for_exec(node,
- prebuilt->trx,
- prebuilt->heap));
+ prebuilt->sel_graph = que_node_get_parent(
+ pars_complete_graph_for_exec(node,
+ prebuilt->trx,
+ prebuilt->heap));
prebuilt->sel_graph->state = QUE_FORK_ACTIVE;
}
@@ -1260,10 +1260,10 @@ row_get_prebuilt_update_vector(
prebuilt->upd_node = node;
- prebuilt->upd_graph = que_node_get_parent
- (pars_complete_graph_for_exec(node,
- prebuilt->trx,
- prebuilt->heap));
+ prebuilt->upd_graph = que_node_get_parent(
+ pars_complete_graph_for_exec(node,
+ prebuilt->trx,
+ prebuilt->heap));
prebuilt->upd_graph->state = QUE_FORK_ACTIVE;
}
@@ -1607,16 +1607,11 @@ row_table_got_default_clust_index(
/*==============================*/
dict_table_t* table)
{
- dict_index_t* clust_index;
+ const dict_index_t* clust_index;
clust_index = dict_table_get_first_index(table);
- if (dtype_get_mtype(dict_index_get_nth_type(clust_index, 0))
- == DATA_SYS) {
- return(TRUE);
- }
-
- return(FALSE);
+ return(dict_index_get_nth_col(clust_index, 0)->mtype == DATA_SYS);
}
/*************************************************************************
@@ -1782,9 +1777,8 @@ row_create_table_for_mysql(
/* Check that no reserved column names are used. */
for (i = 0; i < dict_table_get_n_user_cols(table); i++) {
- dict_col_t* col = dict_table_get_nth_col(table, i);
-
- if (dict_col_name_is_reserved(col->name)) {
+ if (dict_col_name_is_reserved(
+ dict_table_get_col_name(table, i))) {
dict_mem_table_free(table);
trx_commit_for_mysql(trx);
@@ -1975,16 +1969,16 @@ row_create_index_for_mysql(
for (i = 0; i < dict_index_get_n_fields(index); i++) {
for (j = 0; j < i; j++) {
- if (0 == ut_strcmp
- (dict_index_get_nth_field(index, j)->name,
- dict_index_get_nth_field(index, i)->name)) {
+ if (0 == ut_strcmp(
+ dict_index_get_nth_field(index, j)->name,
+ dict_index_get_nth_field(index, i)->name)) {
ut_print_timestamp(stderr);
fputs(" InnoDB: Error: column ", stderr);
ut_print_name(stderr, trx, FALSE,
- dict_index_get_nth_field
- (index, i)->name);
+ dict_index_get_nth_field(
+ index, i)->name);
fputs(" appears twice in ", stderr);
dict_index_name_print(stderr, trx, index);
fputs("\n"
@@ -2205,8 +2199,8 @@ loop:
goto already_dropped;
}
- if (DB_SUCCESS != row_drop_table_for_mysql_in_background
- (drop->table_name)) {
+ if (DB_SUCCESS != row_drop_table_for_mysql_in_background(
+ drop->table_name)) {
/* If the DROP fails for some table, we return, and let the
main thread retry later */
@@ -2835,9 +2829,9 @@ row_truncate_table_for_mysql(
rec = btr_pcur_get_rec(&pcur);
if (root_page_no != FIL_NULL) {
- page_rec_write_index_page_no
- (rec, DICT_SYS_INDEXES_PAGE_NO_FIELD,
- root_page_no, &mtr);
+ page_rec_write_index_page_no(
+ rec, DICT_SYS_INDEXES_PAGE_NO_FIELD,
+ root_page_no, &mtr);
/* We will need to commit and restart the
mini-transaction in order to avoid deadlocks.
The dict_truncate_index_tree() call has allocated
@@ -3038,8 +3032,8 @@ check_next_foreign:
}
if (foreign && trx->check_foreigns
- && !(drop_db && dict_tables_have_same_db
- (name, foreign->foreign_table_name))) {
+ && !(drop_db && dict_tables_have_same_db(
+ name, foreign->foreign_table_name))) {
FILE* ef = dict_foreign_err_file;
/* We only allow dropping a referenced table if
@@ -3232,8 +3226,8 @@ check_next_foreign:
space_id = table->space;
if (table->dir_path_of_temp_table != NULL) {
- dir_path_of_temp_table = mem_strdup
- (table->dir_path_of_temp_table);
+ dir_path_of_temp_table = mem_strdup(
+ table->dir_path_of_temp_table);
is_path = TRUE;
name_or_path = dir_path_of_temp_table;
} else {
@@ -3447,8 +3441,8 @@ row_delete_constraint(
ulint err;
/* New format constraints have ids <databasename>/<constraintname>. */
- err = row_delete_constraint_low
- (mem_heap_strcat(heap, database_name, id), trx);
+ err = row_delete_constraint_low(
+ mem_heap_strcat(heap, database_name, id), trx);
if ((err == DB_SUCCESS) && !strchr(id, '/')) {
/* Old format < 4.0.18 constraints have constraint ids
@@ -3570,9 +3564,9 @@ row_rename_table_for_mysql(
heap = mem_heap_create(100);
- err = dict_foreign_parse_drop_constraints
- (heap, trx, table,
- &n_constraints_to_drop, &constraints_to_drop);
+ err = dict_foreign_parse_drop_constraints(
+ heap, trx, table, &n_constraints_to_drop,
+ &constraints_to_drop);
if (err != DB_SUCCESS) {
@@ -3611,71 +3605,71 @@ row_rename_table_for_mysql(
pars_info_add_str_literal(info, "new_table_name", new_name);
pars_info_add_str_literal(info, "old_table_name", old_name);
- err = que_eval_sql
- (info,
- "PROCEDURE RENAME_CONSTRAINT_IDS () IS\n"
- "gen_constr_prefix CHAR;\n"
- "new_db_name CHAR;\n"
- "foreign_id CHAR;\n"
- "new_foreign_id CHAR;\n"
- "old_db_name_len INT;\n"
- "old_t_name_len INT;\n"
- "new_db_name_len INT;\n"
- "id_len INT;\n"
- "found INT;\n"
- "BEGIN\n"
- "found := 1;\n"
- "old_db_name_len := INSTR(:old_table_name, '/')-1;\n"
- "new_db_name_len := INSTR(:new_table_name, '/')-1;\n"
- "new_db_name := SUBSTR(:new_table_name, 0,\n"
- " new_db_name_len);\n"
- "old_t_name_len := LENGTH(:old_table_name);\n"
- "gen_constr_prefix := CONCAT(:old_table_name,\n"
- " '_ibfk_');\n"
- "WHILE found = 1 LOOP\n"
- " SELECT ID INTO foreign_id\n"
- " FROM SYS_FOREIGN\n"
- " WHERE FOR_NAME = :old_table_name\n"
- " AND TO_BINARY(FOR_NAME)\n"
- " = TO_BINARY(:old_table_name)\n"
- " LOCK IN SHARE MODE;\n"
- " IF (SQL % NOTFOUND) THEN\n"
- " found := 0;\n"
- " ELSE\n"
- " UPDATE SYS_FOREIGN\n"
- " SET FOR_NAME = :new_table_name\n"
- " WHERE ID = foreign_id;\n"
- " id_len := LENGTH(foreign_id);\n"
- " IF (INSTR(foreign_id, '/') > 0) THEN\n"
- " IF (INSTR(foreign_id,\n"
- " gen_constr_prefix) > 0)\n"
- " THEN\n"
- " new_foreign_id :=\n"
- " CONCAT(:new_table_name,\n"
- " SUBSTR(foreign_id, old_t_name_len,\n"
- " id_len - old_t_name_len));\n"
- " ELSE\n"
- " new_foreign_id :=\n"
- " CONCAT(new_db_name,\n"
- " SUBSTR(foreign_id,\n"
- " old_db_name_len,\n"
- " id_len - old_db_name_len));\n"
- " END IF;\n"
- " UPDATE SYS_FOREIGN\n"
- " SET ID = new_foreign_id\n"
- " WHERE ID = foreign_id;\n"
- " UPDATE SYS_FOREIGN_COLS\n"
- " SET ID = new_foreign_id\n"
- " WHERE ID = foreign_id;\n"
- " END IF;\n"
- " END IF;\n"
- "END LOOP;\n"
- "UPDATE SYS_FOREIGN SET REF_NAME = :new_table_name\n"
- "WHERE REF_NAME = :old_table_name\n"
- " AND TO_BINARY(REF_NAME)\n"
- " = TO_BINARY(:old_table_name);\n"
- "END;\n"
- , FALSE, trx);
+ err = que_eval_sql(
+ info,
+ "PROCEDURE RENAME_CONSTRAINT_IDS () IS\n"
+ "gen_constr_prefix CHAR;\n"
+ "new_db_name CHAR;\n"
+ "foreign_id CHAR;\n"
+ "new_foreign_id CHAR;\n"
+ "old_db_name_len INT;\n"
+ "old_t_name_len INT;\n"
+ "new_db_name_len INT;\n"
+ "id_len INT;\n"
+ "found INT;\n"
+ "BEGIN\n"
+ "found := 1;\n"
+ "old_db_name_len := INSTR(:old_table_name, '/')-1;\n"
+ "new_db_name_len := INSTR(:new_table_name, '/')-1;\n"
+ "new_db_name := SUBSTR(:new_table_name, 0,\n"
+ " new_db_name_len);\n"
+ "old_t_name_len := LENGTH(:old_table_name);\n"
+ "gen_constr_prefix := CONCAT(:old_table_name,\n"
+ " '_ibfk_');\n"
+ "WHILE found = 1 LOOP\n"
+ " SELECT ID INTO foreign_id\n"
+ " FROM SYS_FOREIGN\n"
+ " WHERE FOR_NAME = :old_table_name\n"
+ " AND TO_BINARY(FOR_NAME)\n"
+ " = TO_BINARY(:old_table_name)\n"
+ " LOCK IN SHARE MODE;\n"
+ " IF (SQL % NOTFOUND) THEN\n"
+ " found := 0;\n"
+ " ELSE\n"
+ " UPDATE SYS_FOREIGN\n"
+ " SET FOR_NAME = :new_table_name\n"
+ " WHERE ID = foreign_id;\n"
+ " id_len := LENGTH(foreign_id);\n"
+ " IF (INSTR(foreign_id, '/') > 0) THEN\n"
+ " IF (INSTR(foreign_id,\n"
+ " gen_constr_prefix) > 0)\n"
+ " THEN\n"
+ " new_foreign_id :=\n"
+ " CONCAT(:new_table_name,\n"
+ " SUBSTR(foreign_id, old_t_name_len,\n"
+ " id_len - old_t_name_len));\n"
+ " ELSE\n"
+ " new_foreign_id :=\n"
+ " CONCAT(new_db_name,\n"
+ " SUBSTR(foreign_id,\n"
+ " old_db_name_len,\n"
+ " id_len - old_db_name_len));\n"
+ " END IF;\n"
+ " UPDATE SYS_FOREIGN\n"
+ " SET ID = new_foreign_id\n"
+ " WHERE ID = foreign_id;\n"
+ " UPDATE SYS_FOREIGN_COLS\n"
+ " SET ID = new_foreign_id\n"
+ " WHERE ID = foreign_id;\n"
+ " END IF;\n"
+ " END IF;\n"
+ "END LOOP;\n"
+ "UPDATE SYS_FOREIGN SET REF_NAME = :new_table_name\n"
+ "WHERE REF_NAME = :old_table_name\n"
+ " AND TO_BINARY(REF_NAME)\n"
+ " = TO_BINARY(:old_table_name);\n"
+ "END;\n"
+ , FALSE, trx);
} else if (n_constraints_to_drop > 0) {
/* Drop some constraints of tmp tables. */
@@ -3763,8 +3757,8 @@ end:
/* We only want to switch off some of the type checking in
an ALTER, not in a RENAME. */
- err = dict_load_foreigns
- (new_name, old_is_tmp ? trx->check_foreigns : TRUE);
+ err = dict_load_foreigns(
+ new_name, old_is_tmp ? trx->check_foreigns : TRUE);
if (err != DB_SUCCESS) {
ut_print_timestamp(stderr);
@@ -3904,8 +3898,8 @@ func_exit:
for (i = 0;
i < dict_index_get_n_ordering_defined_by_user(index);
i++) {
- if (UNIV_SQL_NULL == dfield_get_len
- (dtuple_get_nth_field(prev_entry, i))) {
+ if (UNIV_SQL_NULL == dfield_get_len(
+ dtuple_get_nth_field(prev_entry, i))) {
contains_null = TRUE;
}
@@ -3928,8 +3922,8 @@ not_ok:
} else if ((index->type & DICT_UNIQUE)
&& !contains_null
&& matched_fields
- >= dict_index_get_n_ordering_defined_by_user
- (index)) {
+ >= dict_index_get_n_ordering_defined_by_user(
+ index)) {
fputs("InnoDB: duplicate key in ", stderr);
goto not_ok;
@@ -4004,7 +3998,7 @@ row_check_table_for_mysql(
ut_print_name(stderr, trx, FALSE, index->name);
putc('\n', stderr); */
- if (!btr_validate_tree(index->tree, prebuilt->trx)) {
+ if (!btr_validate_index(index, prebuilt->trx)) {
ret = DB_ERROR;
} else {
if (!row_scan_and_check_index(prebuilt,
diff --git a/storage/innobase/row/row0purge.c b/storage/innobase/row/row0purge.c
index 1513b18666d..889a11a7a76 100644
--- a/storage/innobase/row/row0purge.c
+++ b/storage/innobase/row/row0purge.c
@@ -123,10 +123,10 @@ row_purge_remove_clust_if_poss_low(
rec = btr_pcur_get_rec(pcur);
- if (0 != ut_dulint_cmp(node->roll_ptr, row_get_rec_roll_ptr
- (rec, index, rec_get_offsets
- (rec, index, offsets_,
- ULINT_UNDEFINED, &heap)))) {
+ if (0 != ut_dulint_cmp(node->roll_ptr, row_get_rec_roll_ptr(
+ rec, index, rec_get_offsets(
+ rec, index, offsets_,
+ ULINT_UNDEFINED, &heap)))) {
if (UNIV_LIKELY_NULL(heap)) {
mem_heap_free(heap);
}
@@ -248,9 +248,9 @@ row_purge_remove_sec_if_poss_low(
success = row_purge_reposition_pcur(BTR_SEARCH_LEAF, node, mtr_vers);
if (success) {
- old_has = row_vers_old_has_index_entry
- (TRUE, btr_pcur_get_rec(&(node->pcur)),
- mtr_vers, index, entry);
+ old_has = row_vers_old_has_index_entry(
+ TRUE, btr_pcur_get_rec(&(node->pcur)),
+ mtr_vers, index, entry);
}
btr_pcur_commit_specify_mtr(&(node->pcur), mtr_vers);
@@ -430,7 +430,7 @@ skip_secondaries:
index = dict_table_get_first_index(node->table);
- mtr_x_lock(dict_tree_get_lock(index->tree), &mtr);
+ mtr_x_lock(dict_index_get_lock(index), &mtr);
/* NOTE: we must also acquire an X-latch to the
root page of the tree. We will need it when we
@@ -441,7 +441,7 @@ skip_secondaries:
latching order if we would only later latch the
root page of such a tree! */
- btr_root_get(index->tree, &mtr);
+ btr_root_get(index, &mtr);
/* We assume in purge of externally stored fields
that the space id of the undo log record is 0! */
@@ -618,8 +618,8 @@ row_purge(
if (purge_needed) {
node->found_clust = FALSE;
- node->index = dict_table_get_next_index
- (dict_table_get_first_index(node->table));
+ node->index = dict_table_get_next_index(
+ dict_table_get_first_index(node->table));
if (node->rec_type == TRX_UNDO_DEL_MARK_REC) {
row_purge_del_mark(node);
diff --git a/storage/innobase/row/row0row.c b/storage/innobase/row/row0row.c
index b945954041e..efa129d6211 100644
--- a/storage/innobase/row/row0row.c
+++ b/storage/innobase/row/row0row.c
@@ -114,10 +114,8 @@ row_build_index_entry(
dict_field_t* ind_field;
dfield_t* dfield;
dfield_t* dfield2;
- dict_col_t* col;
ulint i;
ulint storage_len;
- dtype_t* cur_type;
ut_ad(row && index && heap);
ut_ad(dtuple_check_typed(row));
@@ -128,11 +126,12 @@ row_build_index_entry(
if (index->type & DICT_UNIVERSAL) {
dtuple_set_n_fields_cmp(entry, entry_len);
} else {
- dtuple_set_n_fields_cmp
- (entry, dict_index_get_n_unique_in_tree(index));
+ dtuple_set_n_fields_cmp(
+ entry, dict_index_get_n_unique_in_tree(index));
}
for (i = 0; i < entry_len; i++) {
+ const dict_col_t* col;
ind_field = dict_index_get_nth_field(index, i);
col = ind_field->col;
@@ -143,17 +142,20 @@ row_build_index_entry(
dfield_copy(dfield, dfield2);
/* If a column prefix index, take only the prefix */
- if (ind_field->prefix_len > 0
- && dfield_get_len(dfield2) != UNIV_SQL_NULL) {
+ if (ind_field->prefix_len) {
+ if (dfield_get_len(dfield2) != UNIV_SQL_NULL) {
- cur_type = dict_col_get_type
- (dict_field_get_col(ind_field));
+ storage_len = dtype_get_at_most_n_mbchars(
+ col->prtype,
+ col->mbminlen, col->mbmaxlen,
+ ind_field->prefix_len,
+ dfield_get_len(dfield2),
+ dfield2->data);
- storage_len = dtype_get_at_most_n_mbchars
- (cur_type, ind_field->prefix_len,
- dfield_get_len(dfield2), dfield2->data);
+ dfield_set_len(dfield, storage_len);
+ }
- dfield_set_len(dfield, storage_len);
+ dfield_get_type(dfield)->len = ind_field->prefix_len;
}
}
@@ -192,7 +194,6 @@ row_build(
dtuple_t* row;
dict_table_t* table;
dict_field_t* ind_field;
- dict_col_t* col;
dfield_t* dfield;
ulint n_fields;
byte* field;
@@ -227,8 +228,8 @@ row_build(
row = dtuple_create(heap, row_len);
- dtuple_set_info_bits(row, rec_get_info_bits
- (rec, dict_table_is_comp(table)));
+ dtuple_set_info_bits(row, rec_get_info_bits(
+ rec, dict_table_is_comp(table)));
n_fields = rec_offs_n_fields(offsets);
@@ -239,7 +240,9 @@ row_build(
if (ind_field->prefix_len == 0) {
- col = dict_field_get_col(ind_field);
+ const dict_col_t* col
+ = dict_field_get_col(ind_field);
+
dfield = dtuple_get_nth_field(row,
dict_col_get_no(col));
field = rec_get_nth_field(rec, offsets, i, &len);
@@ -416,17 +419,22 @@ row_build_row_ref(
column, or the full column, and we must adjust the length
accordingly. */
- clust_col_prefix_len = dict_index_get_nth_field
- (clust_index, i)->prefix_len;
+ clust_col_prefix_len = dict_index_get_nth_field(
+ clust_index, i)->prefix_len;
if (clust_col_prefix_len > 0) {
if (len != UNIV_SQL_NULL) {
+ const dtype_t* dtype
+ = dfield_get_type(dfield);
+
dfield_set_len(dfield,
- dtype_get_at_most_n_mbchars
- (dfield_get_type(dfield),
- clust_col_prefix_len, len,
- (char*) field));
+ dtype_get_at_most_n_mbchars(
+ dtype->prtype,
+ dtype->mbminlen,
+ dtype->mbmaxlen,
+ clust_col_prefix_len,
+ len, (char*) field));
}
}
}
@@ -513,17 +521,22 @@ notfound:
column, or the full column, and we must adjust the length
accordingly. */
- clust_col_prefix_len = dict_index_get_nth_field
- (clust_index, i)->prefix_len;
+ clust_col_prefix_len = dict_index_get_nth_field(
+ clust_index, i)->prefix_len;
if (clust_col_prefix_len > 0) {
if (len != UNIV_SQL_NULL) {
+ const dtype_t* dtype
+ = dfield_get_type(dfield);
+
dfield_set_len(dfield,
- dtype_get_at_most_n_mbchars
- (dfield_get_type(dfield),
- clust_col_prefix_len, len,
- (char*) field));
+ dtype_get_at_most_n_mbchars(
+ dtype->prtype,
+ dtype->mbminlen,
+ dtype->mbmaxlen,
+ clust_col_prefix_len,
+ len, (char*) field));
}
}
}
@@ -550,13 +563,8 @@ row_build_row_ref_from_row(
directly into data of this row */
{
dict_index_t* clust_index;
- dict_field_t* field;
- dfield_t* dfield;
- dfield_t* dfield2;
- dict_col_t* col;
ulint ref_len;
ulint i;
- dtype_t* cur_type;
ut_ad(ref && table && row);
@@ -567,6 +575,11 @@ row_build_row_ref_from_row(
ut_ad(ref_len == dtuple_get_n_fields(ref));
for (i = 0; i < ref_len; i++) {
+ const dict_col_t* col;
+ dict_field_t* field;
+ dfield_t* dfield;
+ dfield_t* dfield2;
+
dfield = dtuple_get_nth_field(ref, i);
field = dict_index_get_nth_field(clust_index, i);
@@ -580,12 +593,9 @@ row_build_row_ref_from_row(
if (field->prefix_len > 0
&& dfield->len != UNIV_SQL_NULL) {
- cur_type = dict_col_get_type
- (dict_field_get_col(field));
-
- dfield->len = dtype_get_at_most_n_mbchars
- (cur_type, field->prefix_len,
- dfield->len, dfield->data);
+ dfield->len = dtype_get_at_most_n_mbchars(
+ col->prtype, col->mbminlen, col->mbmaxlen,
+ field->prefix_len, dfield->len, dfield->data);
}
}
diff --git a/storage/innobase/row/row0sel.c b/storage/innobase/row/row0sel.c
index 06aeca509d3..c6b117cdafa 100644
--- a/storage/innobase/row/row0sel.c
+++ b/storage/innobase/row/row0sel.c
@@ -45,9 +45,6 @@ to que_run_threads: this is to allow canceling runaway queries */
#define SEL_COST_LIMIT 100
-/* The lower limit for what we consider a "big" row */
-#define BIG_ROW_SIZE 1024
-
/* Flags for search shortcut */
#define SEL_FOUND 0
#define SEL_EXHAUSTED 1
@@ -72,15 +69,12 @@ row_sel_sec_rec_is_for_clust_rec(
rec_t* clust_rec, /* in: clustered index record */
dict_index_t* clust_index) /* in: clustered index */
{
- dict_field_t* ifield;
- dict_col_t* col;
byte* sec_field;
ulint sec_len;
byte* clust_field;
ulint clust_len;
ulint n;
ulint i;
- dtype_t* cur_type;
mem_heap_t* heap = NULL;
ulint clust_offsets_[REC_OFFS_NORMAL_SIZE];
ulint sec_offsets_[REC_OFFS_SMALL_SIZE];
@@ -99,26 +93,26 @@ row_sel_sec_rec_is_for_clust_rec(
n = dict_index_get_n_ordering_defined_by_user(sec_index);
for (i = 0; i < n; i++) {
+ const dict_field_t* ifield;
+ const dict_col_t* col;
+
ifield = dict_index_get_nth_field(sec_index, i);
col = dict_field_get_col(ifield);
- clust_field = rec_get_nth_field(clust_rec, clust_offs,
- dict_col_get_clust_pos(col),
- &clust_len);
+ clust_field = rec_get_nth_field(
+ clust_rec, clust_offs,
+ dict_col_get_clust_pos(col, clust_index), &clust_len);
sec_field = rec_get_nth_field(sec_rec, sec_offs, i, &sec_len);
- if (ifield->prefix_len > 0
- && clust_len != UNIV_SQL_NULL) {
+ if (ifield->prefix_len > 0 && clust_len != UNIV_SQL_NULL) {
- cur_type = dict_col_get_type
- (dict_field_get_col(ifield));
-
- clust_len = dtype_get_at_most_n_mbchars
- (cur_type, ifield->prefix_len,
- clust_len, (char*) clust_field);
+ clust_len = dtype_get_at_most_n_mbchars(
+ col->prtype, col->mbminlen, col->mbmaxlen,
+ ifield->prefix_len,
+ clust_len, (char*) clust_field);
}
- if (0 != cmp_data_data(dict_col_get_type(col),
+ if (0 != cmp_data_data(col->mtype, col->prtype,
clust_field, clust_len,
sec_field, sec_len)) {
is_equal = FALSE;
@@ -319,8 +313,8 @@ row_sel_fetch_columns(
heap = mem_heap_create(1);
- data = btr_rec_copy_externally_stored_field
- (rec, offsets, field_no, &len, heap);
+ data = btr_rec_copy_externally_stored_field(
+ rec, offsets, field_no, &len, heap);
ut_a(len != UNIV_SQL_NULL);
@@ -557,9 +551,9 @@ row_sel_build_prev_vers(
plan->old_vers_heap = mem_heap_create(512);
}
- err = row_vers_build_for_consistent_read
- (rec, mtr, plan->index, offsets, read_view, offset_heap,
- plan->old_vers_heap, old_vers);
+ err = row_vers_build_for_consistent_read(
+ rec, mtr, plan->index, offsets, read_view, offset_heap,
+ plan->old_vers_heap, old_vers);
return(err);
}
@@ -592,9 +586,9 @@ row_sel_build_committed_vers_for_mysql(
prebuilt->old_vers_heap = mem_heap_create(200);
}
- err = row_vers_build_for_semi_consistent_read
- (rec, mtr, clust_index, offsets, offset_heap,
- prebuilt->old_vers_heap, old_vers);
+ err = row_vers_build_for_semi_consistent_read(
+ rec, mtr, clust_index, offsets, offset_heap,
+ prebuilt->old_vers_heap, old_vers);
return(err);
}
@@ -754,9 +748,9 @@ row_sel_get_clust_rec(
lock_type = LOCK_ORDINARY;
}
- err = lock_clust_rec_read_check_and_lock
- (0, clust_rec, index, offsets,
- node->row_lock_mode, lock_type, thr);
+ err = lock_clust_rec_read_check_and_lock(
+ 0, clust_rec, index, offsets,
+ node->row_lock_mode, lock_type, thr);
if (err != DB_SUCCESS) {
@@ -800,8 +794,8 @@ row_sel_get_clust_rec(
exist in our snapshot. */
if ((old_vers
- || rec_get_deleted_flag(rec, dict_table_is_comp
- (plan->table)))
+ || rec_get_deleted_flag(rec, dict_table_is_comp(
+ plan->table)))
&& !row_sel_sec_rec_is_for_clust_rec(rec, plan->index,
clust_rec, index)) {
goto func_exit;
@@ -850,11 +844,11 @@ sel_set_rec_lock(
}
if (index->type & DICT_CLUSTERED) {
- err = lock_clust_rec_read_check_and_lock
- (0, rec, index, offsets, mode, type, thr);
+ err = lock_clust_rec_read_check_and_lock(
+ 0, rec, index, offsets, mode, type, thr);
} else {
- err = lock_sec_rec_read_check_and_lock
- (0, rec, index, offsets, mode, type, thr);
+ err = lock_sec_rec_read_check_and_lock(
+ 0, rec, index, offsets, mode, type, thr);
}
return(err);
@@ -1246,7 +1240,7 @@ table_loop:
if (consistent_read && plan->unique_search && !plan->pcur_is_open
&& !plan->must_get_clust
- && (plan->table->max_row_size < BIG_ROW_SIZE)) {
+ && !plan->table->big_rows) {
if (!search_latch_locked) {
rw_lock_s_lock(&btr_search_latch);
@@ -1506,13 +1500,13 @@ skip_lock:
}
if (old_vers == NULL) {
- offsets = rec_get_offsets
- (rec, index, offsets,
- ULINT_UNDEFINED, &heap);
- row_sel_fetch_columns
- (index, rec, offsets,
- UT_LIST_GET_FIRST
- (plan->columns));
+ offsets = rec_get_offsets(
+ rec, index, offsets,
+ ULINT_UNDEFINED, &heap);
+ row_sel_fetch_columns(
+ index, rec, offsets,
+ UT_LIST_GET_FIRST(
+ plan->columns));
if (!row_sel_test_end_conds(plan)) {
@@ -1651,7 +1645,7 @@ skip_lock:
if ((plan->n_rows_fetched <= SEL_PREFETCH_LIMIT)
|| plan->unique_search || plan->no_prefetch
- || (plan->table->max_row_size >= BIG_ROW_SIZE)) {
+ || plan->table->big_rows) {
/* No prefetch in operation: go to the next table */
@@ -1922,8 +1916,8 @@ row_sel_step(
if (node->consistent_read) {
/* Assign a read view for the query */
- node->read_view = trx_assign_read_view
- (thr_get_trx(thr));
+ node->read_view = trx_assign_read_view(
+ thr_get_trx(thr));
} else {
if (node->set_x_locks) {
i_lock_mode = LOCK_IX;
@@ -2010,8 +2004,8 @@ fetch_step(
sel_assign_into_var_values(node->into_list,
sel_node);
} else {
- void* ret = (*node->func->func)
- (sel_node, node->func->arg);
+ void* ret = (*node->func->func)(
+ sel_node, node->func->arg);
if (!ret) {
sel_node->state
@@ -2249,8 +2243,7 @@ row_sel_convert_mysql_key_to_innobase(
while (key_ptr < key_end) {
- ut_a(dict_col_get_type(field->col)->mtype
- == dfield_get_type(dfield)->mtype);
+ ut_a(field->col->mtype == dfield_get_type(dfield)->mtype);
data_offset = 0;
is_null = FALSE;
@@ -2334,11 +2327,11 @@ row_sel_convert_mysql_key_to_innobase(
/* Storing may use at most data_len bytes of buf */
if (!is_null) {
- row_mysql_store_col_in_innobase_format
- (dfield, buf,
- FALSE, /* MySQL key value format col */
- key_ptr + data_offset, data_len,
- dict_table_is_comp(index->table));
+ row_mysql_store_col_in_innobase_format(
+ dfield, buf,
+ FALSE, /* MySQL key value format col */
+ key_ptr + data_offset, data_len,
+ dict_table_is_comp(index->table));
buf += data_len;
}
@@ -2405,9 +2398,9 @@ row_sel_store_row_id_to_prebuilt(
ut_ad(rec_offs_validate(index_rec, index, offsets));
- data = rec_get_nth_field
- (index_rec, offsets,
- dict_index_get_sys_col_pos(index, DATA_ROW_ID), &len);
+ data = rec_get_nth_field(
+ index_rec, offsets,
+ dict_index_get_sys_col_pos(index, DATA_ROW_ID), &len);
if (len != DATA_ROW_ID_LEN) {
fprintf(stderr,
@@ -2480,8 +2473,8 @@ row_sel_field_store_in_mysql_format(
length of the data to the first byte or the first
two bytes of dest. */
- dest = row_mysql_store_true_var_len
- (dest, len, templ->mysql_length_bytes);
+ dest = row_mysql_store_true_var_len(
+ dest, len, templ->mysql_length_bytes);
}
/* Copy the actual data */
@@ -2614,8 +2607,8 @@ row_sel_store_mysql_rec(
if (UNIV_UNLIKELY(templ->type == DATA_BLOB)) {
if (prebuilt->blob_heap == NULL) {
- prebuilt->blob_heap = mem_heap_create
- (UNIV_PAGE_SIZE);
+ prebuilt->blob_heap = mem_heap_create(
+ UNIV_PAGE_SIZE);
}
heap = prebuilt->blob_heap;
@@ -2630,9 +2623,9 @@ row_sel_store_mysql_rec(
already run out of memory in the next call, which
causes an assert */
- data = btr_rec_copy_externally_stored_field
- (rec, offsets, templ->rec_field_no,
- &len, heap);
+ data = btr_rec_copy_externally_stored_field(
+ rec, offsets, templ->rec_field_no,
+ &len, heap);
ut_a(len != UNIV_SQL_NULL);
} else {
@@ -2643,9 +2636,9 @@ row_sel_store_mysql_rec(
}
if (len != UNIV_SQL_NULL) {
- row_sel_field_store_in_mysql_format
- (mysql_rec + templ->mysql_col_offset,
- templ, data, len);
+ row_sel_field_store_in_mysql_format(
+ mysql_rec + templ->mysql_col_offset,
+ templ, data, len);
/* Cleanup */
if (extern_field_heap) {
@@ -2747,9 +2740,9 @@ row_sel_build_prev_vers_for_mysql(
prebuilt->old_vers_heap = mem_heap_create(200);
}
- err = row_vers_build_for_consistent_read
- (rec, mtr, clust_index, offsets, read_view, offset_heap,
- prebuilt->old_vers_heap, old_vers);
+ err = row_vers_build_for_consistent_read(
+ rec, mtr, clust_index, offsets, read_view, offset_heap,
+ prebuilt->old_vers_heap, old_vers);
return(err);
}
@@ -2853,9 +2846,9 @@ row_sel_get_clust_rec_for_mysql(
the clust rec with a unique condition, hence
we set a LOCK_REC_NOT_GAP type lock */
- err = lock_clust_rec_read_check_and_lock
- (0, clust_rec, clust_index, *offsets,
- prebuilt->select_lock_type, LOCK_REC_NOT_GAP, thr);
+ err = lock_clust_rec_read_check_and_lock(
+ 0, clust_rec, clust_index, *offsets,
+ prebuilt->select_lock_type, LOCK_REC_NOT_GAP, thr);
if (err != DB_SUCCESS) {
goto err_exit;
@@ -2870,15 +2863,16 @@ row_sel_get_clust_rec_for_mysql(
then we never look for an earlier version */
if (trx->isolation_level > TRX_ISO_READ_UNCOMMITTED
- && !lock_clust_rec_cons_read_sees
- (clust_rec, clust_index, *offsets, trx->read_view)) {
+ && !lock_clust_rec_cons_read_sees(
+ clust_rec, clust_index, *offsets,
+ trx->read_view)) {
/* The following call returns 'offsets' associated with
'old_vers' */
- err = row_sel_build_prev_vers_for_mysql
- (trx->read_view, clust_index,
- prebuilt, clust_rec, offsets, offset_heap,
- &old_vers, mtr);
+ err = row_sel_build_prev_vers_for_mysql(
+ trx->read_view, clust_index, prebuilt,
+ clust_rec, offsets, offset_heap, &old_vers,
+ mtr);
if (err != DB_SUCCESS) {
@@ -2901,16 +2895,18 @@ row_sel_get_clust_rec_for_mysql(
visit through secondary index records that would not really
exist in our snapshot. */
- if (clust_rec && (old_vers || rec_get_deleted_flag
- (rec, dict_table_is_comp(sec_index->table)))
- && !row_sel_sec_rec_is_for_clust_rec
- (rec, sec_index, clust_rec, clust_index)) {
+ if (clust_rec && (old_vers || rec_get_deleted_flag(
+ rec,
+ dict_table_is_comp(
+ sec_index->table)))
+ && !row_sel_sec_rec_is_for_clust_rec(
+ rec, sec_index, clust_rec, clust_index)) {
clust_rec = NULL;
} else {
#ifdef UNIV_SEARCH_DEBUG
ut_a(clust_rec == NULL
- || row_sel_sec_rec_is_for_clust_rec
- (rec, sec_index, clust_rec, clust_index));
+ || row_sel_sec_rec_is_for_clust_rec(
+ rec, sec_index, clust_rec, clust_index));
#endif
}
}
@@ -3018,8 +3014,8 @@ row_sel_pop_cached_row_for_mysql(
if (UNIV_UNLIKELY(prebuilt->keep_other_fields_on_keyread)) {
/* Copy cache record field by field, don't touch fields that
are not covered by current key */
- cached_rec = prebuilt->fetch_cache
- [prebuilt->fetch_cache_first];
+ cached_rec = prebuilt->fetch_cache[
+ prebuilt->fetch_cache_first];
for (i = 0; i < prebuilt->n_template; i++) {
templ = prebuilt->mysql_template + i;
@@ -3031,8 +3027,7 @@ row_sel_pop_cached_row_for_mysql(
if (templ->mysql_null_bit_mask) {
buf[templ->mysql_null_byte_offset]
^= (buf[templ->mysql_null_byte_offset]
- ^ cached_rec
- [templ->mysql_null_byte_offset])
+ ^ cached_rec[templ->mysql_null_byte_offset])
& (byte)templ->mysql_null_bit_mask;
}
}
@@ -3088,9 +3083,10 @@ row_sel_push_cache_row_for_mysql(
ut_ad(prebuilt->fetch_cache_first == 0);
- if (UNIV_UNLIKELY(!row_sel_store_mysql_rec
- (prebuilt->fetch_cache[prebuilt->n_fetch_cached],
- prebuilt, rec, offsets))) {
+ if (UNIV_UNLIKELY(!row_sel_store_mysql_rec(
+ prebuilt->fetch_cache[
+ prebuilt->n_fetch_cached],
+ prebuilt, rec, offsets))) {
ut_error;
}
@@ -3217,15 +3213,12 @@ row_search_for_mysql(
ibool mtr_has_extra_clust_latch = FALSE;
ibool moves_up = FALSE;
ibool set_also_gap_locks = TRUE;
- /* if the query is a plain
- locking SELECT, and the isolation
- level is <= TRX_ISO_READ_COMMITTED,
- then this is set to FALSE */
+ /* if the query is a plain locking SELECT, and the isolation level
+ is <= TRX_ISO_READ_COMMITTED, then this is set to FALSE */
ibool did_semi_consistent_read = FALSE;
- /* if the returned record was locked
- and we did a semi-consistent read
- (fetch the newest committed version),
- then this is set to TRUE */
+ /* if the returned record was locked and we did a semi-consistent
+ read (fetch the newest committed version), then this is set to
+ TRUE */
#ifdef UNIV_SEARCH_DEBUG
ulint cnt = 0;
#endif /* UNIV_SEARCH_DEBUG */
@@ -3478,8 +3471,9 @@ row_search_for_mysql(
trx->has_search_latch = TRUE;
}
#endif
- switch (row_sel_try_search_shortcut_for_mysql
- (&rec, prebuilt, &offsets, &heap, &mtr)) {
+ switch (row_sel_try_search_shortcut_for_mysql(
+ &rec, prebuilt, &offsets, &heap,
+ &mtr)) {
case SEL_FOUND:
#ifdef UNIV_SEARCH_DEBUG
ut_a(0 == cmp_dtuple_rec(search_tuple,
@@ -3559,8 +3553,8 @@ shortcut_fails_too_big_rec:
/* Scan the MySQL query string; check if SELECT is the first
word there */
- if (dict_str_starts_with_keyword
- (trx->mysql_thd, *trx->mysql_query_str, "SELECT")) {
+ if (dict_str_starts_with_keyword(
+ trx->mysql_thd, *trx->mysql_query_str, "SELECT")) {
/* It is a plain locking SELECT and the isolation
level is low: do not lock gaps */
@@ -3587,9 +3581,9 @@ shortcut_fails_too_big_rec:
clust_index = dict_table_get_first_index(index->table);
if (UNIV_LIKELY(direction != 0)) {
- ibool need_to_process = sel_restore_position_for_mysql
- (&same_user_rec, BTR_SEARCH_LEAF,
- pcur, moves_up, &mtr);
+ ibool need_to_process = sel_restore_position_for_mysql(
+ &same_user_rec, BTR_SEARCH_LEAF,
+ pcur, moves_up, &mtr);
if (UNIV_UNLIKELY(need_to_process)) {
if (UNIV_UNLIKELY(prebuilt->row_read_type
@@ -3621,13 +3615,13 @@ shortcut_fails_too_big_rec:
pcur->trx_if_known = trx;
} else {
if (mode == PAGE_CUR_G) {
- btr_pcur_open_at_index_side
- (TRUE, index,
- BTR_SEARCH_LEAF, pcur, FALSE, &mtr);
+ btr_pcur_open_at_index_side(
+ TRUE, index, BTR_SEARCH_LEAF, pcur, FALSE,
+ &mtr);
} else if (mode == PAGE_CUR_L) {
- btr_pcur_open_at_index_side
- (FALSE, index,
- BTR_SEARCH_LEAF, pcur, FALSE, &mtr);
+ btr_pcur_open_at_index_side(
+ FALSE, index, BTR_SEARCH_LEAF, pcur, FALSE,
+ &mtr);
}
}
@@ -3759,7 +3753,7 @@ wrong_offs:
"InnoDB: Index corruption: rec offs %lu"
" next offs %lu, page no %lu,\n"
"InnoDB: ",
- (ulong) ut_align_offset(rec, UNIV_PAGE_SIZE),
+ (ulong) page_offset(rec),
(ulong) next_offs,
(ulong) buf_frame_get_page_no(rec));
dict_index_name_print(stderr, trx, index);
@@ -3779,7 +3773,7 @@ wrong_offs:
"InnoDB: Index corruption: rec offs %lu"
" next offs %lu, page no %lu,\n"
"InnoDB: ",
- (ulong) ut_align_offset(rec, UNIV_PAGE_SIZE),
+ (ulong) page_offset(rec),
(ulong) next_offs,
(ulong) buf_frame_get_page_no(rec));
dict_index_name_print(stderr, trx, index);
@@ -3804,7 +3798,7 @@ wrong_offs:
"InnoDB: Index corruption: rec offs %lu"
" next offs %lu, page no %lu,\n"
"InnoDB: ",
- (ulong) ut_align_offset(rec, UNIV_PAGE_SIZE),
+ (ulong) page_offset(rec),
(ulong) next_offs,
(ulong) buf_frame_get_page_no(rec));
dict_index_name_print(stderr, trx, index);
@@ -3839,10 +3833,10 @@ wrong_offs:
option is not set or this session is not
using a READ COMMITTED isolation level. */
- err = sel_set_rec_lock
- (rec, index, offsets,
- prebuilt->select_lock_type,
- LOCK_GAP, thr);
+ err = sel_set_rec_lock(
+ rec, index, offsets,
+ prebuilt->select_lock_type, LOCK_GAP,
+ thr);
if (err != DB_SUCCESS) {
@@ -3874,10 +3868,10 @@ wrong_offs:
option is not set or this session is not
using a READ COMMITTED isolation level. */
- err = sel_set_rec_lock
- (rec, index, offsets,
- prebuilt->select_lock_type,
- LOCK_GAP, thr);
+ err = sel_set_rec_lock(
+ rec, index, offsets,
+ prebuilt->select_lock_type, LOCK_GAP,
+ thr);
if (err != DB_SUCCESS) {
@@ -3961,9 +3955,9 @@ no_gap_lock:
/* The following call returns 'offsets'
associated with 'old_vers' */
- err = row_sel_build_committed_vers_for_mysql
- (clust_index, prebuilt, rec,
- &offsets, &heap, &old_vers, &mtr);
+ err = row_sel_build_committed_vers_for_mysql(
+ clust_index, prebuilt, rec,
+ &offsets, &heap, &old_vers, &mtr);
if (err != DB_SUCCESS) {
@@ -3977,8 +3971,8 @@ no_gap_lock:
goto lock_wait_or_error;
}
if (UNIV_LIKELY(trx->wait_lock != NULL)) {
- lock_cancel_waiting_and_release
- (trx->wait_lock);
+ lock_cancel_waiting_and_release(
+ trx->wait_lock);
trx_reset_new_rec_lock_info(trx);
} else {
mutex_exit(&kernel_mutex);
@@ -4025,16 +4019,16 @@ no_gap_lock:
by skipping this lookup */
if (UNIV_LIKELY(srv_force_recovery < 5)
- && !lock_clust_rec_cons_read_sees
- (rec, index, offsets, trx->read_view)) {
+ && !lock_clust_rec_cons_read_sees(
+ rec, index, offsets, trx->read_view)) {
rec_t* old_vers;
/* The following call returns 'offsets'
associated with 'old_vers' */
- err = row_sel_build_prev_vers_for_mysql
- (trx->read_view, clust_index,
- prebuilt, rec, &offsets, &heap,
- &old_vers, &mtr);
+ err = row_sel_build_prev_vers_for_mysql(
+ trx->read_view, clust_index,
+ prebuilt, rec, &offsets, &heap,
+ &old_vers, &mtr);
if (err != DB_SUCCESS) {
@@ -4084,6 +4078,23 @@ no_gap_lock:
row_unlock_for_mysql(prebuilt, TRUE);
}
+ /* This is an optimization to skip setting the next key lock
+ on the record that follows this delete-marked record. This
+ optimization works because of the unique search criteria
+ which precludes the presence of a range lock between this
+ delete marked record and the record following it.
+
+ For now this is applicable only to clustered indexes while
+ doing a unique search. There is scope for further optimization
+ applicable to unique secondary indexes. Current behaviour is
+ to widen the scope of a lock on an already delete marked record
+ if the same record is deleted twice by the same transaction */
+ if (index == clust_index && unique_search) {
+ err = DB_RECORD_NOT_FOUND;
+
+ goto normal_return;
+ }
+
goto next_rec;
}
@@ -4209,9 +4220,9 @@ requires_clust_rec:
if (prebuilt->clust_index_was_generated) {
if (result_rec != rec) {
- offsets = rec_get_offsets
- (rec, index, offsets,
- ULINT_UNDEFINED, &heap);
+ offsets = rec_get_offsets(
+ rec, index, offsets, ULINT_UNDEFINED,
+ &heap);
}
row_sel_store_row_id_to_prebuilt(prebuilt, rec,
index, offsets);
@@ -4466,8 +4477,8 @@ row_search_check_if_query_cache_permitted(
if (trx->isolation_level >= TRX_ISO_REPEATABLE_READ
&& !trx->read_view) {
- trx->read_view = read_view_open_now
- (trx->id, trx->global_read_view_heap);
+ trx->read_view = read_view_open_now(
+ trx->id, trx->global_read_view_heap);
trx->global_read_view = trx->read_view;
}
}
diff --git a/storage/innobase/row/row0uins.c b/storage/innobase/row/row0uins.c
index 822b7cfb9f2..ce9ab792204 100644
--- a/storage/innobase/row/row0uins.c
+++ b/storage/innobase/row/row0uins.c
@@ -286,8 +286,8 @@ row_undo_ins(
return(DB_SUCCESS);
}
- node->index = dict_table_get_next_index
- (dict_table_get_first_index(node->table));
+ node->index = dict_table_get_next_index(
+ dict_table_get_first_index(node->table));
while (node->index != NULL) {
entry = row_build_index_entry(node->row, node->index,
diff --git a/storage/innobase/row/row0umod.c b/storage/innobase/row/row0umod.c
index 778f240d18e..68139da116e 100644
--- a/storage/innobase/row/row0umod.c
+++ b/storage/innobase/row/row0umod.c
@@ -108,12 +108,12 @@ row_undo_mod_clust_low(
} else {
ut_ad(mode == BTR_MODIFY_TREE);
- err = btr_cur_pessimistic_update
- (BTR_NO_LOCKING_FLAG
- | BTR_NO_UNDO_LOG_FLAG
- | BTR_KEEP_SYS_FLAG,
- btr_cur, &dummy_big_rec, node->update,
- node->cmpl_info, thr, mtr);
+ err = btr_cur_pessimistic_update(
+ BTR_NO_LOCKING_FLAG
+ | BTR_NO_UNDO_LOG_FLAG
+ | BTR_KEEP_SYS_FLAG,
+ btr_cur, &dummy_big_rec, node->update,
+ node->cmpl_info, thr, mtr);
}
return(err);
@@ -444,8 +444,8 @@ row_undo_mod_del_unmark_sec_and_undo_update(
ut_a(err == DB_SUCCESS);
heap = mem_heap_create(100);
- update = row_upd_build_sec_rec_difference_binary
- (index, entry, btr_cur_get_rec(btr_cur), trx, heap);
+ update = row_upd_build_sec_rec_difference_binary(
+ index, entry, btr_cur_get_rec(btr_cur), trx, heap);
if (upd_get_n_fields(update) == 0) {
/* Do nothing */
@@ -454,18 +454,18 @@ row_undo_mod_del_unmark_sec_and_undo_update(
/* Try an optimistic updating of the record, keeping
changes within the page */
- err = btr_cur_optimistic_update
- (BTR_KEEP_SYS_FLAG | BTR_NO_LOCKING_FLAG,
- btr_cur, update, 0, thr, &mtr);
+ err = btr_cur_optimistic_update(
+ BTR_KEEP_SYS_FLAG | BTR_NO_LOCKING_FLAG,
+ btr_cur, update, 0, thr, &mtr);
if (err == DB_OVERFLOW || err == DB_UNDERFLOW) {
err = DB_FAIL;
}
} else {
ut_a(mode == BTR_MODIFY_TREE);
- err = btr_cur_pessimistic_update
- (BTR_KEEP_SYS_FLAG | BTR_NO_LOCKING_FLAG,
- btr_cur, &dummy_big_rec,
- update, 0, thr, &mtr);
+ err = btr_cur_pessimistic_update(
+ BTR_KEEP_SYS_FLAG | BTR_NO_LOCKING_FLAG,
+ btr_cur, &dummy_big_rec,
+ update, 0, thr, &mtr);
}
mem_heap_free(heap);
@@ -538,11 +538,11 @@ row_undo_mod_del_mark_sec(
entry = row_build_index_entry(node->row, index, heap);
- err = row_undo_mod_del_unmark_sec_and_undo_update
- (BTR_MODIFY_LEAF, thr, index, entry);
+ err = row_undo_mod_del_unmark_sec_and_undo_update(
+ BTR_MODIFY_LEAF, thr, index, entry);
if (err == DB_FAIL) {
- err = row_undo_mod_del_unmark_sec_and_undo_update
- (BTR_MODIFY_TREE, thr, index, entry);
+ err = row_undo_mod_del_unmark_sec_and_undo_update(
+ BTR_MODIFY_TREE, thr, index, entry);
}
if (err != DB_SUCCESS) {
@@ -620,11 +620,11 @@ row_undo_mod_upd_exist_sec(
row_upd_index_replace_new_col_vals(entry, index,
node->update, NULL);
- err = row_undo_mod_del_unmark_sec_and_undo_update
- (BTR_MODIFY_LEAF, thr, index, entry);
+ err = row_undo_mod_del_unmark_sec_and_undo_update(
+ BTR_MODIFY_LEAF, thr, index, entry);
if (err == DB_FAIL) {
- err = row_undo_mod_del_unmark_sec_and_undo_update
- (BTR_MODIFY_TREE, thr, index, entry);
+ err = row_undo_mod_del_unmark_sec_and_undo_update(
+ BTR_MODIFY_TREE, thr, index, entry);
}
if (err != DB_SUCCESS) {
@@ -736,8 +736,8 @@ row_undo_mod(
return(DB_SUCCESS);
}
- node->index = dict_table_get_next_index
- (dict_table_get_first_index(node->table));
+ node->index = dict_table_get_next_index(
+ dict_table_get_first_index(node->table));
if (node->rec_type == TRX_UNDO_UPD_EXIST_REC) {
diff --git a/storage/innobase/row/row0upd.c b/storage/innobase/row/row0upd.c
index 84f5f2a1acf..6533ac93d7d 100644
--- a/storage/innobase/row/row0upd.c
+++ b/storage/innobase/row/row0upd.c
@@ -197,8 +197,9 @@ row_upd_check_references_constraints(
if (foreign->referenced_index == index
&& (node->is_delete
- || row_upd_changes_first_fields_binary
- (entry, index, node->update, foreign->n_fields))) {
+ || row_upd_changes_first_fields_binary(
+ entry, index, node->update,
+ foreign->n_fields))) {
if (foreign->foreign_table == NULL) {
dict_table_get(foreign->foreign_table_name);
@@ -218,8 +219,8 @@ row_upd_check_references_constraints(
But the counter on the table protects 'foreign' from
being dropped while the check is running. */
- err = row_ins_check_foreign_constraint
- (FALSE, foreign, table, entry, thr);
+ err = row_ins_check_foreign_constraint(
+ FALSE, foreign, table, entry, thr);
if (foreign->foreign_table) {
mutex_enter(&(dict_sys->mutex));
@@ -235,8 +236,8 @@ row_upd_check_references_constraints(
if (err != DB_SUCCESS) {
if (got_s_lock) {
- row_mysql_unfreeze_data_dictionary
- (trx);
+ row_mysql_unfreeze_data_dictionary(
+ trx);
}
mem_heap_free(heap);
@@ -388,9 +389,9 @@ row_upd_changes_field_size_or_external(
this fix also to 4.0. The merge to 5.0 will be made
manually immediately after we commit this to 4.1. */
- new_len = dtype_get_sql_null_size
- (dict_index_get_nth_type(index,
- upd_field->field_no));
+ new_len = dict_col_get_sql_null_size(
+ dict_index_get_nth_col(index,
+ upd_field->field_no));
}
old_len = rec_offs_nth_size(offsets, upd_field->field_no);
@@ -479,8 +480,8 @@ row_upd_write_sys_vals_to_log(
ut_ad(mtr);
log_ptr += mach_write_compressed(log_ptr,
- dict_index_get_sys_col_pos
- (index, DATA_TRX_ID));
+ dict_index_get_sys_col_pos(
+ index, DATA_TRX_ID));
trx_write_roll_ptr(log_ptr, roll_ptr);
log_ptr += DATA_ROLL_PTR_LEN;
@@ -884,7 +885,6 @@ row_upd_index_replace_new_col_vals_index_pos(
ulint j;
ulint i;
ulint n_fields;
- dtype_t* cur_type;
ut_ad(index);
@@ -913,8 +913,8 @@ row_upd_index_replace_new_col_vals_index_pos(
dfield_set_data(dfield, new_val->data,
new_val->len);
if (heap && new_val->len != UNIV_SQL_NULL) {
- dfield->data = mem_heap_alloc
- (heap, new_val->len);
+ dfield->data = mem_heap_alloc(
+ heap, new_val->len);
ut_memcpy(dfield->data, new_val->data,
new_val->len);
}
@@ -922,13 +922,17 @@ row_upd_index_replace_new_col_vals_index_pos(
if (field->prefix_len > 0
&& new_val->len != UNIV_SQL_NULL) {
- cur_type = dict_col_get_type
- (dict_field_get_col(field));
+ const dict_col_t* col
+ = dict_field_get_col(field);
dfield->len
- = dtype_get_at_most_n_mbchars
- (cur_type, field->prefix_len,
- new_val->len, new_val->data);
+ = dtype_get_at_most_n_mbchars(
+ col->prtype,
+ col->mbminlen,
+ col->mbmaxlen,
+ field->prefix_len,
+ new_val->len,
+ new_val->data);
}
}
}
@@ -952,27 +956,31 @@ row_upd_index_replace_new_col_vals(
copy the new values, set this as NULL if you
do not want allocation */
{
- dict_field_t* field;
upd_field_t* upd_field;
dfield_t* dfield;
dfield_t* new_val;
ulint j;
ulint i;
- dtype_t* cur_type;
+ dict_index_t* clust_index;
ut_ad(index);
+ clust_index = dict_table_get_first_index(index->table);
+
dtuple_set_info_bits(entry, update->info_bits);
for (j = 0; j < dict_index_get_n_fields(index); j++) {
- field = dict_index_get_nth_field(index, j);
+ ulint clust_pos;
+ dict_field_t* field = dict_index_get_nth_field(index, j);
+
+ clust_pos = dict_col_get_clust_pos(field->col, clust_index);
for (i = 0; i < upd_get_n_fields(update); i++) {
upd_field = upd_get_nth_field(update, i);
- if (upd_field->field_no == field->col->clust_pos) {
+ if (upd_field->field_no == clust_pos) {
dfield = dtuple_get_nth_field(entry, j);
@@ -981,8 +989,8 @@ row_upd_index_replace_new_col_vals(
dfield_set_data(dfield, new_val->data,
new_val->len);
if (heap && new_val->len != UNIV_SQL_NULL) {
- dfield->data = mem_heap_alloc
- (heap, new_val->len);
+ dfield->data = mem_heap_alloc(
+ heap, new_val->len);
ut_memcpy(dfield->data, new_val->data,
new_val->len);
}
@@ -990,13 +998,17 @@ row_upd_index_replace_new_col_vals(
if (field->prefix_len > 0
&& new_val->len != UNIV_SQL_NULL) {
- cur_type = dict_col_get_type
- (dict_field_get_col(field));
+ const dict_col_t* col
+ = dict_field_get_col(field);
dfield->len
- = dtype_get_at_most_n_mbchars
- (cur_type, field->prefix_len,
- new_val->len, new_val->data);
+ = dtype_get_at_most_n_mbchars(
+ col->prtype,
+ col->mbminlen,
+ col->mbmaxlen,
+ field->prefix_len,
+ new_val->len,
+ new_val->data);
}
}
}
@@ -1025,30 +1037,34 @@ row_upd_changes_ord_field_binary(
field numbers in this MUST be clustered index
positions! */
{
- upd_field_t* upd_field;
- dict_field_t* ind_field;
- dict_col_t* col;
ulint n_unique;
ulint n_upd_fields;
- ulint col_pos;
- ulint col_no;
ulint i, j;
+ dict_index_t* clust_index;
ut_ad(update && index);
n_unique = dict_index_get_n_unique(index);
n_upd_fields = upd_get_n_fields(update);
+ clust_index = dict_table_get_first_index(index->table);
+
for (i = 0; i < n_unique; i++) {
+ const dict_field_t* ind_field;
+ const dict_col_t* col;
+ ulint col_pos;
+ ulint col_no;
+
ind_field = dict_index_get_nth_field(index, i);
col = dict_field_get_col(ind_field);
- col_pos = dict_col_get_clust_pos(col);
+ col_pos = dict_col_get_clust_pos(col, clust_index);
col_no = dict_col_get_no(col);
for (j = 0; j < n_upd_fields; j++) {
- upd_field = upd_get_nth_field(update, j);
+ upd_field_t* upd_field
+ = upd_get_nth_field(update, j);
/* Note that if the index field is a column prefix
then it may be that row does not contain an externally
@@ -1058,9 +1074,9 @@ row_upd_changes_ord_field_binary(
if (col_pos == upd_field->field_no
&& (row == NULL
|| ind_field->prefix_len > 0
- || !dfield_datas_are_binary_equal
- (dtuple_get_nth_field(row, col_no),
- &(upd_field->new_val)))) {
+ || !dfield_datas_are_binary_equal(
+ dtuple_get_nth_field(row, col_no),
+ &(upd_field->new_val)))) {
return(TRUE);
}
@@ -1092,8 +1108,8 @@ row_upd_changes_some_index_ord_field_binary(
upd_field = upd_get_nth_field(update, i);
- if (dict_field_get_col(dict_index_get_nth_field
- (index, upd_field->field_no))
+ if (dict_field_get_col(dict_index_get_nth_field(
+ index, upd_field->field_no))
->ord_part) {
return(TRUE);
@@ -1117,34 +1133,37 @@ row_upd_changes_first_fields_binary(
upd_t* update, /* in: update vector for the row */
ulint n) /* in: how many first fields to check */
{
- upd_field_t* upd_field;
- dict_field_t* ind_field;
- dict_col_t* col;
ulint n_upd_fields;
- ulint col_pos;
ulint i, j;
+ dict_index_t* clust_index;
- ut_a(update && index);
- ut_a(n <= dict_index_get_n_fields(index));
+ ut_ad(update && index);
+ ut_ad(n <= dict_index_get_n_fields(index));
n_upd_fields = upd_get_n_fields(update);
+ clust_index = dict_table_get_first_index(index->table);
for (i = 0; i < n; i++) {
+ const dict_field_t* ind_field;
+ const dict_col_t* col;
+ ulint col_pos;
+
ind_field = dict_index_get_nth_field(index, i);
col = dict_field_get_col(ind_field);
- col_pos = dict_col_get_clust_pos(col);
+ col_pos = dict_col_get_clust_pos(col, clust_index);
ut_a(ind_field->prefix_len == 0);
for (j = 0; j < n_upd_fields; j++) {
- upd_field = upd_get_nth_field(update, j);
+ upd_field_t* upd_field
+ = upd_get_nth_field(update, j);
if (col_pos == upd_field->field_no
- && !dfield_datas_are_binary_equal
- (dtuple_get_nth_field(entry, i),
- &(upd_field->new_val))) {
+ && !dfield_datas_are_binary_equal(
+ dtuple_get_nth_field(entry, i),
+ &(upd_field->new_val))) {
return(TRUE);
}
@@ -1322,9 +1341,9 @@ row_upd_sec_index_entry(
/* NOTE that the following call loses
the position of pcur ! */
- err = row_upd_check_references_constraints
- (node, &pcur, index->table,
- index, thr, &mtr);
+ err = row_upd_check_references_constraints(
+ node, &pcur, index->table,
+ index, thr, &mtr);
if (err != DB_SUCCESS) {
goto close_cur;
@@ -1356,8 +1375,8 @@ close_cur:
}
/***************************************************************
-Updates secondary index record if it is changed in the row update. This
-should be quite rare in database applications. */
+Updates the secondary index record if it is changed in the row update or
+deletes it if this is a delete. */
UNIV_INLINE
ulint
row_upd_sec_step(
@@ -1434,17 +1453,17 @@ row_upd_clust_rec_by_insert(
free those externally stored fields even if the delete marked
record is removed from the index tree, or updated. */
- btr_cur_mark_extern_inherited_fields
- (btr_cur_get_rec(btr_cur),
- rec_get_offsets(btr_cur_get_rec(btr_cur),
- dict_table_get_first_index(table),
- offsets_, ULINT_UNDEFINED, &heap),
- node->update, mtr);
+ btr_cur_mark_extern_inherited_fields(
+ btr_cur_get_rec(btr_cur),
+ rec_get_offsets(btr_cur_get_rec(btr_cur),
+ dict_table_get_first_index(table),
+ offsets_, ULINT_UNDEFINED, &heap),
+ node->update, mtr);
if (check_ref) {
/* NOTE that the following call loses
the position of pcur ! */
- err = row_upd_check_references_constraints
- (node, pcur, table, index, thr, mtr);
+ err = row_upd_check_references_constraints(
+ node, pcur, table, index, thr, mtr);
if (err != DB_SUCCESS) {
mtr_commit(mtr);
if (UNIV_LIKELY_NULL(heap)) {
@@ -1573,10 +1592,10 @@ row_upd_clust_rec(
ut_a(btr_pcur_restore_position(BTR_MODIFY_TREE, pcur, mtr));
rec = btr_cur_get_rec(btr_cur);
- err = btr_store_big_rec_extern_fields
- (index, rec,
- rec_get_offsets(rec, index, offsets_,
- ULINT_UNDEFINED, &heap),
+ err = btr_store_big_rec_extern_fields(
+ index, rec,
+ rec_get_offsets(rec, index, offsets_,
+ ULINT_UNDEFINED, &heap),
big_rec, mtr);
if (UNIV_LIKELY_NULL(heap)) {
mem_heap_free(heap);
@@ -1730,8 +1749,8 @@ row_upd_clust_step(
ULINT_UNDEFINED, &heap);
if (!node->has_clust_rec_x_lock) {
- err = lock_clust_rec_modify_check_and_lock
- (0, rec, index, offsets, thr);
+ err = lock_clust_rec_modify_check_and_lock(
+ 0, rec, index, offsets, thr);
if (err != DB_SUCCESS) {
mtr_commit(mtr);
goto exit_func;
@@ -1831,14 +1850,14 @@ row_upd(
ut_ad(node && thr);
- if (node->in_mysql_interface) {
+ if (UNIV_LIKELY(node->in_mysql_interface)) {
/* We do not get the cmpl_info value from the MySQL
interpreter: we must calculate it on the fly: */
if (node->is_delete
- || row_upd_changes_some_index_ord_field_binary
- (node->table, node->update)) {
+ || row_upd_changes_some_index_ord_field_binary(
+ node->table, node->update)) {
node->cmpl_info = 0;
} else {
node->cmpl_info = UPD_NODE_NO_ORD_CHANGE;
@@ -2046,9 +2065,9 @@ row_upd_in_place_in_select(
}
row_upd_eval_new_vals(node->update);
- ut_ad(!rec_get_deleted_flag
- (btr_pcur_get_rec(pcur),
- dict_table_is_comp(btr_cur->index->table)));
+ ut_ad(!rec_get_deleted_flag(
+ btr_pcur_get_rec(pcur),
+ dict_table_is_comp(btr_cur->index->table)));
ut_ad(node->cmpl_info & UPD_NODE_NO_SIZE_CHANGE);
ut_ad(node->cmpl_info & UPD_NODE_NO_ORD_CHANGE);
diff --git a/storage/innobase/row/row0vers.c b/storage/innobase/row/row0vers.c
index 9b51314df7b..c8b71965f75 100644
--- a/storage/innobase/row/row0vers.c
+++ b/storage/innobase/row/row0vers.c
@@ -158,9 +158,9 @@ row_vers_impl_x_locked_off_kernel(
mem_heap_free(heap2); /* free version and clust_offsets */
if (prev_version) {
- clust_offsets = rec_get_offsets
- (prev_version, clust_index, NULL,
- ULINT_UNDEFINED, &heap);
+ clust_offsets = rec_get_offsets(
+ prev_version, clust_index, NULL,
+ ULINT_UNDEFINED, &heap);
row = row_build(ROW_COPY_POINTERS, clust_index,
prev_version, clust_offsets, heap);
entry = row_build_index_entry(row, index, heap);
diff --git a/storage/innobase/srv/srv0srv.c b/storage/innobase/srv/srv0srv.c
index b781a601039..5d92b913934 100644
--- a/storage/innobase/srv/srv0srv.c
+++ b/storage/innobase/srv/srv0srv.c
@@ -899,21 +899,21 @@ srv_init(void)
table = dict_mem_table_create("SYS_DUMMY1",
DICT_HDR_SPACE, 1, 0);
dict_mem_table_add_col(table, "DUMMY", DATA_CHAR,
- DATA_ENGLISH | DATA_NOT_NULL, 8, 0);
+ DATA_ENGLISH | DATA_NOT_NULL, 8);
- srv_sys->dummy_ind1 = dict_mem_index_create
- ("SYS_DUMMY1", "SYS_DUMMY1", DICT_HDR_SPACE, 0, 1);
- dict_index_add_col(srv_sys->dummy_ind1,
+ srv_sys->dummy_ind1 = dict_mem_index_create(
+ "SYS_DUMMY1", "SYS_DUMMY1", DICT_HDR_SPACE, 0, 1);
+ dict_index_add_col(srv_sys->dummy_ind1, table, (dict_col_t*)
dict_table_get_nth_col(table, 0), 0);
srv_sys->dummy_ind1->table = table;
/* create dummy table and index for new-style infimum and supremum */
table = dict_mem_table_create("SYS_DUMMY2",
DICT_HDR_SPACE, 1, DICT_TF_COMPACT);
dict_mem_table_add_col(table, "DUMMY", DATA_CHAR,
- DATA_ENGLISH | DATA_NOT_NULL, 8, 0);
- srv_sys->dummy_ind2 = dict_mem_index_create
- ("SYS_DUMMY2", "SYS_DUMMY2", DICT_HDR_SPACE, 0, 1);
- dict_index_add_col(srv_sys->dummy_ind2,
+ DATA_ENGLISH | DATA_NOT_NULL, 8);
+ srv_sys->dummy_ind2 = dict_mem_index_create(
+ "SYS_DUMMY2", "SYS_DUMMY2", DICT_HDR_SPACE, 0, 1);
+ dict_index_add_col(srv_sys->dummy_ind2, table, (dict_col_t*)
dict_table_get_nth_col(table, 0), 0);
srv_sys->dummy_ind2->table = table;
@@ -1902,8 +1902,8 @@ loop:
if (srv_innodb_status) {
mutex_enter(&srv_monitor_file_mutex);
rewind(srv_monitor_file);
- srv_printf_innodb_monitor
- (srv_monitor_file, NULL, NULL);
+ srv_printf_innodb_monitor(srv_monitor_file, NULL,
+ NULL);
os_file_set_eof(srv_monitor_file);
mutex_exit(&srv_monitor_file_mutex);
}
@@ -1984,9 +1984,9 @@ loop:
granted: in that case do nothing */
if (thr_get_trx(slot->thr)->wait_lock) {
- lock_cancel_waiting_and_release
- (thr_get_trx(slot->thr)
- ->wait_lock);
+ lock_cancel_waiting_and_release(
+ thr_get_trx(slot->thr)
+ ->wait_lock);
}
}
}
@@ -2493,8 +2493,8 @@ flush_loop:
srv_main_thread_op_info = "flushing buffer pool pages";
if (srv_fast_shutdown < 2) {
- n_pages_flushed = buf_flush_batch
- (BUF_FLUSH_LIST, 100, ut_dulint_max);
+ n_pages_flushed = buf_flush_batch(BUF_FLUSH_LIST, 100,
+ ut_dulint_max);
} else {
/* In the fastest shutdown we do not flush the buffer pool
to data files: we set n_pages_flushed to 0 artificially. */
diff --git a/storage/innobase/srv/srv0start.c b/storage/innobase/srv/srv0start.c
index 2b9bd402bb7..5eaea26b75d 100644
--- a/storage/innobase/srv/srv0start.c
+++ b/storage/innobase/srv/srv0start.c
@@ -301,8 +301,8 @@ srv_parse_data_file_paths_and_sizes(
str += (sizeof ":max:") - 1;
- str = srv_parse_megabytes
- (str, max_auto_extend_size);
+ str = srv_parse_megabytes(
+ str, max_auto_extend_size);
}
if (*str != '\0') {
@@ -557,8 +557,8 @@ open_or_create_log_file(
*log_file_created = FALSE;
srv_normalize_path_for_win(srv_log_group_home_dirs[k]);
- srv_log_group_home_dirs[k] = srv_add_path_separator_if_needed
- (srv_log_group_home_dirs[k]);
+ srv_log_group_home_dirs[k] = srv_add_path_separator_if_needed(
+ srv_log_group_home_dirs[k]);
ut_a(strlen(srv_log_group_home_dirs[k])
< (sizeof name) - 10 - sizeof "ib_logfile");
@@ -796,17 +796,17 @@ open_or_create_data_files(
}
if (srv_data_file_is_raw_partition[i] == SRV_OLD_RAW) {
- files[i] = os_file_create
- (name, OS_FILE_OPEN_RAW,
- OS_FILE_NORMAL, OS_DATA_FILE, &ret);
+ files[i] = os_file_create(
+ name, OS_FILE_OPEN_RAW,
+ OS_FILE_NORMAL, OS_DATA_FILE, &ret);
} else if (i == 0) {
- files[i] = os_file_create
- (name, OS_FILE_OPEN_RETRY,
- OS_FILE_NORMAL, OS_DATA_FILE, &ret);
+ files[i] = os_file_create(
+ name, OS_FILE_OPEN_RETRY,
+ OS_FILE_NORMAL, OS_DATA_FILE, &ret);
} else {
- files[i] = os_file_create
- (name, OS_FILE_OPEN,
- OS_FILE_NORMAL, OS_DATA_FILE, &ret);
+ files[i] = os_file_create(
+ name, OS_FILE_OPEN, OS_FILE_NORMAL,
+ OS_DATA_FILE, &ret);
}
if (!ret) {
@@ -876,12 +876,12 @@ open_or_create_data_files(
return(DB_ERROR);
}
skip_size_check:
- fil_read_flushed_lsn_and_arch_log_no
- (files[i], one_opened,
+ fil_read_flushed_lsn_and_arch_log_no(
+ files[i], one_opened,
#ifdef UNIV_LOG_ARCHIVE
- min_arch_log_no, max_arch_log_no,
+ min_arch_log_no, max_arch_log_no,
#endif /* UNIV_LOG_ARCHIVE */
- min_flushed_lsn, max_flushed_lsn);
+ min_flushed_lsn, max_flushed_lsn);
one_opened = TRUE;
} else {
/* We created the data file and now write it full of
@@ -915,10 +915,10 @@ skip_size_check:
"InnoDB: Database physically writes the"
" file full: wait...\n");
- ret = os_file_set_size
- (name, files[i],
- srv_calc_low32(srv_data_file_sizes[i]),
- srv_calc_high32(srv_data_file_sizes[i]));
+ ret = os_file_set_size(
+ name, files[i],
+ srv_calc_low32(srv_data_file_sizes[i]),
+ srv_calc_high32(srv_data_file_sizes[i]));
if (!ret) {
fprintf(stderr,
@@ -1163,7 +1163,7 @@ innobase_start_or_create_for_mysql(void)
maximum number of threads that can wait in the 'srv_conc array' for
their time to enter InnoDB. */
-#if defined(__WIN__) || defined(__NETWARE__)
+#if defined(__NETWARE__)
/* Create less event semaphores because Win 98/ME had
difficulty creating 40000 event semaphores. Comment from
@@ -1198,9 +1198,9 @@ innobase_start_or_create_for_mysql(void)
mutex_create(&srv_monitor_file_mutex, SYNC_NO_ORDER_CHECK);
if (srv_innodb_status) {
- srv_monitor_file_name = mem_alloc
- (strlen(fil_path_to_mysql_datadir)
- + 20 + sizeof "/innodb_status.");
+ srv_monitor_file_name = mem_alloc(
+ strlen(fil_path_to_mysql_datadir)
+ + 20 + sizeof "/innodb_status.");
sprintf(srv_monitor_file_name, "%s/innodb_status.%lu",
fil_path_to_mysql_datadir, os_proc_get_number());
srv_monitor_file = fopen(srv_monitor_file_name, "w+");
@@ -1471,10 +1471,9 @@ innobase_start_or_create_for_mysql(void)
fprintf(stderr,
"InnoDB: Starting archive"
" recovery from a backup...\n");
- err = recv_recovery_from_archive_start
- (min_flushed_lsn,
- srv_archive_recovery_limit_lsn,
- min_arch_log_no);
+ err = recv_recovery_from_archive_start(
+ min_flushed_lsn, srv_archive_recovery_limit_lsn,
+ min_arch_log_no);
if (err != DB_SUCCESS) {
return(DB_ERROR);
@@ -1535,8 +1534,8 @@ innobase_start_or_create_for_mysql(void)
data dictionary tables. Does that harm the scanning of
the data dictionary below? */
- dict_check_tablespaces_and_store_max_id
- (recv_needed_recovery);
+ dict_check_tablespaces_and_store_max_id(
+ recv_needed_recovery);
}
srv_startup_is_before_trx_rollback_phase = FALSE;
diff --git a/storage/innobase/sync/sync0arr.c b/storage/innobase/sync/sync0arr.c
index 278dd65bb1e..e45cd48a6b4 100644
--- a/storage/innobase/sync/sync0arr.c
+++ b/storage/innobase/sync/sync0arr.c
@@ -737,9 +737,9 @@ sync_array_detect_deadlock(
(cannot be cell thread) (wait) x-lock, and
he is blocked by start thread */
- ret = sync_array_deadlock_step
- (arr, start, thread,
- debug->pass, depth);
+ ret = sync_array_deadlock_step(
+ arr, start, thread, debug->pass,
+ depth);
if (ret) {
print:
fprintf(stderr, "rw-lock %p ",
@@ -772,9 +772,9 @@ print:
holding (wait) x-lock, and he is blocked by
start thread */
- ret = sync_array_deadlock_step
- (arr, start, thread,
- debug->pass, depth);
+ ret = sync_array_deadlock_step(
+ arr, start, thread, debug->pass,
+ depth);
if (ret) {
goto print;
}
diff --git a/storage/innobase/sync/sync0rw.c b/storage/innobase/sync/sync0rw.c
index f22b0dc8d61..304801d0a3b 100644
--- a/storage/innobase/sync/sync0rw.c
+++ b/storage/innobase/sync/sync0rw.c
@@ -89,7 +89,8 @@ void
rw_lock_create_func(
/*================*/
rw_lock_t* lock, /* in: pointer to memory */
- ulint level, /* in: level */
+ ulint level __attribute__((unused)),
+ /* in: level */
const char* cfile_name, /* in: file name where created */
ulint cline, /* in: file line where created */
const char* cmutex_name) /* in: mutex name */
@@ -116,9 +117,9 @@ rw_lock_create_func(
#ifdef UNIV_SYNC_DEBUG
UT_LIST_INIT(lock->debug_list);
-#endif /* UNIV_SYNC_DEBUG */
lock->level = level;
+#endif /* UNIV_SYNC_DEBUG */
lock->magic_n = RW_LOCK_MAGIC_N;
diff --git a/storage/innobase/sync/sync0sync.c b/storage/innobase/sync/sync0sync.c
index d74b2b09ccf..91fd248502a 100644
--- a/storage/innobase/sync/sync0sync.c
+++ b/storage/innobase/sync/sync0sync.c
@@ -838,17 +838,17 @@ sync_thread_levels_g(
ulint line;
os_thread_id_t thread_id;
- mutex_get_debug_info
- (mutex, &file_name,
- &line, &thread_id);
+ mutex_get_debug_info(
+ mutex, &file_name,
+ &line, &thread_id);
fprintf(stderr,
"InnoDB: Locked mutex:"
" addr %p thread %ld"
" file %s line %ld\n",
(void*) mutex,
- os_thread_pf
- (thread_id),
+ os_thread_pf(
+ thread_id),
file_name,
(ulong) line);
#else /* UNIV_SYNC_DEBUG */
@@ -1155,8 +1155,8 @@ sync_thread_add_level(
case SYNC_IBUF_HEADER:
ut_a(sync_thread_levels_g(array, SYNC_FSP - 1)
&& !sync_thread_levels_contain(array, SYNC_IBUF_MUTEX)
- && !sync_thread_levels_contain
- (array, SYNC_IBUF_PESS_INSERT_MUTEX));
+ && !sync_thread_levels_contain(
+ array, SYNC_IBUF_PESS_INSERT_MUTEX));
break;
case SYNC_DICT_AUTOINC_MUTEX:
ut_a(sync_thread_levels_g(array, SYNC_DICT_AUTOINC_MUTEX));
diff --git a/storage/innobase/trx/trx0purge.c b/storage/innobase/trx/trx0purge.c
index 9689a9fb179..11e089ac90e 100644
--- a/storage/innobase/trx/trx0purge.c
+++ b/storage/innobase/trx/trx0purge.c
@@ -284,8 +284,8 @@ trx_purge_add_update_undo_to_history(
hist_size = mtr_read_ulint(rseg_header + TRX_RSEG_HISTORY_SIZE,
MLOG_4BYTES, mtr);
- ut_ad(undo->size == flst_get_len
- (seg_header + TRX_UNDO_PAGE_LIST, mtr));
+ ut_ad(undo->size == flst_get_len(
+ seg_header + TRX_UNDO_PAGE_LIST, mtr));
mlog_write_ulint(rseg_header + TRX_RSEG_HISTORY_SIZE,
hist_size + undo->size, MLOG_4BYTES, mtr);
@@ -454,8 +454,8 @@ trx_purge_truncate_rseg_history(
rseg_hdr = trx_rsegf_get(rseg->space, rseg->page_no, &mtr);
- hdr_addr = trx_purge_get_log_from_hist
- (flst_get_last(rseg_hdr + TRX_RSEG_HISTORY, &mtr));
+ hdr_addr = trx_purge_get_log_from_hist(
+ flst_get_last(rseg_hdr + TRX_RSEG_HISTORY, &mtr));
loop:
if (hdr_addr.page == FIL_NULL) {
@@ -493,8 +493,8 @@ loop:
return;
}
- prev_hdr_addr = trx_purge_get_log_from_hist
- (flst_get_prev_addr(log_hdr + TRX_UNDO_HISTORY_NODE, &mtr));
+ prev_hdr_addr = trx_purge_get_log_from_hist(
+ flst_get_prev_addr(log_hdr + TRX_UNDO_HISTORY_NODE, &mtr));
n_removed_logs++;
seg_hdr = undo_page + TRX_UNDO_SEG_HDR;
@@ -633,8 +633,8 @@ trx_purge_rseg_get_next_history_log(
purge_sys->n_pages_handled++;
- prev_log_addr = trx_purge_get_log_from_hist
- (flst_get_prev_addr(log_hdr + TRX_UNDO_HISTORY_NODE, &mtr));
+ prev_log_addr = trx_purge_get_log_from_hist(
+ flst_get_prev_addr(log_hdr + TRX_UNDO_HISTORY_NODE, &mtr));
if (prev_log_addr.page == FIL_NULL) {
/* No logs left in the history list */
@@ -855,9 +855,9 @@ trx_purge_get_next_rec(
purge_sys->hdr_page_no,
purge_sys->hdr_offset);
if (next_rec == NULL) {
- rec2 = trx_undo_get_next_rec
- (rec2, purge_sys->hdr_page_no,
- purge_sys->hdr_offset, &mtr);
+ rec2 = trx_undo_get_next_rec(
+ rec2, purge_sys->hdr_page_no,
+ purge_sys->hdr_offset, &mtr);
break;
}
diff --git a/storage/innobase/trx/trx0rec.c b/storage/innobase/trx/trx0rec.c
index 3a214d6ce38..69e858fe71d 100644
--- a/storage/innobase/trx/trx0rec.c
+++ b/storage/innobase/trx/trx0rec.c
@@ -50,8 +50,8 @@ trx_undof_page_add_undo_rec_log(
}
log_end = &log_ptr[11 + 13 + MLOG_BUF_MARGIN];
- log_ptr = mlog_write_initial_log_record_fast
- (undo_page, MLOG_UNDO_INSERT, log_ptr, mtr);
+ log_ptr = mlog_write_initial_log_record_fast(
+ undo_page, MLOG_UNDO_INSERT, log_ptr, mtr);
len = new_free - old_free - 4;
mach_write_to_2(log_ptr, len);
@@ -413,7 +413,6 @@ trx_undo_page_report_modify(
{
dict_table_t* table;
upd_field_t* upd_field;
- dict_col_t* col;
ulint first_free;
byte* ptr;
ulint len;
@@ -486,13 +485,13 @@ trx_undo_page_report_modify(
/* Store the values of the system columns */
field = rec_get_nth_field(rec, offsets,
- dict_index_get_sys_col_pos
- (index, DATA_TRX_ID), &len);
+ dict_index_get_sys_col_pos(
+ index, DATA_TRX_ID), &len);
ut_ad(len == DATA_TRX_ID_LEN);
trx_id = trx_read_trx_id(field);
field = rec_get_nth_field(rec, offsets,
- dict_index_get_sys_col_pos
- (index, DATA_ROLL_PTR), &len);
+ dict_index_get_sys_col_pos(
+ index, DATA_ROLL_PTR), &len);
ut_ad(len == DATA_ROLL_PTR_LEN);
roll_ptr = trx_read_roll_ptr(field);
@@ -567,9 +566,9 @@ trx_undo_page_report_modify(
/* If a field has external storage, we add
to flen the flag */
- len = mach_write_compressed
- (ptr,
- UNIV_EXTERN_STORAGE_FIELD + flen);
+ len = mach_write_compressed(
+ ptr,
+ UNIV_EXTERN_STORAGE_FIELD + flen);
/* Notify purge that it eventually has to
free the old externally stored field */
@@ -627,7 +626,8 @@ trx_undo_page_report_modify(
for (col_no = 0; col_no < dict_table_get_n_cols(table);
col_no++) {
- col = dict_table_get_nth_col(table, col_no);
+ const dict_col_t* col
+ = dict_table_get_nth_col(table, col_no);
if (col->ord_part > 0) {
@@ -826,9 +826,9 @@ trx_undo_update_rec_get_update(
buf = mem_heap_alloc(heap, DATA_ROLL_PTR_LEN);
trx_write_roll_ptr(buf, roll_ptr);
- upd_field_set_field_no
- (upd_field, dict_index_get_sys_col_pos(index, DATA_ROLL_PTR),
- index, trx);
+ upd_field_set_field_no(
+ upd_field, dict_index_get_sys_col_pos(index, DATA_ROLL_PTR),
+ index, trx);
dfield_set_data(&(upd_field->new_val), buf, DATA_ROLL_PTR_LEN);
/* Store then the updated ordinary columns to the update vector */
@@ -1094,14 +1094,14 @@ trx_undo_report_row_operation(
#endif /* UNIV_SYNC_DEBUG */
if (op_type == TRX_UNDO_INSERT_OP) {
- offset = trx_undo_page_report_insert
- (undo_page, trx, index, clust_entry, &mtr);
+ offset = trx_undo_page_report_insert(
+ undo_page, trx, index, clust_entry, &mtr);
} else {
offsets = rec_get_offsets(rec, index, offsets,
ULINT_UNDEFINED, &heap);
- offset = trx_undo_page_report_modify
- (undo_page, trx, index, rec, offsets,
- update, cmpl_info, &mtr);
+ offset = trx_undo_page_report_modify(
+ undo_page, trx, index, rec, offsets, update,
+ cmpl_info, &mtr);
}
if (offset == 0) {
diff --git a/storage/innobase/trx/trx0rseg.c b/storage/innobase/trx/trx0rseg.c
index 745a29021ad..7a6989c7b4f 100644
--- a/storage/innobase/trx/trx0rseg.c
+++ b/storage/innobase/trx/trx0rseg.c
@@ -171,18 +171,18 @@ trx_rseg_mem_create(
if (len > 0) {
trx_sys->rseg_history_len += len;
- node_addr = trx_purge_get_log_from_hist
- (flst_get_last(rseg_header + TRX_RSEG_HISTORY, mtr));
+ node_addr = trx_purge_get_log_from_hist(
+ flst_get_last(rseg_header + TRX_RSEG_HISTORY, mtr));
rseg->last_page_no = node_addr.page;
rseg->last_offset = node_addr.boffset;
undo_log_hdr = trx_undo_page_get(rseg->space, node_addr.page,
mtr) + node_addr.boffset;
- rseg->last_trx_no = mtr_read_dulint
- (undo_log_hdr + TRX_UNDO_TRX_NO, mtr);
- rseg->last_del_marks = mtr_read_ulint
- (undo_log_hdr + TRX_UNDO_DEL_MARKS, MLOG_2BYTES, mtr);
+ rseg->last_trx_no = mtr_read_dulint(
+ undo_log_hdr + TRX_UNDO_TRX_NO, mtr);
+ rseg->last_del_marks = mtr_read_ulint(
+ undo_log_hdr + TRX_UNDO_DEL_MARKS, MLOG_2BYTES, mtr);
} else {
rseg->last_page_no = FIL_NULL;
}
diff --git a/storage/innobase/trx/trx0sys.c b/storage/innobase/trx/trx0sys.c
index ce68f994d44..b87f3d5e090 100644
--- a/storage/innobase/trx/trx0sys.c
+++ b/storage/innobase/trx/trx0sys.c
@@ -105,17 +105,17 @@ trx_doublewrite_init(
trx_doublewrite->first_free = 0;
- trx_doublewrite->block1 = mach_read_from_4
- (doublewrite + TRX_SYS_DOUBLEWRITE_BLOCK1);
- trx_doublewrite->block2 = mach_read_from_4
- (doublewrite + TRX_SYS_DOUBLEWRITE_BLOCK2);
- trx_doublewrite->write_buf_unaligned = ut_malloc
- ((1 + 2 * TRX_SYS_DOUBLEWRITE_BLOCK_SIZE) * UNIV_PAGE_SIZE);
-
- trx_doublewrite->write_buf = ut_align
- (trx_doublewrite->write_buf_unaligned, UNIV_PAGE_SIZE);
- trx_doublewrite->buf_block_arr = mem_alloc
- (2 * TRX_SYS_DOUBLEWRITE_BLOCK_SIZE * sizeof(void*));
+ trx_doublewrite->block1 = mach_read_from_4(
+ doublewrite + TRX_SYS_DOUBLEWRITE_BLOCK1);
+ trx_doublewrite->block2 = mach_read_from_4(
+ doublewrite + TRX_SYS_DOUBLEWRITE_BLOCK2);
+ trx_doublewrite->write_buf_unaligned = ut_malloc(
+ (1 + 2 * TRX_SYS_DOUBLEWRITE_BLOCK_SIZE) * UNIV_PAGE_SIZE);
+
+ trx_doublewrite->write_buf = ut_align(
+ trx_doublewrite->write_buf_unaligned, UNIV_PAGE_SIZE);
+ trx_doublewrite->buf_block_arr = mem_alloc(
+ 2 * TRX_SYS_DOUBLEWRITE_BLOCK_SIZE * sizeof(void*));
}
/********************************************************************
@@ -438,8 +438,8 @@ trx_sys_doublewrite_init_or_restore_pages(
/* printf("Resetting space id in page %lu\n",
source_page_no); */
} else {
- space_id = mach_read_from_4
- (page + FIL_PAGE_ARCH_LOG_NO_OR_SPACE_ID);
+ space_id = mach_read_from_4(
+ page + FIL_PAGE_ARCH_LOG_NO_OR_SPACE_ID);
}
if (!restore_corrupt_pages) {
@@ -671,12 +671,12 @@ trx_sys_print_mysql_binlog_offset_from_page(
fprintf(stderr,
"ibbackup: Last MySQL binlog file position %lu %lu,"
" file name %s\n",
- (ulong) mach_read_from_4
- (sys_header + TRX_SYS_MYSQL_LOG_INFO
- + TRX_SYS_MYSQL_LOG_OFFSET_HIGH),
- (ulong) mach_read_from_4
- (sys_header + TRX_SYS_MYSQL_LOG_INFO
- + TRX_SYS_MYSQL_LOG_OFFSET_LOW),
+ (ulong) mach_read_from_4(
+ sys_header + TRX_SYS_MYSQL_LOG_INFO
+ + TRX_SYS_MYSQL_LOG_OFFSET_HIGH),
+ (ulong) mach_read_from_4(
+ sys_header + TRX_SYS_MYSQL_LOG_INFO
+ + TRX_SYS_MYSQL_LOG_OFFSET_LOW),
sys_header + TRX_SYS_MYSQL_LOG_INFO
+ TRX_SYS_MYSQL_LOG_NAME);
}
@@ -708,12 +708,12 @@ trx_sys_print_mysql_binlog_offset(void)
return;
}
- trx_sys_mysql_bin_log_pos_high = mach_read_from_4
- (sys_header + TRX_SYS_MYSQL_LOG_INFO
- + TRX_SYS_MYSQL_LOG_OFFSET_HIGH);
- trx_sys_mysql_bin_log_pos_low = mach_read_from_4
- (sys_header + TRX_SYS_MYSQL_LOG_INFO
- + TRX_SYS_MYSQL_LOG_OFFSET_LOW);
+ trx_sys_mysql_bin_log_pos_high = mach_read_from_4(
+ sys_header + TRX_SYS_MYSQL_LOG_INFO
+ + TRX_SYS_MYSQL_LOG_OFFSET_HIGH);
+ trx_sys_mysql_bin_log_pos_low = mach_read_from_4(
+ sys_header + TRX_SYS_MYSQL_LOG_INFO
+ + TRX_SYS_MYSQL_LOG_OFFSET_LOW);
trx_sys_mysql_bin_log_pos
= (((ib_longlong)trx_sys_mysql_bin_log_pos_high) << 32)
@@ -777,12 +777,12 @@ trx_sys_print_mysql_master_log_pos(void)
TRX_SYS_MYSQL_LOG_NAME_LEN);
trx_sys_mysql_master_log_pos
- = (((ib_longlong) mach_read_from_4
- (sys_header + TRX_SYS_MYSQL_MASTER_LOG_INFO
- + TRX_SYS_MYSQL_LOG_OFFSET_HIGH)) << 32)
- + ((ib_longlong) mach_read_from_4
- (sys_header + TRX_SYS_MYSQL_MASTER_LOG_INFO
- + TRX_SYS_MYSQL_LOG_OFFSET_LOW));
+ = (((ib_longlong) mach_read_from_4(
+ sys_header + TRX_SYS_MYSQL_MASTER_LOG_INFO
+ + TRX_SYS_MYSQL_LOG_OFFSET_HIGH)) << 32)
+ + ((ib_longlong) mach_read_from_4(
+ sys_header + TRX_SYS_MYSQL_MASTER_LOG_INFO
+ + TRX_SYS_MYSQL_LOG_OFFSET_LOW));
mtr_commit(&mtr);
}
@@ -847,12 +847,6 @@ trx_sysf_create(
mtr);
ut_a(buf_frame_get_page_no(page) == TRX_SYS_PAGE_NO);
- /* Reset the doublewrite buffer magic number to zero so that we
- know that the doublewrite buffer has not yet been created (this
- suppresses a Valgrind warning) */
-
- mach_write_to_4(page + TRX_SYS_DOUBLEWRITE + TRX_SYS_DOUBLEWRITE_MAGIC,
- 0);
#ifdef UNIV_SYNC_DEBUG
buf_page_dbg_add_level(page, SYNC_TRX_SYS_HEADER);
#endif /* UNIV_SYNC_DEBUG */
@@ -860,6 +854,13 @@ trx_sysf_create(
mlog_write_ulint(page + FIL_PAGE_TYPE, FIL_PAGE_TYPE_TRX_SYS,
MLOG_2BYTES, mtr);
+ /* Reset the doublewrite buffer magic number to zero so that we
+ know that the doublewrite buffer has not yet been created (this
+ suppresses a Valgrind warning) */
+
+ mlog_write_ulint(page + TRX_SYS_DOUBLEWRITE
+ + TRX_SYS_DOUBLEWRITE_MAGIC, 0, MLOG_4BYTES, mtr);
+
sys_header = trx_sysf_get(mtr);
/* Start counting transaction ids from number 1 up */
@@ -919,12 +920,12 @@ trx_sys_init_at_db_start(void)
to the disk-based header! Thus trx id values will not overlap when
the database is repeatedly started! */
- trx_sys->max_trx_id = ut_dulint_add
- (ut_dulint_align_up(mtr_read_dulint
- (sys_header
- + TRX_SYS_TRX_ID_STORE, &mtr),
- TRX_SYS_TRX_ID_WRITE_MARGIN),
- 2 * TRX_SYS_TRX_ID_WRITE_MARGIN);
+ trx_sys->max_trx_id = ut_dulint_add(
+ ut_dulint_align_up(mtr_read_dulint(
+ sys_header
+ + TRX_SYS_TRX_ID_STORE, &mtr),
+ TRX_SYS_TRX_ID_WRITE_MARGIN),
+ 2 * TRX_SYS_TRX_ID_WRITE_MARGIN);
UT_LIST_INIT(trx_sys->mysql_trx_list);
trx_lists_init_at_db_start();
@@ -935,8 +936,8 @@ trx_sys_init_at_db_start(void)
for (;;) {
if ( trx->conc_state != TRX_PREPARED) {
- rows_to_undo += ut_conv_dulint_to_longlong
- (trx->undo_no);
+ rows_to_undo += ut_conv_dulint_to_longlong(
+ trx->undo_no);
}
trx = UT_LIST_GET_NEXT(trx_list, trx);
diff --git a/storage/innobase/trx/trx0trx.c b/storage/innobase/trx/trx0trx.c
index 78b9e2446cb..4d0a26b5757 100644
--- a/storage/innobase/trx/trx0trx.c
+++ b/storage/innobase/trx/trx0trx.c
@@ -556,10 +556,10 @@ trx_lists_init_at_db_start(void)
"InnoDB: Transaction"
" %lu %lu was in the"
" XA prepared state.\n",
- ut_dulint_get_high
- (trx->id),
- ut_dulint_get_low
- (trx->id));
+ ut_dulint_get_high(
+ trx->id),
+ ut_dulint_get_low(
+ trx->id));
if (srv_force_recovery == 0) {
@@ -790,8 +790,8 @@ trx_commit_off_kernel(
because only a single OS thread is allowed to do the
transaction commit for this transaction. */
- update_hdr_page = trx_undo_set_state_at_finish
- (trx, undo, &mtr);
+ update_hdr_page = trx_undo_set_state_at_finish(
+ trx, undo, &mtr);
/* We have to do the cleanup for the update log while
holding the rseg mutex because update log headers
@@ -809,19 +809,19 @@ trx_commit_off_kernel(
if (trx->mysql_log_file_name
&& trx->mysql_log_file_name[0] != '\0') {
- trx_sys_update_mysql_binlog_offset
- (trx->mysql_log_file_name,
- trx->mysql_log_offset,
- TRX_SYS_MYSQL_LOG_INFO, &mtr);
+ trx_sys_update_mysql_binlog_offset(
+ trx->mysql_log_file_name,
+ trx->mysql_log_offset,
+ TRX_SYS_MYSQL_LOG_INFO, &mtr);
trx->mysql_log_file_name = NULL;
}
if (trx->mysql_master_log_file_name[0] != '\0') {
/* This database server is a MySQL replication slave */
- trx_sys_update_mysql_binlog_offset
- (trx->mysql_master_log_file_name,
- trx->mysql_master_log_pos,
- TRX_SYS_MYSQL_MASTER_LOG_INFO, &mtr);
+ trx_sys_update_mysql_binlog_offset(
+ trx->mysql_master_log_file_name,
+ trx->mysql_master_log_pos,
+ TRX_SYS_MYSQL_MASTER_LOG_INFO, &mtr);
}
/* The following call commits the mini-transaction, making the
@@ -1010,8 +1010,8 @@ trx_assign_read_view(
mutex_enter(&kernel_mutex);
if (!trx->read_view) {
- trx->read_view = read_view_open_now
- (trx->id, trx->global_read_view_heap);
+ trx->read_view = read_view_open_now(
+ trx->id, trx->global_read_view_heap);
trx->global_read_view = trx->read_view;
}
@@ -1835,8 +1835,8 @@ trx_prepare_off_kernel(
}
if (trx->update_undo) {
- update_hdr_page = trx_undo_set_state_at_prepare
- (trx, trx->update_undo, &mtr);
+ update_hdr_page = trx_undo_set_state_at_prepare(
+ trx, trx->update_undo, &mtr);
}
mutex_exit(&(rseg->mutex));
@@ -1983,8 +1983,8 @@ trx_recover_for_mysql(
fprintf(stderr,
" InnoDB: Transaction contains changes"
" to %lu rows\n",
- (ulong) ut_conv_dulint_to_longlong
- (trx->undo_no));
+ (ulong) ut_conv_dulint_to_longlong(
+ trx->undo_no));
count++;
diff --git a/storage/innobase/trx/trx0undo.c b/storage/innobase/trx/trx0undo.c
index db33c515c34..fbcfab38f01 100644
--- a/storage/innobase/trx/trx0undo.c
+++ b/storage/innobase/trx/trx0undo.c
@@ -153,8 +153,8 @@ trx_undo_get_prev_rec_from_prev_page(
return(NULL);
}
- prev_page = trx_undo_page_get_s_latched
- (buf_frame_get_space_id(undo_page), prev_page_no, mtr);
+ prev_page = trx_undo_page_get_s_latched(
+ buf_frame_get_space_id(undo_page), prev_page_no, mtr);
return(trx_undo_page_get_last_rec(prev_page, page_no, offset));
}
@@ -1041,8 +1041,8 @@ trx_undo_truncate_end(
goto function_exit;
}
- trx_undo_free_page_in_rollback
- (trx, undo, last_page_no, &mtr);
+ trx_undo_free_page_in_rollback(
+ trx, undo, last_page_no, &mtr);
break;
}
@@ -1261,8 +1261,8 @@ trx_undo_mem_create_at_db_start(
page_no, offset);
mutex_exit(&(rseg->mutex));
- undo->dict_operation = mtr_read_ulint
- (undo_header + TRX_UNDO_DICT_TRANS, MLOG_1BYTE, mtr);
+ undo->dict_operation = mtr_read_ulint(
+ undo_header + TRX_UNDO_DICT_TRANS, MLOG_1BYTE, mtr);
undo->table_id = mtr_read_dulint(undo_header + TRX_UNDO_TABLE_ID, mtr);
undo->state = state;
@@ -1601,8 +1601,8 @@ trx_undo_reuse_cached(
offset = trx_undo_insert_header_reuse(undo_page, trx_id, mtr);
if (trx->support_xa) {
- trx_undo_header_add_space_for_xid
- (undo_page, undo_page + offset, mtr);
+ trx_undo_header_add_space_for_xid(
+ undo_page, undo_page + offset, mtr);
}
} else {
ut_a(mach_read_from_2(undo_page + TRX_UNDO_PAGE_HDR
@@ -1612,8 +1612,8 @@ trx_undo_reuse_cached(
offset = trx_undo_header_create(undo_page, trx_id, mtr);
if (trx->support_xa) {
- trx_undo_header_add_space_for_xid
- (undo_page, undo_page + offset, mtr);
+ trx_undo_header_add_space_for_xid(
+ undo_page, undo_page + offset, mtr);
}
}
diff --git a/storage/myisam/ha_myisam.cc b/storage/myisam/ha_myisam.cc
index 39cbc20fd4b..03065b43dd5 100644
--- a/storage/myisam/ha_myisam.cc
+++ b/storage/myisam/ha_myisam.cc
@@ -48,9 +48,11 @@ TYPELIB myisam_stats_method_typelib= {
** MyISAM tables
*****************************************************************************/
-static handler *myisam_create_handler(TABLE_SHARE *table, MEM_ROOT *mem_root)
+static handler *myisam_create_handler(handlerton *hton,
+ TABLE_SHARE *table,
+ MEM_ROOT *mem_root)
{
- return new (mem_root) ha_myisam(table);
+ return new (mem_root) ha_myisam(hton, table);
}
// collect errors printed by mi_check routines
@@ -133,8 +135,8 @@ void mi_check_print_warning(MI_CHECK *param, const char *fmt,...)
}
-ha_myisam::ha_myisam(TABLE_SHARE *table_arg)
- :handler(myisam_hton, table_arg), file(0),
+ha_myisam::ha_myisam(handlerton *hton, TABLE_SHARE *table_arg)
+ :handler(hton, table_arg), file(0),
int_table_flags(HA_NULL_IN_KEY | HA_CAN_FULLTEXT | HA_CAN_SQL_HANDLER |
HA_DUPLICATE_POS | HA_CAN_INDEX_BLOBS | HA_AUTO_PART_KEY |
HA_FILE_BASED | HA_CAN_GEOMETRY | HA_NO_TRANSACTIONS |
@@ -1787,21 +1789,27 @@ bool ha_myisam::check_if_incompatible_data(HA_CREATE_INFO *info,
return COMPATIBLE_DATA_YES;
}
-handlerton *myisam_hton;
+extern int mi_panic(enum ha_panic_function flag);
+int myisam_panic(handlerton *hton, ha_panic_function flag)
+{
+ return mi_panic(flag);
+}
static int myisam_init(void *p)
{
+ handlerton *myisam_hton;
+
myisam_hton= (handlerton *)p;
- myisam_hton->state=SHOW_OPTION_YES;
- myisam_hton->db_type=DB_TYPE_MYISAM;
- myisam_hton->create=myisam_create_handler;
- myisam_hton->panic=mi_panic;
+ myisam_hton->state= SHOW_OPTION_YES;
+ myisam_hton->db_type= DB_TYPE_MYISAM;
+ myisam_hton->create= myisam_create_handler;
+ myisam_hton->panic= myisam_panic;
myisam_hton->flags= HTON_CAN_RECREATE | HTON_SUPPORT_LOG_TABLES;
return 0;
}
struct st_mysql_storage_engine myisam_storage_engine=
-{ MYSQL_HANDLERTON_INTERFACE_VERSION, myisam_hton };
+{ MYSQL_HANDLERTON_INTERFACE_VERSION };
mysql_declare_plugin(myisam)
{
@@ -1810,6 +1818,7 @@ mysql_declare_plugin(myisam)
"MyISAM",
"MySQL AB",
"Default engine as of MySQL 3.23 with great performance",
+ PLUGIN_LICENSE_GPL,
myisam_init, /* Plugin Init */
NULL, /* Plugin Deinit */
0x0100, /* 1.0 */
diff --git a/storage/myisam/ha_myisam.h b/storage/myisam/ha_myisam.h
index 511b796ebdb..85abcdca8b2 100644
--- a/storage/myisam/ha_myisam.h
+++ b/storage/myisam/ha_myisam.h
@@ -43,7 +43,7 @@ class ha_myisam: public handler
int repair(THD *thd, MI_CHECK &param, bool optimize);
public:
- ha_myisam(TABLE_SHARE *table_arg);
+ ha_myisam(handlerton *hton, TABLE_SHARE *table_arg);
~ha_myisam() {}
handler *clone(MEM_ROOT *mem_root);
const char *table_type() const { return "MyISAM"; }
diff --git a/storage/myisam/mi_check.c b/storage/myisam/mi_check.c
index 91c04866b5a..a7685bf653d 100644
--- a/storage/myisam/mi_check.c
+++ b/storage/myisam/mi_check.c
@@ -1370,7 +1370,8 @@ int mi_repair(MI_CHECK *param, register MI_INFO *info,
param->temp_filename);
goto err;
}
- if (filecopy(param,new_file,info->dfile,0L,new_header_length,
+ if (new_header_length &&
+ filecopy(param,new_file,info->dfile,0L,new_header_length,
"datafile-header"))
goto err;
info->s->state.dellink= HA_OFFSET_ERROR;
@@ -2072,7 +2073,8 @@ int mi_repair_by_sort(MI_CHECK *param, register MI_INFO *info,
param->temp_filename);
goto err;
}
- if (filecopy(param, new_file,info->dfile,0L,new_header_length,
+ if (new_header_length &&
+ filecopy(param, new_file,info->dfile,0L,new_header_length,
"datafile-header"))
goto err;
if (param->testflag & T_UNPACK)
@@ -2466,7 +2468,8 @@ int mi_repair_parallel(MI_CHECK *param, register MI_INFO *info,
param->temp_filename);
goto err;
}
- if (filecopy(param, new_file,info->dfile,0L,new_header_length,
+ if (new_header_length &&
+ filecopy(param, new_file,info->dfile,0L,new_header_length,
"datafile-header"))
goto err;
if (param->testflag & T_UNPACK)
diff --git a/storage/myisam/mi_delete.c b/storage/myisam/mi_delete.c
index 2bc99d65dd2..85cc60bdd9d 100644
--- a/storage/myisam/mi_delete.c
+++ b/storage/myisam/mi_delete.c
@@ -446,7 +446,7 @@ static int del(register MI_INFO *info, register MI_KEYDEF *keyinfo, uchar *key,
else
{
DBUG_PRINT("test",("Inserting of key when deleting"));
- if (_mi_get_last_key(info,keyinfo,leaf_buff,keybuff,endpos,
+ if (!_mi_get_last_key(info,keyinfo,leaf_buff,keybuff,endpos,
&tmp))
goto err;
ret_value=_mi_insert(info,keyinfo,key,leaf_buff,endpos,keybuff,
diff --git a/storage/myisam/mi_locking.c b/storage/myisam/mi_locking.c
index 18b87281f26..a8e2de5ea5a 100644
--- a/storage/myisam/mi_locking.c
+++ b/storage/myisam/mi_locking.c
@@ -236,16 +236,20 @@ int mi_lock_database(MI_INFO *info, int lock_type)
default:
break; /* Impossible */
}
- }
+ }
#ifdef __WIN__
else
{
/*
- The file has been closed and kfile is -1.
- See mi_extra.c about implementation of
- HA_EXTRA_PREPARE_FOR_DELETE.
- */
- error=HA_ERR_NO_SUCH_TABLE;
+ Check for bad file descriptors if this table is part
+ of a merge union. Failing to capture this may cause
+ a crash on windows if the table is renamed and
+ later on referenced by the merge table.
+ */
+ if( info->owned_by_merge && (info->s)->kfile < 0 )
+ {
+ error = HA_ERR_NO_SUCH_TABLE;
+ }
}
#endif
pthread_mutex_unlock(&share->intern_lock);
diff --git a/storage/myisam/myisam_ftdump.c b/storage/myisam/myisam_ftdump.c
index 209ef49c8db..46d0ffd13a5 100644
--- a/storage/myisam/myisam_ftdump.c
+++ b/storage/myisam/myisam_ftdump.c
@@ -127,7 +127,6 @@ int main(int argc,char *argv[])
if (count || stats)
{
- doc_cnt++;
if (strcmp(buf, buf2))
{
if (*buf2)
@@ -152,6 +151,7 @@ int main(int argc,char *argv[])
keylen2=keylen;
doc_cnt=0;
}
+ doc_cnt+= (subkeys >= 0 ? 1 : -subkeys);
}
if (dump)
{
@@ -167,7 +167,6 @@ int main(int argc,char *argv[])
if (count || stats)
{
- doc_cnt++;
if (*buf2)
{
uniq++;
diff --git a/storage/myisam/myisamdef.h b/storage/myisam/myisamdef.h
index 765e26dc74d..fa83cbf0524 100644
--- a/storage/myisam/myisamdef.h
+++ b/storage/myisam/myisamdef.h
@@ -291,6 +291,9 @@ struct st_myisam_info {
my_bool page_changed; /* If info->buff can't be used for rnext */
my_bool buff_used; /* If info->buff has to be reread for rnext */
my_bool once_flags; /* For MYISAMMRG */
+#ifdef __WIN__
+ my_bool owned_by_merge; /* This MyISAM table is part of a merge union */
+#endif
#ifdef THREAD
THR_LOCK_DATA lock;
#endif
diff --git a/storage/myisammrg/ha_myisammrg.cc b/storage/myisammrg/ha_myisammrg.cc
index 6ed07df1012..5c8a05f0dde 100644
--- a/storage/myisammrg/ha_myisammrg.cc
+++ b/storage/myisammrg/ha_myisammrg.cc
@@ -34,19 +34,16 @@
static handler *myisammrg_create_handler(TABLE_SHARE *table,
MEM_ROOT *mem_root);
-/* MyISAM MERGE handlerton */
-
-handlerton *myisammrg_hton;
-
-static handler *myisammrg_create_handler(TABLE_SHARE *table,
+static handler *myisammrg_create_handler(handlerton *hton,
+ TABLE_SHARE *table,
MEM_ROOT *mem_root)
{
- return new (mem_root) ha_myisammrg(table);
+ return new (mem_root) ha_myisammrg(hton, table);
}
-ha_myisammrg::ha_myisammrg(TABLE_SHARE *table_arg)
- :handler(myisammrg_hton, table_arg), file(0)
+ha_myisammrg::ha_myisammrg(handlerton *hton, TABLE_SHARE *table_arg)
+ :handler(hton, table_arg), file(0)
{}
static const char *ha_myisammrg_exts[] = {
@@ -315,9 +312,22 @@ void ha_myisammrg::info(uint flag)
if (flag & HA_STATUS_CONST)
{
if (table->s->key_parts && info.rec_per_key)
+ {
+#ifdef HAVE_purify
+ /*
+ valgrind may be unhappy about it, because optimizer may access values
+ between file->keys and table->key_parts, that will be uninitialized.
+ It's safe though, because even if opimizer will decide to use a key
+ with such a number, it'll be an error later anyway.
+ */
+ bzero((char*) table->key_info[0].rec_per_key,
+ sizeof(table->key_info[0].rec_per_key) * table->s->key_parts);
+#endif
memcpy((char*) table->key_info[0].rec_per_key,
(char*) info.rec_per_key,
- sizeof(table->key_info[0].rec_per_key)*table->s->key_parts);
+ sizeof(table->key_info[0].rec_per_key) *
+ min(file->keys, table->s->key_parts));
+ }
}
}
@@ -554,21 +564,29 @@ bool ha_myisammrg::check_if_incompatible_data(HA_CREATE_INFO *info,
return COMPATIBLE_DATA_NO;
}
+extern int myrg_panic(enum ha_panic_function flag);
+int myisammrg_panic(handlerton *hton, ha_panic_function flag)
+{
+ return myrg_panic(flag);
+}
+
static int myisammrg_init(void *p)
{
+ handlerton *myisammrg_hton;
+
myisammrg_hton= (handlerton *)p;
- myisammrg_hton->state=have_merge_db;
- myisammrg_hton->db_type=DB_TYPE_MRG_MYISAM;
- myisammrg_hton->create=myisammrg_create_handler;
- myisammrg_hton->panic=myrg_panic;
- myisammrg_hton->flags= HTON_CAN_RECREATE;
+ myisammrg_hton->state= have_merge_db;
+ myisammrg_hton->db_type= DB_TYPE_MRG_MYISAM;
+ myisammrg_hton->create= myisammrg_create_handler;
+ myisammrg_hton->panic= myisammrg_panic;
+ myisammrg_hton->flags= HTON_CAN_RECREATE|HTON_NO_PARTITION;
return 0;
}
struct st_mysql_storage_engine myisammrg_storage_engine=
-{ MYSQL_HANDLERTON_INTERFACE_VERSION, myisammrg_hton };
+{ MYSQL_HANDLERTON_INTERFACE_VERSION };
mysql_declare_plugin(myisammrg)
{
@@ -577,6 +595,7 @@ mysql_declare_plugin(myisammrg)
"MRG_MYISAM",
"MySQL AB",
"Collection of identical MyISAM tables",
+ PLUGIN_LICENSE_GPL,
myisammrg_init, /* Plugin Init */
NULL, /* Plugin Deinit */
0x0100, /* 1.0 */
diff --git a/storage/myisammrg/ha_myisammrg.h b/storage/myisammrg/ha_myisammrg.h
index d58a3523c26..faa3ae73c59 100644
--- a/storage/myisammrg/ha_myisammrg.h
+++ b/storage/myisammrg/ha_myisammrg.h
@@ -28,7 +28,7 @@ class ha_myisammrg: public handler
MYRG_INFO *file;
public:
- ha_myisammrg(TABLE_SHARE *table_arg);
+ ha_myisammrg(handlerton *hton, TABLE_SHARE *table_arg);
~ha_myisammrg() {}
const char *table_type() const { return "MRG_MyISAM"; }
const char **bas_ext() const;
diff --git a/storage/myisammrg/myrg_locking.c b/storage/myisammrg/myrg_locking.c
index e5a8d3f3d9d..98e8305b9ce 100644
--- a/storage/myisammrg/myrg_locking.c
+++ b/storage/myisammrg/myrg_locking.c
@@ -26,8 +26,19 @@ int myrg_lock_database(MYRG_INFO *info, int lock_type)
MYRG_TABLE *file;
error=0;
- for (file=info->open_tables ; file != info->end_table ; file++)
+ for (file=info->open_tables ; file != info->end_table ; file++)
+ {
+#ifdef __WIN__
+ /*
+ Make sure this table is marked as owned by a merge table.
+ The semaphore is never released as long as table remains
+ in memory. This should be refactored into a more generic
+ approach (observer pattern)
+ */
+ (file->table)->owned_by_merge = TRUE;
+#endif
if ((new_error=mi_lock_database(file->table,lock_type)))
error=new_error;
+ }
return(error);
}
diff --git a/storage/myisammrg/myrg_open.c b/storage/myisammrg/myrg_open.c
index cf82f13da57..dafb3246cbf 100644
--- a/storage/myisammrg/myrg_open.c
+++ b/storage/myisammrg/myrg_open.c
@@ -33,7 +33,7 @@
MYRG_INFO *myrg_open(const char *name, int mode, int handle_locking)
{
int save_errno,errpos=0;
- uint files=0,i,dir_length,length,key_parts;
+ uint files= 0, i, dir_length, length, key_parts, min_keys= 0;
ulonglong file_offset=0;
char name_buff[FN_REFLEN*2],buff[FN_REFLEN],*end;
MYRG_INFO *m_info=0;
@@ -90,7 +90,10 @@ MYRG_INFO *myrg_open(const char *name, int mode, int handle_locking)
else
fn_format(buff, buff, "", "", 0);
if (!(isam=mi_open(buff,mode,(handle_locking?HA_OPEN_WAIT_IF_LOCKED:0))))
+ {
+ my_errno= HA_ERR_WRONG_MRG_TABLE_DEF;
goto err;
+ }
if (!m_info) /* First file */
{
key_parts=isam->s->base.key_parts;
@@ -107,6 +110,7 @@ MYRG_INFO *myrg_open(const char *name, int mode, int handle_locking)
files= 0;
}
m_info->reclength=isam->s->base.reclength;
+ min_keys= isam->s->base.keys;
errpos=3;
}
m_info->open_tables[files].table= isam;
@@ -122,6 +126,8 @@ MYRG_INFO *myrg_open(const char *name, int mode, int handle_locking)
m_info->records+= isam->state->records;
m_info->del+= isam->state->del;
m_info->data_file_length+= isam->state->data_file_length;
+ if (min_keys > isam->s->base.keys)
+ min_keys= isam->s->base.keys;
for (i=0; i < key_parts; i++)
m_info->rec_per_key_part[i]+= (isam->s->state.rec_per_key_part[i] /
m_info->tables);
@@ -139,7 +145,7 @@ MYRG_INFO *myrg_open(const char *name, int mode, int handle_locking)
my_errno=HA_ERR_RECORD_FILE_FULL;
goto err;
}
- m_info->keys= files ? isam->s->base.keys : 0;
+ m_info->keys= min_keys;
bzero((char*) &m_info->by_key,sizeof(m_info->by_key));
/* this works ok if the table list is empty */
diff --git a/storage/myisammrg/myrg_queue.c b/storage/myisammrg/myrg_queue.c
index 2e600a526c0..74fdddc7748 100644
--- a/storage/myisammrg/myrg_queue.c
+++ b/storage/myisammrg/myrg_queue.c
@@ -65,6 +65,8 @@ int _myrg_init_queue(MYRG_INFO *info,int inx,enum ha_rkey_function search_flag)
error=my_errno;
}
}
+ else
+ my_errno= error= HA_ERR_WRONG_INDEX;
return error;
}
diff --git a/storage/ndb/include/kernel/GlobalSignalNumbers.h b/storage/ndb/include/kernel/GlobalSignalNumbers.h
index 4b2c69e4bc6..b449915d756 100644
--- a/storage/ndb/include/kernel/GlobalSignalNumbers.h
+++ b/storage/ndb/include/kernel/GlobalSignalNumbers.h
@@ -127,6 +127,7 @@ extern const GlobalSignalNumber NO_OF_SIGNAL_NAMES;
/* 68 not unused */
/* 69 not unused */
/* 70 unused */
+#define GSN_UPDATE_FRAG_DIST_KEY_ORD 70
#define GSN_ACC_ABORTREQ 71
#define GSN_ACC_CHECK_SCAN 72
#define GSN_ACC_COMMITCONF 73
diff --git a/storage/ndb/include/kernel/signaldata/CmRegSignalData.hpp b/storage/ndb/include/kernel/signaldata/CmRegSignalData.hpp
index ab51ed17bc3..e076534da9e 100644
--- a/storage/ndb/include/kernel/signaldata/CmRegSignalData.hpp
+++ b/storage/ndb/include/kernel/signaldata/CmRegSignalData.hpp
@@ -90,7 +90,11 @@ public:
ZNOT_PRESIDENT = 5, /* We are not president */
ZNOT_DEAD = 6, /* We are not dead when we are starting */
ZINCOMPATIBLE_VERSION = 7,
- ZINCOMPATIBLE_START_TYPE = 8
+ ZINCOMPATIBLE_START_TYPE = 8,
+ ZSINGLE_USER_MODE = 9, /* The cluster is in single user mode,
+ * data node is not allowed to get added
+ * in the cluster while in single user mode */
+ ZGENERIC = 100 /* The generic error code */
};
private:
diff --git a/storage/ndb/include/kernel/signaldata/CopyFrag.hpp b/storage/ndb/include/kernel/signaldata/CopyFrag.hpp
index c92859fdcce..bc308c32935 100644
--- a/storage/ndb/include/kernel/signaldata/CopyFrag.hpp
+++ b/storage/ndb/include/kernel/signaldata/CopyFrag.hpp
@@ -30,7 +30,7 @@ class CopyFragReq {
*/
friend class Dblqh;
public:
- STATIC_CONST( SignalLength = 8 );
+ STATIC_CONST( SignalLength = 9 );
private:
Uint32 userPtr;
@@ -41,6 +41,8 @@ private:
Uint32 schemaVersion;
Uint32 distributionKey;
Uint32 gci;
+ Uint32 nodeCount;
+ Uint32 nodeList[1];
};
class CopyFragConf {
@@ -85,4 +87,13 @@ private:
Uint32 errorCode;
};
+struct UpdateFragDistKeyOrd
+{
+ Uint32 tableId;
+ Uint32 fragId;
+ Uint32 fragDistributionKey;
+
+ STATIC_CONST( SignalLength = 3 );
+};
+
#endif
diff --git a/storage/ndb/include/mgmapi/mgmapi.h b/storage/ndb/include/mgmapi/mgmapi.h
index 0785a5dba99..b6b87ebaaa9 100644
--- a/storage/ndb/include/mgmapi/mgmapi.h
+++ b/storage/ndb/include/mgmapi/mgmapi.h
@@ -230,7 +230,9 @@ extern "C" {
NDB_MGM_SERVER_NOT_CONNECTED = 1010,
/** Could not connect to socker */
NDB_MGM_COULD_NOT_CONNECT_TO_SOCKET = 1011,
-
+ /** Could not bind local address */
+ NDB_MGM_BIND_ADDRESS = 1012,
+
/* Alloc node id failures */
/** Generic error, retry may succeed */
NDB_MGM_ALLOCID_ERROR = 1101,
@@ -515,6 +517,15 @@ extern "C" {
const char *ndb_mgm_get_connectstring(NdbMgmHandle handle, char *buf, int buf_sz);
/**
+ * Set local bindaddress
+ * @param arg - Srting of form "host[:port]"
+ * @note must be called before connect
+ * @note Error on binding local address will not be reported until connect
+ * @return 0 on success
+ */
+ int ndb_mgm_set_bindaddress(NdbMgmHandle, const char * arg);
+
+ /**
* Gets the connectstring used for a connection
*
* @note This function returns the default connectstring if no call to
@@ -861,6 +872,15 @@ extern "C" {
enum ndb_mgm_event_category category,
int level,
struct ndb_mgm_reply* reply);
+ /**
+ * get log category and levels
+ *
+ * @param handle NDB management handle.
+ * @return A vector of twelve elements,
+ * where each element contains
+ * loglevel of corresponding category
+ */
+ const unsigned int *ndb_mgm_get_clusterlog_loglevel(NdbMgmHandle handle);
/** @} *********************************************************************/
/**
@@ -1061,6 +1081,19 @@ extern "C" {
int ndb_mgm_end_session(NdbMgmHandle handle);
/**
+ * ndb_mgm_get_fd
+ *
+ * get the file descriptor of the handle.
+ * INTERNAL ONLY.
+ * USE FOR TESTING. OTHER USES ARE NOT A GOOD IDEA.
+ *
+ * @param handle NDB management handle
+ * @return handle->socket
+ *
+ */
+ int ndb_mgm_get_fd(NdbMgmHandle handle);
+
+ /**
* Get the node id of the mgm server we're connected to
*/
Uint32 ndb_mgm_get_mgmd_nodeid(NdbMgmHandle handle);
@@ -1130,6 +1163,11 @@ extern "C" {
enum ndb_mgm_event_category c,
int l, struct ndb_mgm_reply* r)
{ return ndb_mgm_set_clusterlog_loglevel(h,n,c,l,r); }
+
+ inline
+ const unsigned int *ndb_mgm_get_loglevel_clusterlog(NdbMgmHandle h)
+ { return ndb_mgm_get_clusterlog_loglevel(h); }
+
#endif
#ifdef __cplusplus
diff --git a/storage/ndb/include/mgmapi/mgmapi_debug.h b/storage/ndb/include/mgmapi/mgmapi_debug.h
index 942e132d3b4..073d5f015ae 100644
--- a/storage/ndb/include/mgmapi/mgmapi_debug.h
+++ b/storage/ndb/include/mgmapi/mgmapi_debug.h
@@ -132,6 +132,20 @@ extern "C" {
const char * value,
struct ndb_mgm_reply* reply);
+ Uint64 ndb_mgm_get_session_id(NdbMgmHandle handle);
+
+ struct NdbMgmSession {
+ Uint64 id;
+ Uint32 m_stopSelf;
+ Uint32 m_stop;
+ Uint32 nodeid;
+ Uint32 parser_buffer_len;
+ Uint32 parser_status;
+ };
+
+ int ndb_mgm_get_session(NdbMgmHandle handle, Uint64 id,
+ struct NdbMgmSession *s, int *len);
+
#ifdef __cplusplus
}
#endif
diff --git a/storage/ndb/include/mgmapi/ndbd_exit_codes.h b/storage/ndb/include/mgmapi/ndbd_exit_codes.h
index 79df36e7955..1b662c9d270 100644
--- a/storage/ndb/include/mgmapi/ndbd_exit_codes.h
+++ b/storage/ndb/include/mgmapi/ndbd_exit_codes.h
@@ -65,6 +65,7 @@ typedef ndbd_exit_status_enum ndbd_exit_status;
typedef ndbd_exit_classification_enum ndbd_exit_classification;
/* Errorcodes before block division was used */
+#define NDBD_EXIT_GENERIC 2300
#define NDBD_EXIT_PRGERR 2301
#define NDBD_EXIT_NODE_NOT_IN_CONFIG 2302
#define NDBD_EXIT_SYSTEM_ERROR 2303
@@ -79,6 +80,7 @@ typedef ndbd_exit_classification_enum ndbd_exit_classification;
#define NDBD_EXIT_NO_MORE_UNDOLOG 2312
#define NDBD_EXIT_SR_UNDOLOG 2313
#define NDBD_EXIT_SR_SCHEMAFILE 2310
+#define NDBD_EXIT_SINGLE_USER_MODE 2314
#define NDBD_EXIT_MEMALLOC 2327
#define NDBD_EXIT_BLOCK_JBUFCONGESTION 2334
#define NDBD_EXIT_TIME_QUEUE_SHORT 2335
diff --git a/storage/ndb/include/mgmcommon/ConfigRetriever.hpp b/storage/ndb/include/mgmcommon/ConfigRetriever.hpp
index 1b4ecd56f80..89a1eb976c8 100644
--- a/storage/ndb/include/mgmcommon/ConfigRetriever.hpp
+++ b/storage/ndb/include/mgmcommon/ConfigRetriever.hpp
@@ -28,7 +28,8 @@
class ConfigRetriever {
public:
ConfigRetriever(const char * _connect_string,
- Uint32 version, Uint32 nodeType);
+ Uint32 version, Uint32 nodeType,
+ const char * _bind_address = 0);
~ConfigRetriever();
int do_connect(int no_retries, int retry_delay_in_seconds, int verbose);
diff --git a/storage/ndb/include/ndb_version.h.in b/storage/ndb/include/ndb_version.h.in
index ef35fa4093b..6a1b1f5292c 100644
--- a/storage/ndb/include/ndb_version.h.in
+++ b/storage/ndb/include/ndb_version.h.in
@@ -67,5 +67,9 @@ char ndb_version_string_buf[NDB_VERSION_STRING_BUF_SZ];
#define NDBD_DICT_LOCK_VERSION_5 MAKE_VERSION(5,0,23)
#define NDBD_DICT_LOCK_VERSION_5_1 MAKE_VERSION(5,1,12)
+#define NDBD_UPDATE_FRAG_DIST_KEY_50 MAKE_VERSION(5,0,26)
+#define NDBD_UPDATE_FRAG_DIST_KEY_51 MAKE_VERSION(5,1,12)
+
+#define NDBD_QMGR_SINGLEUSER_VERSION_5 MAKE_VERSION(5,0,25)
#endif
diff --git a/storage/ndb/include/ndbapi/NdbDictionary.hpp b/storage/ndb/include/ndbapi/NdbDictionary.hpp
index 9e73bc00712..8d9ade2fb84 100644
--- a/storage/ndb/include/ndbapi/NdbDictionary.hpp
+++ b/storage/ndb/include/ndbapi/NdbDictionary.hpp
@@ -920,8 +920,49 @@ public:
bool getTemporary();
void setTemporary(bool);
+
+ /**
+ * Check if any of column in bitmaps are disk columns
+ * returns bitmap of different columns
+ * bit 0 = atleast 1 pk column is set
+ * bit 1 = atleast 1 disk column set
+ * bit 2 = atleast 1 non disk column set
+ * passing NULL pointer will equal to bitmap with all columns set
+ */
+ int checkColumns(const Uint32* bitmap, unsigned len_in_bytes) const;
#endif
+ // these 2 are not de-doxygenated
+
+ /**
+ * This method is not needed in normal usage.
+ *
+ * Compute aggregate data on table being defined. Required for
+ * aggregate methods such as getNoOfPrimaryKeys() to work before
+ * table has been created and retrieved via getTable().
+ *
+ * May adjust some column flags. If no PK is so far marked as
+ * distribution key then all PK's will be marked.
+ *
+ * Returns 0 on success. Returns -1 and sets error if an
+ * inconsistency is detected.
+ */
+ int aggregate(struct NdbError& error);
+
+ /**
+ * This method is not needed in normal usage.
+ *
+ * Validate new table definition before create. Does aggregate()
+ * and additional checks. There may still be errors which are
+ * detected only by NDB kernel at create table.
+ *
+ * Create table and retrieve table do validate() automatically.
+ *
+ * Returns 0 on success. Returns -1 and sets error if an
+ * inconsistency is detected.
+ */
+ int validate(struct NdbError& error);
+
private:
#ifndef DOXYGEN_SHOULD_SKIP_INTERNAL
friend class Ndb;
diff --git a/storage/ndb/include/ndbapi/NdbScanOperation.hpp b/storage/ndb/include/ndbapi/NdbScanOperation.hpp
index 34f62defa66..209cd7e29b8 100644
--- a/storage/ndb/include/ndbapi/NdbScanOperation.hpp
+++ b/storage/ndb/include/ndbapi/NdbScanOperation.hpp
@@ -42,7 +42,8 @@ public:
* readTuples.
*/
enum ScanFlag {
- SF_TupScan = (1 << 16), // scan TUP
+ SF_TupScan = (1 << 16), // scan TUP order
+ SF_DiskScan = (2 << 16), // scan in DISK order
SF_OrderBy = (1 << 24), // index scan in order
SF_Descending = (2 << 24), // index scan in descending order
SF_ReadRangeNo = (4 << 24), // enable @ref get_range_no
diff --git a/storage/ndb/include/ndbapi/NdbTransaction.hpp b/storage/ndb/include/ndbapi/NdbTransaction.hpp
index b3fb07d2905..8d367f1620a 100644
--- a/storage/ndb/include/ndbapi/NdbTransaction.hpp
+++ b/storage/ndb/include/ndbapi/NdbTransaction.hpp
@@ -658,8 +658,11 @@ private:
// Release all cursor operations in connection
void releaseOps(NdbOperation*);
void releaseScanOperations(NdbIndexScanOperation*);
- void releaseScanOperation(NdbIndexScanOperation*);
-
+ bool releaseScanOperation(NdbIndexScanOperation** listhead,
+ NdbIndexScanOperation** listtail,
+ NdbIndexScanOperation* op);
+ void releaseExecutedScanOperation(NdbIndexScanOperation*);
+
// Set the transaction identity of the transaction
void setTransactionId(Uint64 aTransactionId);
diff --git a/storage/ndb/include/util/File.hpp b/storage/ndb/include/util/File.hpp
index 53ea88e0f52..fc71394c8c5 100644
--- a/storage/ndb/include/util/File.hpp
+++ b/storage/ndb/include/util/File.hpp
@@ -29,6 +29,14 @@ class File_class
{
public:
/**
+ * Returns time for last contents modification of a file.
+ *
+ * @param aFileName a filename to check.
+ * @return the time for last contents modificaton of the file.
+ */
+ static time_t mtime(const char* aFileName);
+
+ /**
* Returns true if the file exist.
*
* @param aFileName a filename to check.
diff --git a/storage/ndb/include/util/InputStream.hpp b/storage/ndb/include/util/InputStream.hpp
index 10e22a70e42..4238b492917 100644
--- a/storage/ndb/include/util/InputStream.hpp
+++ b/storage/ndb/include/util/InputStream.hpp
@@ -19,14 +19,22 @@
#include <ndb_global.h>
#include <NdbTCP.h>
+#include <NdbMutex.h>
/**
* Input stream
*/
class InputStream {
public:
- virtual ~InputStream() {}
+ InputStream() { m_mutex= NULL; };
+ virtual ~InputStream() {};
virtual char* gets(char * buf, int bufLen) = 0;
+ /**
+ * Set the mutex to be UNLOCKED when blocking (e.g. select(2))
+ */
+ void set_mutex(NdbMutex *m) { m_mutex= m; };
+protected:
+ NdbMutex *m_mutex;
};
class FileInputStream : public InputStream {
@@ -42,6 +50,7 @@ extern FileInputStream Stdin;
class SocketInputStream : public InputStream {
NDB_SOCKET_TYPE m_socket;
unsigned m_timeout;
+ bool m_startover;
public:
SocketInputStream(NDB_SOCKET_TYPE socket, unsigned readTimeout = 1000);
virtual ~SocketInputStream() {}
diff --git a/storage/ndb/include/util/Parser.hpp b/storage/ndb/include/util/Parser.hpp
index 3baf7601a6c..5785961c293 100644
--- a/storage/ndb/include/util/Parser.hpp
+++ b/storage/ndb/include/util/Parser.hpp
@@ -61,12 +61,15 @@ public:
/**
* Context for parse
*/
- struct Context {
+ class Context {
+ public:
+ Context() { m_mutex= NULL; };
ParserStatus m_status;
const ParserRow<T> * m_currentCmd;
const ParserRow<T> * m_currentArg;
char * m_currentToken;
char m_tokenBuffer[512];
+ NdbMutex *m_mutex;
Vector<const ParserRow<T> *> m_aliasUsed;
};
diff --git a/storage/ndb/include/util/SocketClient.hpp b/storage/ndb/include/util/SocketClient.hpp
index bf1ad7d45d6..422560c8a78 100644
--- a/storage/ndb/include/util/SocketClient.hpp
+++ b/storage/ndb/include/util/SocketClient.hpp
@@ -37,7 +37,8 @@ public:
};
unsigned short get_port() { return m_port; };
char *get_server_name() { return m_server_name; };
- NDB_SOCKET_TYPE connect();
+ int bind(const char* toaddress, unsigned short toport);
+ NDB_SOCKET_TYPE connect(const char* toaddress = 0, unsigned short port = 0);
bool close();
};
diff --git a/storage/ndb/include/util/ndb_opts.h b/storage/ndb/include/util/ndb_opts.h
index 08ab4a2e9df..053cc8613f7 100644
--- a/storage/ndb/include/util/ndb_opts.h
+++ b/storage/ndb/include/util/ndb_opts.h
@@ -58,7 +58,7 @@ const char *opt_debug= 0;
{ "ndb-connectstring", OPT_NDB_CONNECTSTRING, \
"Set connect string for connecting to ndb_mgmd. " \
"Syntax: \"[nodeid=<id>;][host=]<hostname>[:<port>]\". " \
- "Overides specifying entries in NDB_CONNECTSTRING and Ndb.cfg", \
+ "Overrides specifying entries in NDB_CONNECTSTRING and my.cnf", \
(gptr*) &opt_ndb_connectstring, (gptr*) &opt_ndb_connectstring, \
0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0 },\
{ "ndb-mgmd-host", OPT_NDB_MGMD, \
diff --git a/storage/ndb/include/util/socket_io.h b/storage/ndb/include/util/socket_io.h
index a0e6c4e369d..fdac455ab57 100644
--- a/storage/ndb/include/util/socket_io.h
+++ b/storage/ndb/include/util/socket_io.h
@@ -21,12 +21,17 @@
#include <NdbTCP.h>
+#include <NdbMutex.h>
+
#ifdef __cplusplus
extern "C" {
#endif
int read_socket(NDB_SOCKET_TYPE, int timeout_ms, char *, int len);
- int readln_socket(NDB_SOCKET_TYPE, int timeout_ms, char *, int len);
+
+ int readln_socket(NDB_SOCKET_TYPE socket, int timeout_millis,
+ char * buf, int buflen, NdbMutex *mutex);
+
int write_socket(NDB_SOCKET_TYPE, int timeout_ms, const char[], int len);
int print_socket(NDB_SOCKET_TYPE, int timeout_ms, const char *, ...);
diff --git a/storage/ndb/src/common/debugger/signaldata/SignalNames.cpp b/storage/ndb/src/common/debugger/signaldata/SignalNames.cpp
index a96d0de0560..259f7480e8f 100644
--- a/storage/ndb/src/common/debugger/signaldata/SignalNames.cpp
+++ b/storage/ndb/src/common/debugger/signaldata/SignalNames.cpp
@@ -633,5 +633,7 @@ const GsnName SignalNames [] = {
,{ GSN_DICT_LOCK_REF, "DICT_LOCK_REF" }
,{ GSN_DICT_UNLOCK_ORD, "DICT_UNLOCK_ORD" }
+ ,{ GSN_UPDATE_FRAG_DIST_KEY_ORD, "UPDATE_FRAG_DIST_KEY_ORD" }
+ ,{ GSN_DICT_COMMIT_REQ, "DICT_COMMIT_REQ"}
};
const unsigned short NO_OF_SIGNAL_NAMES = sizeof(SignalNames)/sizeof(GsnName);
diff --git a/storage/ndb/src/common/logger/FileLogHandler.cpp b/storage/ndb/src/common/logger/FileLogHandler.cpp
index 3d29e63ac1f..b8859630406 100644
--- a/storage/ndb/src/common/logger/FileLogHandler.cpp
+++ b/storage/ndb/src/common/logger/FileLogHandler.cpp
@@ -147,6 +147,7 @@ FileLogHandler::createNewFile()
bool rc = true;
int fileNo = 1;
char newName[PATH_MAX];
+ time_t newMtime, preMtime = 0;
do
{
@@ -159,7 +160,15 @@ FileLogHandler::createNewFile()
}
BaseString::snprintf(newName, sizeof(newName),
"%s.%d", m_pLogFile->getName(), fileNo++);
-
+ newMtime = File_class::mtime(newName);
+ if (newMtime < preMtime)
+ {
+ break;
+ }
+ else
+ {
+ preMtime = newMtime;
+ }
} while (File_class::exists(newName));
m_pLogFile->close();
diff --git a/storage/ndb/src/common/mgmcommon/ConfigRetriever.cpp b/storage/ndb/src/common/mgmcommon/ConfigRetriever.cpp
index e24ed5b8ddc..ed55e2f2f2b 100644
--- a/storage/ndb/src/common/mgmcommon/ConfigRetriever.cpp
+++ b/storage/ndb/src/common/mgmcommon/ConfigRetriever.cpp
@@ -45,7 +45,8 @@
//****************************************************************************
ConfigRetriever::ConfigRetriever(const char * _connect_string,
- Uint32 version, Uint32 node_type)
+ Uint32 version, Uint32 node_type,
+ const char * _bindaddress)
{
DBUG_ENTER("ConfigRetriever::ConfigRetriever");
@@ -69,6 +70,15 @@ ConfigRetriever::ConfigRetriever(const char * _connect_string,
setError(CR_ERROR, tmp.c_str());
DBUG_VOID_RETURN;
}
+
+ if (_bindaddress)
+ {
+ if (ndb_mgm_set_bindaddress(m_handle, _bindaddress))
+ {
+ setError(CR_ERROR, ndb_mgm_get_latest_error_desc(m_handle));
+ DBUG_VOID_RETURN;
+ }
+ }
resetError();
DBUG_VOID_RETURN;
}
diff --git a/storage/ndb/src/common/transporter/Transporter.cpp b/storage/ndb/src/common/transporter/Transporter.cpp
index 820aa4cfc18..383456f1077 100644
--- a/storage/ndb/src/common/transporter/Transporter.cpp
+++ b/storage/ndb/src/common/transporter/Transporter.cpp
@@ -60,9 +60,6 @@ Transporter::Transporter(TransporterRegistry &t_reg,
}
strncpy(localHostName, lHostName, sizeof(localHostName));
- if (strlen(lHostName) > 0)
- Ndb_getInAddr(&localHostAddress, lHostName);
-
DBUG_PRINT("info",("rId=%d lId=%d isServer=%d rHost=%s lHost=%s s_port=%d",
remoteNodeId, localNodeId, isServer,
remoteHostName, localHostName,
@@ -128,10 +125,23 @@ Transporter::connect_client() {
return true;
if(isMgmConnection)
+ {
sockfd= m_transporter_registry.connect_ndb_mgmd(m_socket_client);
+ }
else
+ {
+ if (!m_socket_client->init())
+ {
+ return false;
+ }
+ if (strlen(localHostName) > 0)
+ {
+ if (m_socket_client->bind(localHostName, 0) != 0)
+ return false;
+ }
sockfd= m_socket_client->connect();
-
+ }
+
return connect_client(sockfd);
}
diff --git a/storage/ndb/src/common/util/File.cpp b/storage/ndb/src/common/util/File.cpp
index 52ad3a4a51e..056b7ff199b 100644
--- a/storage/ndb/src/common/util/File.cpp
+++ b/storage/ndb/src/common/util/File.cpp
@@ -24,6 +24,18 @@
//
// PUBLIC
//
+time_t
+File_class::mtime(const char* aFileName)
+{
+ MY_STAT stmp;
+ time_t rc = 0;
+
+ if (my_stat(aFileName, &stmp, MYF(0)) != NULL) {
+ rc = stmp.st_mtime;
+ }
+
+ return rc;
+}
bool
File_class::exists(const char* aFileName)
diff --git a/storage/ndb/src/common/util/InputStream.cpp b/storage/ndb/src/common/util/InputStream.cpp
index 410e9a70e9c..59aeccef84d 100644
--- a/storage/ndb/src/common/util/InputStream.cpp
+++ b/storage/ndb/src/common/util/InputStream.cpp
@@ -36,26 +36,35 @@ FileInputStream::gets(char * buf, int bufLen){
SocketInputStream::SocketInputStream(NDB_SOCKET_TYPE socket,
unsigned readTimeout)
- : m_socket(socket) {
- m_timeout = readTimeout;
+ : m_socket(socket) {
+ m_startover= true;
+ m_timeout = readTimeout;
}
-char*
+char*
SocketInputStream::gets(char * buf, int bufLen) {
- buf[0] = 77;
assert(bufLen >= 2);
- int res = readln_socket(m_socket, m_timeout, buf, bufLen - 1);
+ int offset= 0;
+ if(m_startover)
+ {
+ buf[0]= '\0';
+ m_startover= false;
+ }
+ else
+ offset= strlen(buf);
+
+ int res = readln_socket(m_socket, m_timeout, buf+offset, bufLen-offset, m_mutex);
+
+ if(res == 0)
+ {
+ buf[0]=0;
+ return buf;
+ }
+
+ m_startover= true;
+
if(res == -1)
return 0;
- if(res == 0 && buf[0] == 77){ // select return 0
- buf[0] = 0;
- } else if(res == 0 && buf[0] == 0){ // only newline
- buf[0] = '\n';
- buf[1] = 0;
- } else {
- int len = strlen(buf);
- buf[len + 1] = '\0';
- buf[len] = '\n';
- }
+
return buf;
}
diff --git a/storage/ndb/src/common/util/Parser.cpp b/storage/ndb/src/common/util/Parser.cpp
index 3a86ae8f318..540724e4f68 100644
--- a/storage/ndb/src/common/util/Parser.cpp
+++ b/storage/ndb/src/common/util/Parser.cpp
@@ -32,6 +32,7 @@ public:
char* gets(char * buf, int bufLen);
void push_back(const char *);
+ void set_mutex(NdbMutex *m) { in.set_mutex(m); };
private:
InputStream & in;
char * buffer;
@@ -144,25 +145,32 @@ ParserImpl::run(Context * ctx, const class Properties ** pDst,
{
DBUG_ENTER("ParserImpl::run");
+ input.set_mutex(ctx->m_mutex);
+
* pDst = 0;
bool ownStop = false;
if(stop == 0)
stop = &ownStop;
-
+
ctx->m_aliasUsed.clear();
-
+
const unsigned sz = sizeof(ctx->m_tokenBuffer);
ctx->m_currentToken = input.gets(ctx->m_tokenBuffer, sz);
if(Eof(ctx->m_currentToken)){
ctx->m_status = Parser<Dummy>::Eof;
DBUG_RETURN(false);
}
-
- if(ctx->m_currentToken[0] == 0){
+
+ int last= strlen(ctx->m_currentToken);
+ if(last>0)
+ last--;
+
+ if(ctx->m_currentToken[last] !='\n'){
ctx->m_status = Parser<Dummy>::NoLine;
+ ctx->m_tokenBuffer[0]= '\0';
DBUG_RETURN(false);
}
-
+
if(Empty(ctx->m_currentToken)){
ctx->m_status = Parser<Dummy>::EmptyLine;
DBUG_RETURN(false);
@@ -174,14 +182,14 @@ ParserImpl::run(Context * ctx, const class Properties ** pDst,
ctx->m_status = Parser<Dummy>::UnknownCommand;
DBUG_RETURN(false);
}
-
+
Properties * p = new Properties();
-
+
bool invalidArgument = false;
ctx->m_currentToken = input.gets(ctx->m_tokenBuffer, sz);
-
- while((! * stop) &&
- !Eof(ctx->m_currentToken) &&
+
+ while((! * stop) &&
+ !Eof(ctx->m_currentToken) &&
!Empty(ctx->m_currentToken)){
if(ctx->m_currentToken[0] != 0){
trim(ctx->m_currentToken);
@@ -193,7 +201,7 @@ ParserImpl::run(Context * ctx, const class Properties ** pDst,
}
ctx->m_currentToken = input.gets(ctx->m_tokenBuffer, sz);
}
-
+
if(invalidArgument){
char buf[sz];
char * tmp;
@@ -204,13 +212,13 @@ ParserImpl::run(Context * ctx, const class Properties ** pDst,
}
DBUG_RETURN(false);
}
-
+
if(* stop){
delete p;
ctx->m_status = Parser<Dummy>::ExternalStop;
DBUG_RETURN(false);
}
-
+
if(!checkMandatory(ctx, p)){
ctx->m_status = Parser<Dummy>::MissingMandatoryArgument;
delete p;
@@ -226,9 +234,9 @@ ParserImpl::run(Context * ctx, const class Properties ** pDst,
tmp.put("name", alias->name);
tmp.put("realName", alias->realName);
p->put("$ALIAS", i, &tmp);
- }
+ }
p->put("$ALIAS", ctx->m_aliasUsed.size());
-
+
ctx->m_status = Parser<Dummy>::Ok;
* pDst = p;
DBUG_RETURN(true);
diff --git a/storage/ndb/src/common/util/SocketClient.cpp b/storage/ndb/src/common/util/SocketClient.cpp
index 821624eb5c4..f4f2babf312 100644
--- a/storage/ndb/src/common/util/SocketClient.cpp
+++ b/storage/ndb/src/common/util/SocketClient.cpp
@@ -25,7 +25,7 @@ SocketClient::SocketClient(const char *server_name, unsigned short port, SocketA
{
m_auth= sa;
m_port= port;
- m_server_name= strdup(server_name);
+ m_server_name= server_name ? strdup(server_name) : 0;
m_sockfd= NDB_INVALID_SOCKET;
}
@@ -45,13 +45,16 @@ SocketClient::init()
if (m_sockfd != NDB_INVALID_SOCKET)
NDB_CLOSE_SOCKET(m_sockfd);
- memset(&m_servaddr, 0, sizeof(m_servaddr));
- m_servaddr.sin_family = AF_INET;
- m_servaddr.sin_port = htons(m_port);
- // Convert ip address presentation format to numeric format
- if (Ndb_getInAddr(&m_servaddr.sin_addr, m_server_name))
- return false;
-
+ if (m_server_name)
+ {
+ memset(&m_servaddr, 0, sizeof(m_servaddr));
+ m_servaddr.sin_family = AF_INET;
+ m_servaddr.sin_port = htons(m_port);
+ // Convert ip address presentation format to numeric format
+ if (Ndb_getInAddr(&m_servaddr.sin_addr, m_server_name))
+ return false;
+ }
+
m_sockfd= socket(AF_INET, SOCK_STREAM, 0);
if (m_sockfd == NDB_INVALID_SOCKET) {
return false;
@@ -62,8 +65,45 @@ SocketClient::init()
return true;
}
+int
+SocketClient::bind(const char* bindaddress, unsigned short localport)
+{
+ if (m_sockfd == NDB_INVALID_SOCKET)
+ return -1;
+
+ struct sockaddr_in local;
+ memset(&local, 0, sizeof(local));
+ local.sin_family = AF_INET;
+ local.sin_port = htons(localport);
+ // Convert ip address presentation format to numeric format
+ if (Ndb_getInAddr(&local.sin_addr, bindaddress))
+ {
+ return errno ? errno : EINVAL;
+ }
+
+ const int on = 1;
+ if (setsockopt(m_sockfd, SOL_SOCKET, SO_REUSEADDR,
+ (const char*)&on, sizeof(on)) == -1) {
+
+ int ret = errno;
+ NDB_CLOSE_SOCKET(m_sockfd);
+ m_sockfd= NDB_INVALID_SOCKET;
+ return errno;
+ }
+
+ if (::bind(m_sockfd, (struct sockaddr*)&local, sizeof(local)) == -1)
+ {
+ int ret = errno;
+ NDB_CLOSE_SOCKET(m_sockfd);
+ m_sockfd= NDB_INVALID_SOCKET;
+ return ret;
+ }
+
+ return 0;
+}
+
NDB_SOCKET_TYPE
-SocketClient::connect()
+SocketClient::connect(const char *toaddress, unsigned short toport)
{
if (m_sockfd == NDB_INVALID_SOCKET)
{
@@ -74,6 +114,21 @@ SocketClient::connect()
return NDB_INVALID_SOCKET;
}
}
+
+ if (toaddress)
+ {
+ if (m_server_name)
+ free(m_server_name);
+ m_server_name = strdup(toaddress);
+ m_port = toport;
+ memset(&m_servaddr, 0, sizeof(m_servaddr));
+ m_servaddr.sin_family = AF_INET;
+ m_servaddr.sin_port = htons(toport);
+ // Convert ip address presentation format to numeric format
+ if (Ndb_getInAddr(&m_servaddr.sin_addr, m_server_name))
+ return NDB_INVALID_SOCKET;
+ }
+
const int r = ::connect(m_sockfd, (struct sockaddr*) &m_servaddr, sizeof(m_servaddr));
if (r == -1) {
NDB_CLOSE_SOCKET(m_sockfd);
diff --git a/storage/ndb/src/common/util/socket_io.cpp b/storage/ndb/src/common/util/socket_io.cpp
index 58636e6663d..deb62d1867a 100644
--- a/storage/ndb/src/common/util/socket_io.cpp
+++ b/storage/ndb/src/common/util/socket_io.cpp
@@ -49,7 +49,7 @@ read_socket(NDB_SOCKET_TYPE socket, int timeout_millis,
extern "C"
int
readln_socket(NDB_SOCKET_TYPE socket, int timeout_millis,
- char * buf, int buflen){
+ char * buf, int buflen, NdbMutex *mutex){
if(buflen <= 1)
return 0;
@@ -65,7 +65,12 @@ readln_socket(NDB_SOCKET_TYPE socket, int timeout_millis,
timeout.tv_sec = (timeout_millis / 1000);
timeout.tv_usec = (timeout_millis % 1000) * 1000;
+ if(mutex)
+ NdbMutex_Unlock(mutex);
const int selectRes = select(socket + 1, &readset, 0, 0, &timeout);
+ if(mutex)
+ NdbMutex_Lock(mutex);
+
if(selectRes == 0){
return 0;
}
@@ -75,7 +80,6 @@ readln_socket(NDB_SOCKET_TYPE socket, int timeout_millis,
return -1;
}
- buf[0] = 0;
const int t = recv(socket, buf, buflen, MSG_PEEK);
if(t < 1)
@@ -87,27 +91,28 @@ readln_socket(NDB_SOCKET_TYPE socket, int timeout_millis,
for(int i=0; i< t;i++)
{
if(buf[i] == '\n'){
- recv(socket, buf, i+1, 0);
- buf[i] = 0;
+ int r= recv(socket, buf, i+1, 0);
+ buf[i+1]= 0;
+ if(r < 1) {
+ fcntl(socket, F_SETFL, sock_flags);
+ return -1;
+ }
if(i > 0 && buf[i-1] == '\r'){
- i--;
- buf[i] = 0;
+ buf[i-1] = '\n';
+ buf[i]= '\0';
}
fcntl(socket, F_SETFL, sock_flags);
- return t;
+ return r;
}
}
- if(t == (buflen - 1)){
- recv(socket, buf, t, 0);
- buf[t] = 0;
- fcntl(socket, F_SETFL, sock_flags);
- return buflen;
- }
-
- return 0;
+ int r= recv(socket, buf, t, 0);
+ if(r>=0)
+ buf[r] = 0;
+ fcntl(socket, F_SETFL, sock_flags);
+ return r;
}
extern "C"
diff --git a/storage/ndb/src/cw/cpcd/main.cpp b/storage/ndb/src/cw/cpcd/main.cpp
index c320f07ef04..137735c9e76 100644
--- a/storage/ndb/src/cw/cpcd/main.cpp
+++ b/storage/ndb/src/cw/cpcd/main.cpp
@@ -82,6 +82,8 @@ int main(int argc, char** argv){
load_defaults("ndb_cpcd",load_default_groups,&argc,&argv);
if (handle_options(&argc, &argv, my_long_options, get_one_option)) {
+ print_defaults(MYSQL_CONFIG_NAME,load_default_groups);
+ puts("");
my_print_help(my_long_options);
my_print_variables(my_long_options);
exit(1);
diff --git a/storage/ndb/src/kernel/blocks/dbdict/Dbdict.cpp b/storage/ndb/src/kernel/blocks/dbdict/Dbdict.cpp
index 150dc75f90c..a7865c356c8 100644
--- a/storage/ndb/src/kernel/blocks/dbdict/Dbdict.cpp
+++ b/storage/ndb/src/kernel/blocks/dbdict/Dbdict.cpp
@@ -2928,10 +2928,10 @@ void Dbdict::checkSchemaStatus(Signal* signal)
// On NR get index from master because index state is not on file
Uint32 type= oldEntry->m_tableType;
- const bool file = c_systemRestart || !DictTabInfo::isIndex(type);
+ const bool file = (* newEntry == * oldEntry) &&
+ (c_systemRestart || !DictTabInfo::isIndex(type));
newEntry->m_info_words= oldEntry->m_info_words;
restartCreateTab(signal, tableId, oldEntry, newEntry, file);
-
return;
}
ndbrequire(ok);
diff --git a/storage/ndb/src/kernel/blocks/dbdih/DbdihMain.cpp b/storage/ndb/src/kernel/blocks/dbdih/DbdihMain.cpp
index 4f20f7bdd22..802230b8e02 100644
--- a/storage/ndb/src/kernel/blocks/dbdih/DbdihMain.cpp
+++ b/storage/ndb/src/kernel/blocks/dbdih/DbdihMain.cpp
@@ -1305,9 +1305,9 @@ void Dbdih::execNDB_STTOR(Signal* signal)
if (isMaster()) {
jam();
systemRestartTakeOverLab(signal);
- if (anyActiveTakeOver() && false) {
+ if (anyActiveTakeOver())
+ {
jam();
- ndbout_c("1 - anyActiveTakeOver == true");
return;
}
}
@@ -2347,6 +2347,8 @@ Dbdih::systemRestartTakeOverLab(Signal* signal)
// NOT ACTIVE NODES THAT HAVE NOT YET BEEN TAKEN OVER NEEDS TAKE OVER
// IMMEDIATELY. IF WE ARE ALIVE WE TAKE OVER OUR OWN NODE.
/*-------------------------------------------------------------------*/
+ infoEvent("Take over of node %d started",
+ nodePtr.i);
startTakeOver(signal, RNIL, nodePtr.i, nodePtr.i);
}//if
break;
@@ -2459,6 +2461,12 @@ void Dbdih::nodeRestartTakeOver(Signal* signal, Uint32 startNodeId)
*--------------------------------------------------------------------*/
Uint32 takeOverNode = Sysfile::getTakeOverNode(startNodeId,
SYSFILE->takeOver);
+ if(takeOverNode == 0){
+ jam();
+ warningEvent("Bug in take-over code restarting");
+ takeOverNode = startNodeId;
+ }
+
startTakeOver(signal, RNIL, startNodeId, takeOverNode);
break;
}
@@ -2612,7 +2620,14 @@ void Dbdih::startTakeOver(Signal* signal,
Sysfile::setTakeOverNode(takeOverPtr.p->toFailedNode, SYSFILE->takeOver,
startNode);
takeOverPtr.p->toMasterStatus = TakeOverRecord::TO_START_COPY;
-
+
+ if (getNodeState().getSystemRestartInProgress())
+ {
+ jam();
+ checkToCopy();
+ checkToCopyCompleted(signal);
+ return;
+ }
cstartGcpNow = true;
}//Dbdih::startTakeOver()
@@ -3264,7 +3279,10 @@ void Dbdih::execCREATE_FRAGCONF(Signal* signal)
copyFragReq->schemaVersion = tabPtr.p->schemaVersion;
copyFragReq->distributionKey = fragPtr.p->distributionKey;
copyFragReq->gci = gci;
- sendSignal(ref, GSN_COPY_FRAGREQ, signal, CopyFragReq::SignalLength, JBB);
+ copyFragReq->nodeCount = extractNodeInfo(fragPtr.p,
+ copyFragReq->nodeList);
+ sendSignal(ref, GSN_COPY_FRAGREQ, signal,
+ CopyFragReq::SignalLength + copyFragReq->nodeCount, JBB);
} else {
ndbrequire(takeOverPtr.p->toMasterStatus == TakeOverRecord::COMMIT_CREATE);
jam();
@@ -3514,6 +3532,18 @@ void Dbdih::toCopyCompletedLab(Signal * signal, TakeOverRecordPtr takeOverPtr)
signal->theData[1] = takeOverPtr.p->toStartingNode;
sendSignal(CMVMI_REF, GSN_EVENT_REP, signal, 2, JBB);
+ if (getNodeState().getSystemRestartInProgress())
+ {
+ jam();
+ infoEvent("Take over of node %d complete", takeOverPtr.p->toStartingNode);
+ setNodeActiveStatus(takeOverPtr.p->toStartingNode, Sysfile::NS_Active);
+ takeOverPtr.p->toMasterStatus = TakeOverRecord::WAIT_LCP;
+ takeOverCompleted(takeOverPtr.p->toStartingNode);
+ checkToCopy();
+ checkToCopyCompleted(signal);
+ return;
+ }
+
c_lcpState.immediateLcpStart = true;
takeOverPtr.p->toMasterStatus = TakeOverRecord::WAIT_LCP;
@@ -3620,16 +3650,12 @@ void Dbdih::execEND_TOCONF(Signal* signal)
}//if
endTakeOver(takeOverPtr.i);
- ndbout_c("2 - endTakeOver");
if (cstartPhase == ZNDB_SPH4) {
jam();
- ndbrequire(false);
if (anyActiveTakeOver()) {
jam();
- ndbout_c("4 - anyActiveTakeOver == true");
return;
}//if
- ndbout_c("5 - anyActiveTakeOver == false -> ndbsttorry10Lab");
ndbsttorry10Lab(signal, __LINE__);
return;
}//if
@@ -6699,7 +6725,13 @@ void Dbdih::execCREATE_FRAGMENTATION_REQ(Signal * signal)
}
}
}
- ndbrequire(count == (2U + (1 + noOfReplicas) * noOfFragments));
+ if(count != (2U + (1 + noOfReplicas) * noOfFragments)){
+ char buf[255];
+ BaseString::snprintf(buf, sizeof(buf),
+ "Illegal configuration change: NoOfReplicas."
+ " Can't be applied online ");
+ progError(__LINE__, NDBD_EXIT_INVALID_CONFIG, buf);
+ }
CreateFragmentationConf * const conf =
(CreateFragmentationConf*)signal->getDataPtrSend();
@@ -10017,73 +10049,84 @@ void Dbdih::startNextChkpt(Signal* signal)
nodePtr.i = replicaPtr.p->procNode;
ptrCheckGuard(nodePtr, MAX_NDB_NODES, nodeRecord);
- if (replicaPtr.p->lcpOngoingFlag &&
- replicaPtr.p->lcpIdStarted < lcpId) {
- jam();
- //-------------------------------------------------------------------
- // We have found a replica on a node that performs local checkpoint
- // that is alive and that have not yet been started.
- //-------------------------------------------------------------------
-
- if (nodePtr.p->noOfStartedChkpt < 2) {
- jam();
- /**
- * Send LCP_FRAG_ORD to LQH
- */
-
- /**
- * Mark the replica so with lcpIdStarted == true
- */
- replicaPtr.p->lcpIdStarted = lcpId;
-
- Uint32 i = nodePtr.p->noOfStartedChkpt;
- nodePtr.p->startedChkpt[i].tableId = tabPtr.i;
- nodePtr.p->startedChkpt[i].fragId = curr.fragmentId;
- nodePtr.p->startedChkpt[i].replicaPtr = replicaPtr.i;
- nodePtr.p->noOfStartedChkpt = i + 1;
-
- sendLCP_FRAG_ORD(signal, nodePtr.p->startedChkpt[i]);
- } else if (nodePtr.p->noOfQueuedChkpt < 2) {
- jam();
- /**
- * Put LCP_FRAG_ORD "in queue"
- */
-
- /**
- * Mark the replica so with lcpIdStarted == true
- */
- replicaPtr.p->lcpIdStarted = lcpId;
+ if (c_lcpState.m_participatingLQH.get(nodePtr.i))
+ {
+ if (replicaPtr.p->lcpOngoingFlag &&
+ replicaPtr.p->lcpIdStarted < lcpId)
+ {
+ jam();
+ //-------------------------------------------------------------------
+ // We have found a replica on a node that performs local checkpoint
+ // that is alive and that have not yet been started.
+ //-------------------------------------------------------------------
- Uint32 i = nodePtr.p->noOfQueuedChkpt;
- nodePtr.p->queuedChkpt[i].tableId = tabPtr.i;
- nodePtr.p->queuedChkpt[i].fragId = curr.fragmentId;
- nodePtr.p->queuedChkpt[i].replicaPtr = replicaPtr.i;
- nodePtr.p->noOfQueuedChkpt = i + 1;
- } else {
- jam();
+ if (nodePtr.p->noOfStartedChkpt < 2)
+ {
+ jam();
+ /**
+ * Send LCP_FRAG_ORD to LQH
+ */
+
+ /**
+ * Mark the replica so with lcpIdStarted == true
+ */
+ replicaPtr.p->lcpIdStarted = lcpId;
- if(save){
+ Uint32 i = nodePtr.p->noOfStartedChkpt;
+ nodePtr.p->startedChkpt[i].tableId = tabPtr.i;
+ nodePtr.p->startedChkpt[i].fragId = curr.fragmentId;
+ nodePtr.p->startedChkpt[i].replicaPtr = replicaPtr.i;
+ nodePtr.p->noOfStartedChkpt = i + 1;
+
+ sendLCP_FRAG_ORD(signal, nodePtr.p->startedChkpt[i]);
+ }
+ else if (nodePtr.p->noOfQueuedChkpt < 2)
+ {
+ jam();
/**
- * Stop increasing value on first that was "full"
+ * Put LCP_FRAG_ORD "in queue"
*/
- c_lcpState.currentFragment = curr;
- save = false;
- }
-
- busyNodes.set(nodePtr.i);
- if(busyNodes.count() == lcpNodes){
+
/**
- * There were no possibility to start the local checkpoint
- * and it was not possible to queue it up. In this case we
- * stop the start of local checkpoints until the nodes with a
- * backlog have performed more checkpoints. We will return and
- * will not continue the process of starting any more checkpoints.
+ * Mark the replica so with lcpIdStarted == true
*/
- return;
+ replicaPtr.p->lcpIdStarted = lcpId;
+
+ Uint32 i = nodePtr.p->noOfQueuedChkpt;
+ nodePtr.p->queuedChkpt[i].tableId = tabPtr.i;
+ nodePtr.p->queuedChkpt[i].fragId = curr.fragmentId;
+ nodePtr.p->queuedChkpt[i].replicaPtr = replicaPtr.i;
+ nodePtr.p->noOfQueuedChkpt = i + 1;
+ }
+ else
+ {
+ jam();
+
+ if(save)
+ {
+ /**
+ * Stop increasing value on first that was "full"
+ */
+ c_lcpState.currentFragment = curr;
+ save = false;
+ }
+
+ busyNodes.set(nodePtr.i);
+ if(busyNodes.count() == lcpNodes)
+ {
+ /**
+ * There were no possibility to start the local checkpoint
+ * and it was not possible to queue it up. In this case we
+ * stop the start of local checkpoints until the nodes with a
+ * backlog have performed more checkpoints. We will return and
+ * will not continue the process of starting any more checkpoints.
+ */
+ return;
+ }//if
}//if
- }//if
- }
- }//while
+ }
+ }//while
+ }
curr.fragmentId++;
if (curr.fragmentId >= tabPtr.p->totalfragments) {
jam();
diff --git a/storage/ndb/src/kernel/blocks/dbdih/Sysfile.hpp b/storage/ndb/src/kernel/blocks/dbdih/Sysfile.hpp
index 4548ad1a30c..c68359a00d4 100644
--- a/storage/ndb/src/kernel/blocks/dbdih/Sysfile.hpp
+++ b/storage/ndb/src/kernel/blocks/dbdih/Sysfile.hpp
@@ -34,8 +34,8 @@
/**
* No of 32 bits word in sysfile
- *
- * 5 +
+ *
+ * 6 + // was 5 in < version 5.1
* MAX_NDB_NODES + // lastCompletedGCI
* NODE_ARRAY_SIZE(MAX_NDB_NODES, 4) + // nodeStatus
* NODE_ARRAY_SIZE(MAX_NDB_NODES, NODEID_BITS) + // nodeGroups
diff --git a/storage/ndb/src/kernel/blocks/dblqh/Dblqh.hpp b/storage/ndb/src/kernel/blocks/dblqh/Dblqh.hpp
index ec3042fa6dc..736134a8a8b 100644
--- a/storage/ndb/src/kernel/blocks/dblqh/Dblqh.hpp
+++ b/storage/ndb/src/kernel/blocks/dblqh/Dblqh.hpp
@@ -2147,6 +2147,7 @@ private:
void execSTORED_PROCCONF(Signal* signal);
void execSTORED_PROCREF(Signal* signal);
void execCOPY_FRAGREQ(Signal* signal);
+ void execUPDATE_FRAG_DIST_KEY_ORD(Signal*);
void execCOPY_ACTIVEREQ(Signal* signal);
void execCOPY_STATEREQ(Signal* signal);
void execLQH_TRANSREQ(Signal* signal);
diff --git a/storage/ndb/src/kernel/blocks/dblqh/DblqhInit.cpp b/storage/ndb/src/kernel/blocks/dblqh/DblqhInit.cpp
index 890aaeb00f3..3f7892f774d 100644
--- a/storage/ndb/src/kernel/blocks/dblqh/DblqhInit.cpp
+++ b/storage/ndb/src/kernel/blocks/dblqh/DblqhInit.cpp
@@ -301,6 +301,9 @@ Dblqh::Dblqh(Block_context& ctx):
addRecSignal(GSN_RESTORE_LCP_REF, &Dblqh::execRESTORE_LCP_REF);
addRecSignal(GSN_RESTORE_LCP_CONF, &Dblqh::execRESTORE_LCP_CONF);
+
+ addRecSignal(GSN_UPDATE_FRAG_DIST_KEY_ORD,
+ &Dblqh::execUPDATE_FRAG_DIST_KEY_ORD);
initData();
diff --git a/storage/ndb/src/kernel/blocks/dblqh/DblqhMain.cpp b/storage/ndb/src/kernel/blocks/dblqh/DblqhMain.cpp
index 98f46ac8c44..9a7803efbec 100644
--- a/storage/ndb/src/kernel/blocks/dblqh/DblqhMain.cpp
+++ b/storage/ndb/src/kernel/blocks/dblqh/DblqhMain.cpp
@@ -9913,6 +9913,7 @@ void Dblqh::execCOPY_FRAGREQ(Signal* signal)
const CopyFragReq * const copyFragReq = (CopyFragReq *)&signal->theData[0];
tabptr.i = copyFragReq->tableId;
ptrCheckGuard(tabptr, ctabrecFileSize, tablerec);
+ Uint32 i;
const Uint32 fragId = copyFragReq->fragId;
const Uint32 copyPtr = copyFragReq->userPtr;
const Uint32 userRef = copyFragReq->userRef;
@@ -9925,8 +9926,20 @@ void Dblqh::execCOPY_FRAGREQ(Signal* signal)
ndbrequire(cfirstfreeTcConrec != RNIL);
ndbrequire(fragptr.p->m_scanNumberMask.get(NR_ScanNo));
- fragptr.p->fragDistributionKey = copyFragReq->distributionKey;
-
+ Uint32 key = fragptr.p->fragDistributionKey = copyFragReq->distributionKey;
+
+ Uint32 checkversion = NDB_VERSION >= MAKE_VERSION(5,1,0) ?
+ NDBD_UPDATE_FRAG_DIST_KEY_51 : NDBD_UPDATE_FRAG_DIST_KEY_50;
+
+ Uint32 nodeCount = copyFragReq->nodeCount;
+ NdbNodeBitmask nodemask;
+ if (getNodeInfo(refToNode(userRef)).m_version >= checkversion)
+ {
+ ndbrequire(nodeCount <= MAX_REPLICAS);
+ for (i = 0; i<nodeCount; i++)
+ nodemask.set(copyFragReq->nodeList[i]);
+ }
+
if (DictTabInfo::isOrderedIndex(tabptr.p->tableType)) {
jam();
/**
@@ -10009,9 +10022,42 @@ void Dblqh::execCOPY_FRAGREQ(Signal* signal)
req->savePointId = tcConnectptr.p->savePointId;
sendSignal(scanptr.p->scanBlockref, GSN_ACC_SCANREQ, signal,
AccScanReq::SignalLength, JBB);
+
+ if (! nodemask.isclear())
+ {
+ ndbrequire(nodemask.get(getOwnNodeId()));
+ ndbrequire(nodemask.get(nodeId)); // cpy dest
+ nodemask.clear(getOwnNodeId());
+ nodemask.clear(nodeId);
+
+ UpdateFragDistKeyOrd*
+ ord = (UpdateFragDistKeyOrd*)signal->getDataPtrSend();
+ ord->tableId = tabptr.i;
+ ord->fragId = fragId;
+ ord->fragDistributionKey = key;
+ i = 0;
+ while ((i = nodemask.find(i+1)) != NdbNodeBitmask::NotFound)
+ {
+ if (getNodeInfo(i).m_version >= checkversion)
+ sendSignal(calcLqhBlockRef(i), GSN_UPDATE_FRAG_DIST_KEY_ORD,
+ signal, UpdateFragDistKeyOrd::SignalLength, JBB);
+ }
+ }
return;
}//Dblqh::execCOPY_FRAGREQ()
+void
+Dblqh::execUPDATE_FRAG_DIST_KEY_ORD(Signal * signal)
+{
+ jamEntry();
+ UpdateFragDistKeyOrd* ord =(UpdateFragDistKeyOrd*)signal->getDataPtr();
+
+ tabptr.i = ord->tableId;
+ ptrCheckGuard(tabptr, ctabrecFileSize, tablerec);
+ ndbrequire(getFragmentrec(signal, ord->fragId));
+ fragptr.p->fragDistributionKey = ord->fragDistributionKey;
+}
+
void Dblqh::accScanConfCopyLab(Signal* signal)
{
AccScanConf * const accScanConf = (AccScanConf *)&signal->theData[0];
@@ -18292,6 +18338,18 @@ Dblqh::execDUMP_STATE_ORD(Signal* signal)
if(tabPtr.p->tableStatus != Tablerec::NOT_DEFINED){
infoEvent("Table %d Status: %d Usage: %d",
i, tabPtr.p->tableStatus, tabPtr.p->usageCount);
+
+ for (Uint32 j = 0; j<MAX_FRAG_PER_NODE; j++)
+ {
+ FragrecordPtr fragPtr;
+ if ((fragPtr.i = tabPtr.p->fragrec[j]) != RNIL)
+ {
+ c_fragment_pool.getPtr(fragPtr);
+ infoEvent(" frag: %d distKey: %u",
+ tabPtr.p->fragid[j],
+ fragPtr.p->fragDistributionKey);
+ }
+ }
}
}
return;
diff --git a/storage/ndb/src/kernel/blocks/dbtc/DbtcMain.cpp b/storage/ndb/src/kernel/blocks/dbtc/DbtcMain.cpp
index 18cb404fc8e..04f44a2742d 100644
--- a/storage/ndb/src/kernel/blocks/dbtc/DbtcMain.cpp
+++ b/storage/ndb/src/kernel/blocks/dbtc/DbtcMain.cpp
@@ -1003,13 +1003,6 @@ Dbtc::handleFailedApiNode(Signal* signal,
TloopCount += 64;
break;
case CS_CONNECTED:
- /*********************************************************************/
- // The api record is connected to failed node. We need to release the
- // connection and set it in a disconnected state.
- /*********************************************************************/
- jam();
- releaseApiCon(signal, apiConnectptr.i);
- break;
case CS_REC_COMMITTING:
case CS_RECEIVING:
case CS_STARTED:
@@ -6317,6 +6310,18 @@ void Dbtc::timeOutFoundLab(Signal* signal, Uint32 TapiConPtr, Uint32 errCode)
break;
case CS_START_SCAN:{
jam();
+
+ /*
+ We are waiting for application to continue the transaction. In this
+ particular state we will use the application timeout parameter rather
+ than the shorter Deadlock detection timeout.
+ */
+ if (c_appl_timeout_value == 0 ||
+ (ctcTimer - getApiConTimer(apiConnectptr.i)) <= c_appl_timeout_value) {
+ jam();
+ return;
+ }//if
+
ScanRecordPtr scanPtr;
scanPtr.i = apiConnectptr.p->apiScanRec;
ptrCheckGuard(scanPtr, cscanrecFileSize, scanRecord);
@@ -9848,6 +9853,17 @@ void Dbtc::sendScanTabConf(Signal* signal, ScanRecordPtr scanPtr) {
conf->requestInfo = op_count | ScanTabConf::EndOfData;
releaseScanResources(scanPtr);
}
+ else
+ {
+ if (scanPtr.p->m_running_scan_frags.isEmpty())
+ {
+ jam();
+ /**
+ * All scan frags delivered...waiting for API
+ */
+ setApiConTimer(apiConnectptr.i, ctcTimer, __LINE__);
+ }
+ }
if(4 + 3 * op_count > 25){
jam();
diff --git a/storage/ndb/src/kernel/blocks/ndbcntr/NdbcntrMain.cpp b/storage/ndb/src/kernel/blocks/ndbcntr/NdbcntrMain.cpp
index 249a0177b3f..84e3279afaf 100644
--- a/storage/ndb/src/kernel/blocks/ndbcntr/NdbcntrMain.cpp
+++ b/storage/ndb/src/kernel/blocks/ndbcntr/NdbcntrMain.cpp
@@ -2316,7 +2316,33 @@ Ndbcntr::StopRecord::checkNodeFail(Signal* signal){
{
NdbNodeBitmask tmp;
tmp.assign(NdbNodeBitmask::Size, stopReq.nodes);
+
+ NdbNodeBitmask ndbStopNodes;
+ ndbStopNodes.assign(NdbNodeBitmask::Size, stopReq.nodes);
+ ndbStopNodes.bitAND(ndbMask);
+ ndbStopNodes.copyto(NdbNodeBitmask::Size, stopReq.nodes);
+
ndbMask.bitANDC(tmp);
+
+ bool allNodesStopped = true;
+ int i ;
+ for( i = 0; i< NdbNodeBitmask::Size; i++ ){
+ if ( stopReq.nodes[i] != 0 ){
+ allNodesStopped = false;
+ break;
+ }
+ }
+
+ if ( allNodesStopped ) {
+ StopConf * const stopConf = (StopConf *)&signal->theData[0];
+ stopConf->senderData = stopReq.senderData;
+ stopConf->nodeState = (Uint32) NodeState::SL_NOTHING;
+ cntr.sendSignal(stopReq.senderRef, GSN_STOP_CONF, signal,
+ StopConf::SignalLength, JBB);
+ stopReq.senderRef = 0;
+ return false;
+ }
+
}
else
{
diff --git a/storage/ndb/src/kernel/blocks/qmgr/QmgrMain.cpp b/storage/ndb/src/kernel/blocks/qmgr/QmgrMain.cpp
index 0da2de3b7a2..23152af2775 100644
--- a/storage/ndb/src/kernel/blocks/qmgr/QmgrMain.cpp
+++ b/storage/ndb/src/kernel/blocks/qmgr/QmgrMain.cpp
@@ -153,6 +153,7 @@ void Qmgr::execCONTINUEB(Signal* signal)
return;
}
Uint64 now = NdbTick_CurrentMillisecond();
+
if (now > (c_start_election_time + c_restartFailureTimeout))
{
jam();
@@ -698,7 +699,40 @@ void Qmgr::execCM_REGREQ(Signal* signal)
sendCmRegrefLab(signal, Tblockref, CmRegRef::ZNOT_IN_CFG);
return;
}
-
+
+ if (getNodeState().getSingleUserMode())
+ {
+ /**
+ * The cluster is in single user mode.
+ * Data node is not allowed to get added in the cluster
+ * while in single user mode.
+ */
+ // handle rolling upgrade
+ {
+ unsigned int get_major = getMajor(startingVersion);
+ unsigned int get_minor = getMinor(startingVersion);
+ unsigned int get_build = getBuild(startingVersion);
+
+ if (startingVersion < NDBD_QMGR_SINGLEUSER_VERSION_5) {
+ jam();
+
+ infoEvent("QMGR: detect upgrade: new node %u old version %u.%u.%u",
+ (unsigned int)addNodePtr.i, get_major, get_minor, get_build);
+ /**
+ * The new node is old version, send ZINCOMPATIBLE_VERSION instead
+ * of ZSINGLE_USER_MODE.
+ */
+ sendCmRegrefLab(signal, Tblockref, CmRegRef::ZINCOMPATIBLE_VERSION);
+ } else {
+ jam();
+
+ sendCmRegrefLab(signal, Tblockref, CmRegRef::ZSINGLE_USER_MODE);
+ }//if
+ }
+
+ return;
+ }//if
+
ptrCheckGuard(addNodePtr, MAX_NDB_NODES, nodeRec);
Phase phase = addNodePtr.p->phase;
if (phase != ZINIT)
@@ -1093,6 +1127,19 @@ void Qmgr::execCM_REGREF(Signal* signal)
jam();
progError(__LINE__, NDBD_EXIT_NODE_NOT_DEAD);
break;
+ case CmRegRef::ZSINGLE_USER_MODE:
+ jam();
+ progError(__LINE__, NDBD_EXIT_SINGLE_USER_MODE);
+ break;
+ /**
+ * For generic refuse error.
+ * e.g. in online upgrade, we can use this error code instead
+ * of the incompatible error code.
+ */
+ case CmRegRef::ZGENERIC:
+ jam();
+ progError(__LINE__, NDBD_EXIT_GENERIC);
+ break;
case CmRegRef::ZELECTION:
jam();
if (candidate_gci > c_start.m_president_candidate_gci ||
@@ -2025,7 +2072,7 @@ void Qmgr::initData(Signal* signal)
&c_restartPartionedTimeout);
ndb_mgm_get_int_parameter(p, CFG_DB_START_FAILURE_TIMEOUT,
&c_restartFailureTimeout);
-
+
if(c_restartPartialTimeout == 0)
{
c_restartPartialTimeout = ~0;
diff --git a/storage/ndb/src/kernel/error/ndbd_exit_codes.c b/storage/ndb/src/kernel/error/ndbd_exit_codes.c
index b2aa6456369..bf1d143e436 100644
--- a/storage/ndb/src/kernel/error/ndbd_exit_codes.c
+++ b/storage/ndb/src/kernel/error/ndbd_exit_codes.c
@@ -45,6 +45,7 @@ typedef struct ErrStruct {
static const ErrStruct errArray[] =
{
+ {NDBD_EXIT_GENERIC, XRE, "Generic error"},
{NDBD_EXIT_PRGERR, XIE, "Assertion"},
{NDBD_EXIT_NODE_NOT_IN_CONFIG, XCE,
"node id in the configuration has the wrong type, (i.e. not an NDB node)"},
@@ -69,6 +70,8 @@ static const ErrStruct errArray[] =
"No more free UNDO log, increase UndoIndexBuffer"},
{NDBD_EXIT_SR_UNDOLOG, XFI,
"Error while reading the datapages and UNDO log"},
+ {NDBD_EXIT_SINGLE_USER_MODE, XRE, "Data node is not allowed to get added "
+ "to the cluster while it is in single user mode"},
{NDBD_EXIT_MEMALLOC, XCE, "Memory allocation failure, "
"please decrease some configuration parameters"},
{NDBD_EXIT_BLOCK_JBUFCONGESTION, XIE, "Job buffer congestion"},
diff --git a/storage/ndb/src/kernel/vm/Configuration.cpp b/storage/ndb/src/kernel/vm/Configuration.cpp
index 12badffe0e0..81b87c818fb 100644
--- a/storage/ndb/src/kernel/vm/Configuration.cpp
+++ b/storage/ndb/src/kernel/vm/Configuration.cpp
@@ -58,11 +58,14 @@ NDB_STD_OPTS_VARS;
// XXX should be my_bool ???
static int _daemon, _no_daemon, _foreground, _initial, _no_start;
static int _initialstart;
-static const char* _nowait_nodes;
+static const char* _nowait_nodes = 0;
+static const char* _bind_address = 0;
extern Uint32 g_start_type;
extern NdbNodeBitmask g_nowait_nodes;
+const char *load_default_groups[]= { "mysql_cluster","ndbd",0 };
+
/**
* Arguments to NDB process
*/
@@ -98,6 +101,10 @@ static struct my_option my_long_options[] =
"Perform initial start",
(gptr*) &_initialstart, (gptr*) &_initialstart, 0,
GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0 },
+ { "bind-address", OPT_NOWAIT_NODES,
+ "Local bind address",
+ (gptr*) &_bind_address, (gptr*) &_bind_address, 0,
+ GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0 },
{ 0, 0, 0, 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}
};
static void short_usage_sub(void)
@@ -108,6 +115,8 @@ static void usage()
{
short_usage_sub();
ndb_std_print_version();
+ print_defaults(MYSQL_CONFIG_NAME,load_default_groups);
+ puts("");
my_print_help(my_long_options);
my_print_variables(my_long_options);
}
@@ -115,7 +124,6 @@ static void usage()
bool
Configuration::init(int argc, char** argv)
{
- const char *load_default_groups[]= { "mysql_cluster","ndbd",0 };
load_defaults("my",load_default_groups,&argc,&argv);
int ho_error;
@@ -257,7 +265,9 @@ Configuration::fetch_configuration(){
m_mgmd_port= 0;
m_config_retriever= new ConfigRetriever(getConnectString(),
- NDB_VERSION, NODE_TYPE_DB);
+ NDB_VERSION,
+ NODE_TYPE_DB,
+ _bind_address);
if (m_config_retriever->hasError())
{
diff --git a/storage/ndb/src/mgmapi/mgmapi.cpp b/storage/ndb/src/mgmapi/mgmapi.cpp
index 11d81fa0fdd..7c5fafd2286 100644
--- a/storage/ndb/src/mgmapi/mgmapi.cpp
+++ b/storage/ndb/src/mgmapi/mgmapi.cpp
@@ -107,6 +107,7 @@ struct ndb_mgm_handle {
int mgmd_version_major;
int mgmd_version_minor;
int mgmd_version_build;
+ char * m_bindaddress;
};
#define SET_ERROR(h, e, s) setError(h, e, __LINE__, s)
@@ -168,6 +169,7 @@ ndb_mgm_create_handle()
h->cfg_i = -1;
h->errstream = stdout;
h->m_name = 0;
+ h->m_bindaddress = 0;
strncpy(h->last_error_desc, "No error", NDB_MGM_MAX_ERR_DESC_SIZE);
@@ -215,6 +217,22 @@ ndb_mgm_set_connectstring(NdbMgmHandle handle, const char * mgmsrv)
DBUG_RETURN(0);
}
+extern "C"
+int
+ndb_mgm_set_bindaddress(NdbMgmHandle handle, const char * arg)
+{
+ DBUG_ENTER("ndb_mgm_set_bindaddress");
+ if (handle->m_bindaddress)
+ free(handle->m_bindaddress);
+
+ if (arg)
+ handle->m_bindaddress = strdup(arg);
+ else
+ handle->m_bindaddress = 0;
+
+ DBUG_RETURN(0);
+}
+
/**
* Destroy a handle
*/
@@ -241,6 +259,8 @@ ndb_mgm_destroy_handle(NdbMgmHandle * handle)
#endif
(*handle)->cfg.~LocalConfig();
my_free((*handle)->m_name, MYF(MY_ALLOW_ZERO_PTR));
+ if ((*handle)->m_bindaddress)
+ free((*handle)->m_bindaddress);
my_free((char*)* handle,MYF(MY_ALLOW_ZERO_PTR));
* handle = 0;
DBUG_VOID_RETURN;
@@ -433,6 +453,7 @@ ndb_mgm_connect(NdbMgmHandle handle, int no_retries,
BaseString::snprintf(logname, 64, "mgmapi.log");
handle->logfile = fopen(logname, "w");
#endif
+ char buf[1024];
/**
* Do connect
@@ -440,6 +461,50 @@ ndb_mgm_connect(NdbMgmHandle handle, int no_retries,
LocalConfig &cfg= handle->cfg;
NDB_SOCKET_TYPE sockfd= NDB_INVALID_SOCKET;
Uint32 i;
+ int binderror = 0;
+ SocketClient s(0, 0);
+ if (!s.init())
+ {
+ fprintf(handle->errstream,
+ "Unable to create socket, "
+ "while trying to connect with connect string: %s\n",
+ cfg.makeConnectString(buf,sizeof(buf)));
+
+ setError(handle, NDB_MGM_COULD_NOT_CONNECT_TO_SOCKET, __LINE__,
+ "Unable to create socket, "
+ "while trying to connect with connect string: %s\n",
+ cfg.makeConnectString(buf,sizeof(buf)));
+ DBUG_RETURN(-1);
+ }
+
+ if (handle->m_bindaddress)
+ {
+ BaseString::snprintf(buf, sizeof(buf), handle->m_bindaddress);
+ unsigned short portno = 0;
+ char * port = strchr(buf, ':');
+ if (port != 0)
+ {
+ portno = atoi(port+1);
+ * port = 0;
+ }
+ int err;
+ if ((err = s.bind(buf, portno)) != 0)
+ {
+ fprintf(handle->errstream,
+ "Unable to bind local address %s errno: %d, "
+ "while trying to connect with connect string: %s\n",
+ handle->m_bindaddress, err,
+ cfg.makeConnectString(buf,sizeof(buf)));
+
+ setError(handle, NDB_MGM_BIND_ADDRESS, __LINE__,
+ "Unable to bind local address %s errno: %d, "
+ "while trying to connect with connect string: %s\n",
+ handle->m_bindaddress, err,
+ cfg.makeConnectString(buf,sizeof(buf)));
+ DBUG_RETURN(-1);
+ }
+ }
+
while (sockfd == NDB_INVALID_SOCKET)
{
// do all the mgmt servers
@@ -447,8 +512,7 @@ ndb_mgm_connect(NdbMgmHandle handle, int no_retries,
{
if (cfg.ids[i].type != MgmId_TCP)
continue;
- SocketClient s(cfg.ids[i].name.c_str(), cfg.ids[i].port);
- sockfd = s.connect();
+ sockfd = s.connect(cfg.ids[i].name.c_str(), cfg.ids[i].port);
if (sockfd != NDB_INVALID_SOCKET)
break;
}
@@ -456,19 +520,17 @@ ndb_mgm_connect(NdbMgmHandle handle, int no_retries,
break;
#ifndef DBUG_OFF
{
- char buf[1024];
DBUG_PRINT("info",("Unable to connect with connect string: %s",
cfg.makeConnectString(buf,sizeof(buf))));
}
#endif
if (verbose > 0) {
- char buf[1024];
- fprintf(handle->errstream, "Unable to connect with connect string: %s\n",
+ fprintf(handle->errstream,
+ "Unable to connect with connect string: %s\n",
cfg.makeConnectString(buf,sizeof(buf)));
verbose= -1;
}
if (no_retries == 0) {
- char buf[1024];
setError(handle, NDB_MGM_COULD_NOT_CONNECT_TO_SOCKET, __LINE__,
"Unable to connect with connect string: %s",
cfg.makeConnectString(buf,sizeof(buf)));
@@ -509,6 +571,18 @@ ndb_mgm_connect(NdbMgmHandle handle, int no_retries,
}
/**
+ * Only used for low level testing
+ * Never to be used by end user.
+ * Or anybody who doesn't know exactly what they're doing.
+ */
+extern "C"
+int
+ndb_mgm_get_fd(NdbMgmHandle handle)
+{
+ return handle->socket;
+}
+
+/**
* Disconnect from a mgm server
*/
extern "C"
@@ -698,22 +772,16 @@ ndb_mgm_get_status(NdbMgmHandle handle)
SET_ERROR(handle, NDB_MGM_ILLEGAL_SERVER_REPLY, "Probably disconnected");
return NULL;
}
- if(buf[strlen(buf)-1] == '\n')
- buf[strlen(buf)-1] = '\0';
-
- if(strcmp("node status", buf) != 0) {
+ if(strcmp("node status\n", buf) != 0) {
SET_ERROR(handle, NDB_MGM_ILLEGAL_NODE_STATUS, buf);
return NULL;
}
-
if(!in.gets(buf, sizeof(buf)))
{
SET_ERROR(handle, NDB_MGM_ILLEGAL_SERVER_REPLY, "Probably disconnected");
return NULL;
}
- if(buf[strlen(buf)-1] == '\n')
- buf[strlen(buf)-1] = '\0';
-
+
BaseString tmp(buf);
Vector<BaseString> split;
tmp.split(split, ":");
@@ -721,7 +789,7 @@ ndb_mgm_get_status(NdbMgmHandle handle)
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;
@@ -1306,6 +1374,45 @@ ndb_mgm_get_event_category_string(enum ndb_mgm_event_category status)
return 0;
}
+static const char *clusterlog_names[]=
+ { "startup", "shutdown", "statistics", "checkpoint", "noderestart", "connection", "info", "warning", "error", "congestion", "debug", "backup" };
+
+extern "C"
+const unsigned int *
+ndb_mgm_get_clusterlog_loglevel(NdbMgmHandle handle)
+{
+ SET_ERROR(handle, NDB_MGM_NO_ERROR, "Executing: ndb_mgm_get_clusterlog_loglevel");
+ int loglevel_count = CFG_MAX_LOGLEVEL - CFG_MIN_LOGLEVEL + 1 ;
+ static unsigned int loglevel[CFG_MAX_LOGLEVEL - CFG_MIN_LOGLEVEL + 1] = {0,0,0,0,0,0,0,0,0,0,0,0};
+ const ParserRow<ParserDummy> getloglevel_reply[] = {
+ MGM_CMD("get cluster loglevel", NULL, ""),
+ MGM_ARG(clusterlog_names[0], Int, Mandatory, ""),
+ MGM_ARG(clusterlog_names[1], Int, Mandatory, ""),
+ MGM_ARG(clusterlog_names[2], Int, Mandatory, ""),
+ MGM_ARG(clusterlog_names[3], Int, Mandatory, ""),
+ MGM_ARG(clusterlog_names[4], Int, Mandatory, ""),
+ MGM_ARG(clusterlog_names[5], Int, Mandatory, ""),
+ MGM_ARG(clusterlog_names[6], Int, Mandatory, ""),
+ MGM_ARG(clusterlog_names[7], Int, Mandatory, ""),
+ MGM_ARG(clusterlog_names[8], Int, Mandatory, ""),
+ MGM_ARG(clusterlog_names[9], Int, Mandatory, ""),
+ MGM_ARG(clusterlog_names[10], Int, Mandatory, ""),
+ MGM_ARG(clusterlog_names[11], Int, Mandatory, ""),
+ };
+ CHECK_HANDLE(handle, NULL);
+ CHECK_CONNECTED(handle, NULL);
+
+ Properties args;
+ const Properties *reply;
+ reply = ndb_mgm_call(handle, getloglevel_reply, "get cluster loglevel", &args);
+ CHECK_REPLY(reply, NULL);
+
+ for(int i=0; i < loglevel_count; i++) {
+ reply->get(clusterlog_names[i], &loglevel[i]);
+ }
+ return loglevel;
+}
+
extern "C"
int
ndb_mgm_set_clusterlog_loglevel(NdbMgmHandle handle, int nodeId,
@@ -1906,7 +2013,7 @@ ndb_mgm_get_configuration(NdbMgmHandle handle, unsigned int version) {
break;
void *tmp_data = malloc(base64_needed_decoded_length((size_t) (len - 1)));
- const int res = base64_decode(buf64, len-1, tmp_data);
+ const int res = base64_decode(buf64, len-1, tmp_data, NULL);
delete[] buf64;
UtilBuffer tmp;
tmp.append((void *) tmp_data, res);
@@ -2259,7 +2366,6 @@ ndb_mgm_check_connection(NdbMgmHandle handle){
SocketOutputStream out(handle->socket);
SocketInputStream in(handle->socket, handle->read_timeout);
char buf[32];
-
if (out.println("check connection"))
goto ndb_mgm_check_connection_error;
@@ -2469,7 +2575,6 @@ int ndb_mgm_end_session(NdbMgmHandle handle)
SocketInputStream in(handle->socket, handle->read_timeout);
char buf[32];
-
in.gets(buf, sizeof(buf));
DBUG_RETURN(0);
@@ -2527,4 +2632,104 @@ int ndb_mgm_get_version(NdbMgmHandle handle,
DBUG_RETURN(1);
}
+extern "C"
+Uint64
+ndb_mgm_get_session_id(NdbMgmHandle handle)
+{
+ Uint64 session_id=0;
+
+ DBUG_ENTER("ndb_mgm_get_session_id");
+ CHECK_HANDLE(handle, 0);
+ CHECK_CONNECTED(handle, 0);
+
+ Properties args;
+
+ const ParserRow<ParserDummy> reply[]= {
+ MGM_CMD("get session id reply", NULL, ""),
+ MGM_ARG("id", Int, Mandatory, "Node ID"),
+ MGM_END()
+ };
+
+ const Properties *prop;
+ prop = ndb_mgm_call(handle, reply, "get session id", &args);
+ CHECK_REPLY(prop, 0);
+
+ if(!prop->get("id",&session_id)){
+ fprintf(handle->errstream, "Unable to get session id\n");
+ return 0;
+ }
+
+ delete prop;
+ DBUG_RETURN(session_id);
+}
+
+extern "C"
+int
+ndb_mgm_get_session(NdbMgmHandle handle, Uint64 id,
+ struct NdbMgmSession *s, int *len)
+{
+ int retval= 0;
+ DBUG_ENTER("ndb_mgm_get_session");
+ CHECK_HANDLE(handle, 0);
+ CHECK_CONNECTED(handle, 0);
+
+ Properties args;
+ args.put("id", id);
+
+ const ParserRow<ParserDummy> reply[]= {
+ MGM_CMD("get session reply", NULL, ""),
+ MGM_ARG("id", Int, Mandatory, "Node ID"),
+ MGM_ARG("m_stopSelf", Int, Optional, "m_stopSelf"),
+ MGM_ARG("m_stop", Int, Optional, "stop session"),
+ MGM_ARG("nodeid", Int, Optional, "allocated node id"),
+ MGM_ARG("parser_buffer_len", Int, Optional, "waiting in buffer"),
+ MGM_ARG("parser_status", Int, Optional, "parser status"),
+ MGM_END()
+ };
+
+ const Properties *prop;
+ prop = ndb_mgm_call(handle, reply, "get session", &args);
+ CHECK_REPLY(prop, 0);
+
+ Uint64 r_id;
+ int rlen= 0;
+
+ if(!prop->get("id",&r_id)){
+ fprintf(handle->errstream, "Unable to get session id\n");
+ goto err;
+ }
+
+ s->id= r_id;
+ rlen+=sizeof(s->id);
+
+ if(prop->get("m_stopSelf",&(s->m_stopSelf)))
+ rlen+=sizeof(s->m_stopSelf);
+ else
+ goto err;
+
+ if(prop->get("m_stop",&(s->m_stop)))
+ rlen+=sizeof(s->m_stop);
+ else
+ goto err;
+
+ if(prop->get("nodeid",&(s->nodeid)))
+ rlen+=sizeof(s->nodeid);
+ else
+ goto err;
+
+ if(prop->get("parser_buffer_len",&(s->parser_buffer_len)))
+ {
+ rlen+=sizeof(s->parser_buffer_len);
+ if(prop->get("parser_status",&(s->parser_status)))
+ rlen+=sizeof(s->parser_status);
+ }
+
+ *len= rlen;
+ retval= 1;
+
+err:
+ delete prop;
+ DBUG_RETURN(retval);
+}
+
template class Vector<const ParserRow<ParserDummy>*>;
diff --git a/storage/ndb/src/mgmclient/CommandInterpreter.cpp b/storage/ndb/src/mgmclient/CommandInterpreter.cpp
index 948bad9c48f..8bff874a97a 100644
--- a/storage/ndb/src/mgmclient/CommandInterpreter.cpp
+++ b/storage/ndb/src/mgmclient/CommandInterpreter.cpp
@@ -48,11 +48,11 @@ public:
*
* @return true until quit/bye/exit has been typed
*/
- int execute(const char *_line, int _try_reconnect=-1, int *error= 0);
+ int execute(const char *_line, int _try_reconnect=-1, bool interactive=1, int *error= 0);
private:
void printError();
- int execute_impl(const char *_line);
+ int execute_impl(const char *_line, bool interactive=1);
/**
* Analyse the command line, after the first token.
@@ -61,10 +61,11 @@ private:
* command will be sent to all DB processes.
* @param allAfterFirstToken: What the client gave after the
* first token on the command line
+ * @return: 0 if analyseAfterFirstToken succeeds, otherwise -1
*/
- void analyseAfterFirstToken(int processId, char* allAfterFirstTokenCstr);
+ int analyseAfterFirstToken(int processId, char* allAfterFirstTokenCstr);
- void executeCommand(Vector<BaseString> &command_list,
+ int executeCommand(Vector<BaseString> &command_list,
unsigned command_pos,
int *node_ids, int no_of_nodes);
/**
@@ -90,54 +91,54 @@ private:
* this case "22". Each function is responsible to check the parameters
* argument.
*/
- void executeHelp(char* parameters);
- void executeShow(char* parameters);
- void executeConnect(char* parameters);
- void executePurge(char* parameters);
+ int executeHelp(char* parameters);
+ int executeShow(char* parameters);
+ int executePurge(char* parameters);
+ int executeConnect(char* parameters, bool interactive);
int executeShutdown(char* parameters);
void executeRun(char* parameters);
void executeInfo(char* parameters);
void executeClusterLog(char* parameters);
public:
- void executeStop(int processId, const char* parameters, bool all);
- void executeStop(Vector<BaseString> &command_list, unsigned command_pos,
+ int executeStop(int processId, const char* parameters, bool all);
+ int executeEnterSingleUser(char* parameters);
+ int executeExitSingleUser(char* parameters);
+ int executeStart(int processId, const char* parameters, bool all);
+ int executeRestart(int processId, const char* parameters, bool all);
+ int executeLogLevel(int processId, const char* parameters, bool all);
+ int executeError(int processId, const char* parameters, bool all);
+ int executeLog(int processId, const char* parameters, bool all);
+ int executeLogIn(int processId, const char* parameters, bool all);
+ int executeLogOut(int processId, const char* parameters, bool all);
+ int executeLogOff(int processId, const char* parameters, bool all);
+ int executeTestOn(int processId, const char* parameters, bool all);
+ int executeTestOff(int processId, const char* parameters, bool all);
+ int executeSet(int processId, const char* parameters, bool all);
+ int executeGetStat(int processId, const char* parameters, bool all);
+ int executeStatus(int processId, const char* parameters, bool all);
+ int executeEventReporting(int processId, const char* parameters, bool all);
+ int executeDumpState(int processId, const char* parameters, bool all);
+ int executeStartBackup(char * parameters);
+ int executeAbortBackup(char * parameters);
+ int executeStop(Vector<BaseString> &command_list, unsigned command_pos,
int *node_ids, int no_of_nodes);
- void executeEnterSingleUser(char* parameters);
- void executeExitSingleUser(char* parameters);
- void executeStart(int processId, const char* parameters, bool all);
- void executeRestart(int processId, const char* parameters, bool all);
- void executeRestart(Vector<BaseString> &command_list, unsigned command_pos,
+ int executeRestart(Vector<BaseString> &command_list, unsigned command_pos,
int *node_ids, int no_of_nodes);
- void executeLogLevel(int processId, const char* parameters, bool all);
- void executeError(int processId, const char* parameters, bool all);
- void executeLog(int processId, const char* parameters, bool all);
- void executeLogIn(int processId, const char* parameters, bool all);
- void executeLogOut(int processId, const char* parameters, bool all);
- void executeLogOff(int processId, const char* parameters, bool all);
- void executeTestOn(int processId, const char* parameters, bool all);
- void executeTestOff(int processId, const char* parameters, bool all);
- void executeSet(int processId, const char* parameters, bool all);
- void executeGetStat(int processId, const char* parameters, bool all);
- void executeStatus(int processId, const char* parameters, bool all);
- void executeEventReporting(int processId, const char* parameters, bool all);
- void executeDumpState(int processId, const char* parameters, bool all);
- int executeStartBackup(char * parameters);
- void executeAbortBackup(char * parameters);
-
- void executeRep(char* parameters);
+
+ int executeRep(char* parameters);
void executeCpc(char * parameters);
public:
- bool connect();
+ bool connect(bool interactive);
bool disconnect();
/**
* A execute function definition
*/
public:
- typedef void (CommandInterpreter::* ExecuteFunction)(int processId,
+ typedef int (CommandInterpreter::* ExecuteFunction)(int processId,
const char * param,
bool all);
@@ -149,7 +150,7 @@ private:
/**
*
*/
- void executeForAll(const char * cmd,
+ int executeForAll(const char * cmd,
ExecuteFunction fun,
const char * param);
@@ -186,9 +187,9 @@ Ndb_mgmclient::~Ndb_mgmclient()
{
delete m_cmd;
}
-int Ndb_mgmclient::execute(const char *_line, int _try_reconnect, int *error)
+int Ndb_mgmclient::execute(const char *_line, int _try_reconnect, bool interactive, int *error)
{
- return m_cmd->execute(_line,_try_reconnect,error);
+ return m_cmd->execute(_line,_try_reconnect,interactive, error);
}
int
Ndb_mgmclient::disconnect()
@@ -230,7 +231,7 @@ extern "C" {
#include <util/InputStream.hpp>
#include <util/OutputStream.hpp>
-int Ndb_mgmclient::execute(int argc, char** argv, int _try_reconnect, int *error)
+int Ndb_mgmclient::execute(int argc, char** argv, int _try_reconnect, bool interactive, int *error)
{
if (argc <= 0)
return 0;
@@ -239,7 +240,7 @@ int Ndb_mgmclient::execute(int argc, char** argv, int _try_reconnect, int *error
{
_line.appfmt(" %s", argv[i]);
}
- return m_cmd->execute(_line.c_str(),_try_reconnect, error);
+ return m_cmd->execute(_line.c_str(),_try_reconnect, interactive, error);
}
/*****************************************************************************
@@ -250,7 +251,7 @@ static const char* helpText =
" NDB Cluster -- Management Client -- Help\n"
"---------------------------------------------------------------------------\n"
"HELP Print help text\n"
-"HELP SHOW Help for SHOW command\n"
+"HELP COMMAND Print detailed help for COMMAND(e.g. SHOW)\n"
#ifdef VM_TRACE // DEBUG ONLY
"HELP DEBUG Help for debug compiled version\n"
#endif
@@ -267,10 +268,10 @@ static const char* helpText =
"CLUSTERLOG OFF [<severity>] ... Disable Cluster logging\n"
"CLUSTERLOG TOGGLE [<severity>] ... Toggle severity filter on/off\n"
"CLUSTERLOG INFO Print cluster log information\n"
-"<id> START Start DB node (started with -n)\n"
-"<id> RESTART [-n] [-i] Restart DB node\n"
-"<id> STOP Stop DB node\n"
-"ENTER SINGLE USER MODE <api-node> Enter single user mode\n"
+"<id> START Start data node (started with -n)\n"
+"<id> RESTART [-n] [-i] Restart data or management server node\n"
+"<id> STOP Stop data or management server node\n"
+"ENTER SINGLE USER MODE <id> Enter single user mode\n"
"EXIT SINGLE USER MODE Exit single user mode\n"
"<id> STATUS Print status\n"
"<id> CLUSTERLOG {<category>=<level>}+ Set log level for cluster log\n"
@@ -283,14 +284,296 @@ static const char* helpTextShow =
"---------------------------------------------------------------------------\n"
" NDB Cluster -- Management Client -- Help for SHOW command\n"
"---------------------------------------------------------------------------\n"
-"SHOW prints NDB Cluster information\n\n"
-"SHOW Print information about cluster\n"
+"SHOW Print information about cluster\n\n"
+"SHOW Print information about cluster.The status reported is from\n"
+" the perspective of the data nodes. API and Management Server nodes\n"
+" are only reported as connected once the data nodes have started.\n"
#if 0
"SHOW CONFIG Print configuration (in initial config file format)\n"
"SHOW PARAMETERS Print information about configuration parameters\n\n"
#endif
;
+static const char* helpTextHelp =
+"---------------------------------------------------------------------------\n"
+" NDB Cluster -- Management Client -- Help for HELP command\n"
+"---------------------------------------------------------------------------\n"
+"HELP List available commands of NDB Cluster Management Client\n\n"
+"HELP List available commands.\n"
+;
+
+static const char* helpTextBackup =
+"---------------------------------------------------------------------------\n"
+" NDB Cluster -- Management Client -- Help for BACKUP command\n"
+"---------------------------------------------------------------------------\n"
+"BACKUP A backup is a snapshot of the database at a given time. \n"
+" The backup consists of three main parts:\n\n"
+" Metadata: the names and definitions of all database tables. \n"
+" Table records: the data actually stored in the database tables \n"
+" at the time that the backup was made.\n"
+" Transaction log: a sequential record telling how \n"
+" and when data was stored in the database.\n\n"
+" Backups are stored on each data node in the cluster that \n"
+" participates in the backup.\n\n"
+" The cluster log records backup related events (such as \n"
+" backup started, aborted, finished).\n"
+;
+
+static const char* helpTextStartBackup =
+"---------------------------------------------------------------------------\n"
+" NDB Cluster -- Management Client -- Help for START BACKUP command\n"
+"---------------------------------------------------------------------------\n"
+"START BACKUP Start a cluster backup\n\n"
+"START BACKUP [NOWAIT | WAIT STARTED | WAIT COMPLETED]\n"
+" Start a backup for the cluster.\n"
+" Each backup gets an ID number that is reported to the\n"
+" user. This ID number can help you find the backup on the\n"
+" file system, or ABORT BACKUP if you wish to cancel a \n"
+" running backup.\n\n"
+" NOWAIT \n"
+" Start a cluster backup and return immediately.\n"
+" The management client will return control directly\n"
+" to the user without waiting for the backup\n"
+" to have started.\n"
+" The status of the backup is recorded in the Cluster log.\n"
+" WAIT STARTED\n"
+" Start a cluster backup and return until the backup has\n"
+" started. The management client will wait for the backup \n"
+" to have started before returning control to the user.\n"
+" WAIT COMPLETED\n"
+" Start a cluster backup and return until the backup has\n"
+" completed. The management client will wait for the backup\n"
+" to complete before returning control to the user.\n"
+;
+
+static const char* helpTextAbortBackup =
+"---------------------------------------------------------------------------\n"
+" NDB Cluster -- Management Client -- Help for ABORT BACKUP command\n"
+"---------------------------------------------------------------------------\n"
+"ABORT BACKUP Abort a cluster backup\n\n"
+"ABORT BACKUP <backup id> \n"
+" Abort a backup that is already in progress.\n"
+" The backup id can be seen in the cluster log or in the\n"
+" output of the START BACKUP command.\n"
+;
+
+static const char* helpTextShutdown =
+"---------------------------------------------------------------------------\n"
+" NDB Cluster -- Management Client -- Help for SHUTDOWN command\n"
+"---------------------------------------------------------------------------\n"
+"SHUTDOWN Shutdown the cluster\n\n"
+"SHUTDOWN Shutdown the data nodes and management nodes.\n"
+" MySQL Servers and NDBAPI nodes are currently not \n"
+" shut down by issuing this command.\n"
+;
+
+static const char* helpTextClusterlogOn =
+"---------------------------------------------------------------------------\n"
+" NDB Cluster -- Management Client -- Help for CLUSTERLOG ON command\n"
+"---------------------------------------------------------------------------\n"
+"CLUSTERLOG ON Enable Cluster logging\n\n"
+"CLUSTERLOG ON [<severity>] ... \n"
+" Turn the cluster log on.\n"
+" It tells management server which severity levels\n"
+" messages will be logged.\n\n"
+" <severity> can be any one of the following values:\n"
+" ALERT, CRITICAL, ERROR, WARNING, INFO, DEBUG.\n"
+;
+
+static const char* helpTextClusterlogOff =
+"---------------------------------------------------------------------------\n"
+" NDB Cluster -- Management Client -- Help for CLUSTERLOG OFF command\n"
+"---------------------------------------------------------------------------\n"
+"CLUSTERLOG OFF Disable Cluster logging\n\n"
+"CLUSTERLOG OFF [<severity>] ... \n"
+" Turn the cluster log off.\n"
+" It tells management server which serverity\n"
+" levels logging will be disabled.\n\n"
+" <severity> can be any one of the following values:\n"
+" ALERT, CRITICAL, ERROR, WARNING, INFO, DEBUG.\n"
+;
+
+static const char* helpTextClusterlogToggle =
+"---------------------------------------------------------------------------\n"
+" NDB Cluster -- Management Client -- Help for CLUSTERLOG TOGGLE command\n"
+"---------------------------------------------------------------------------\n"
+"CLUSTERLOG TOGGLE Toggle severity filter on/off\n\n"
+"CLUSTERLOG TOGGLE [<severity>] ... \n"
+" Toggle serverity filter on/off.\n"
+" If a serverity level is already enabled,then it will\n"
+" be disabled after you use the command,vice versa.\n\n"
+" <severity> can be any one of the following values:\n"
+" ALERT, CRITICAL, ERROR, WARNING, INFO, DEBUG.\n"
+;
+
+static const char* helpTextClusterlogInfo =
+"---------------------------------------------------------------------------\n"
+" NDB Cluster -- Management Client -- Help for CLUSTERLOG INFO command\n"
+"---------------------------------------------------------------------------\n"
+"CLUSTERLOG INFO Print cluster log information\n\n"
+"CLUSTERLOG INFO Display which severity levels have been enabled,\n"
+" see HELP CLUSTERLOG for list of the severity levels.\n"
+;
+
+static const char* helpTextStart =
+"---------------------------------------------------------------------------\n"
+" NDB Cluster -- Management Client -- Help for START command\n"
+"---------------------------------------------------------------------------\n"
+"START Start data node (started with -n)\n\n"
+"<id> START Start the data node identified by <id>.\n"
+" Only starts data nodes that have not\n"
+" yet joined the cluster. These are nodes\n"
+" launched or restarted with the -n(--nostart)\n"
+" option.\n\n"
+" It does not launch the ndbd process on a remote\n"
+" machine.\n"
+;
+
+static const char* helpTextRestart =
+"---------------------------------------------------------------------------\n"
+" NDB Cluster -- Management Client -- Help for RESTART command\n"
+"---------------------------------------------------------------------------\n"
+"RESTART Restart data or management server node\n\n"
+"<id> RESTART [-n] [-i] \n"
+" Restart the data or management node <id>(or All data nodes).\n\n"
+" -n (--nostart) restarts the node but does not\n"
+" make it join the cluster. Use '<id> START' to\n"
+" join the node to the cluster.\n\n"
+" -i (--initial) perform initial start.\n"
+" This cleans the file system (ndb_<id>_fs)\n"
+" and the node will copy data from another node\n"
+" in the same node group during start up.\n\n"
+" Consult the documentation before using -i.\n\n"
+" INCORRECT USE OF -i WILL CAUSE DATA LOSS!\n"
+;
+
+static const char* helpTextStop =
+"---------------------------------------------------------------------------\n"
+" NDB Cluster -- Management Client -- Help for STOP command\n"
+"---------------------------------------------------------------------------\n"
+"STOP Stop data or management server node\n\n"
+"<id> STOP Stop the data or management server node <id>.\n\n"
+" ALL STOP will just stop all data nodes.\n\n"
+" If you desire to also shut down management servers,\n"
+" use SHUTDOWN instead.\n"
+;
+
+static const char* helpTextEnterSingleUserMode =
+"---------------------------------------------------------------------------\n"
+" NDB Cluster -- Management Client -- Help for ENTER SINGLE USER MODE command\n"
+"---------------------------------------------------------------------------\n"
+"ENTER SINGLE USER MODE Enter single user mode\n\n"
+"ENTER SINGLE USER MODE <id> \n"
+" Enters single-user mode, whereby only the MySQL Server or NDBAPI\n"
+" node identified by <id> is allowed to access the database. \n"
+;
+
+static const char* helpTextExitSingleUserMode =
+"---------------------------------------------------------------------------\n"
+" NDB Cluster -- Management Client -- Help for EXIT SINGLE USER MODE command\n"
+"---------------------------------------------------------------------------\n"
+"EXIT SINGLE USER MODE Exit single user mode\n\n"
+"EXIT SINGLE USER MODE \n"
+" Exits single-user mode, allowing all SQL nodes \n"
+" (that is, all running mysqld processes) to access the database. \n"
+;
+
+static const char* helpTextStatus =
+"---------------------------------------------------------------------------\n"
+" NDB Cluster -- Management Client -- Help for STATUS command\n"
+"---------------------------------------------------------------------------\n"
+"STATUS Print status\n\n"
+"<id> STATUS Displays status information for the data node <id>\n"
+" or for All data nodes. \n\n"
+" e.g.\n"
+" ALL STATUS\n"
+" 1 STATUS\n\n"
+" When a node is starting, the start phase will be\n"
+" listed.\n\n"
+" Start Phase Meaning\n"
+" 1 Clear the cluster file system(ndb_<id>_fs). \n"
+" This stage occurs only when the --initial option \n"
+" has been specified.\n"
+" 2 This stage sets up Cluster connections, establishes \n"
+" inter-node communications and starts Cluster heartbeats.\n"
+" 3 The arbitrator node is elected.\n"
+" 4 Initializes a number of internal cluster variables.\n"
+" 5 For an initial start or initial node restart,\n"
+" the redo log files are created.\n"
+" 6 If this is an initial start, create internal system tables.\n"
+" 7 Update internal variables. \n"
+" 8 In a system restart, rebuild all indexes.\n"
+" 9 Update internal variables. \n"
+" 10 The node can be connected by APIs and can receive events.\n"
+" 11 At this point,event delivery is handed over to\n"
+" the node joining the cluster.\n"
+"(see manual for more information)\n"
+;
+
+static const char* helpTextClusterlog =
+"---------------------------------------------------------------------------\n"
+" NDB Cluster -- Management Client -- Help for CLUSTERLOG command\n"
+"---------------------------------------------------------------------------\n"
+"CLUSTERLOG Set log level for cluster log\n\n"
+" <id> CLUSTERLOG {<category>=<level>}+ \n"
+" Logs <category> events with priority less than \n"
+" or equal to <level> in the cluster log.\n\n"
+" <category> can be any one of the following values:\n"
+" STARTUP, SHUTDOWN, STATISTICS, CHECKPOINT, NODERESTART,\n"
+" CONNECTION, ERROR, INFO, CONGESTION, DEBUG, or BACKUP. \n\n"
+" <level> is represented by one of the numbers \n"
+" from 1 to 15 inclusive, where 1 indicates 'most important' \n"
+" and 15 'least important'.\n\n"
+" <severity> can be any one of the following values:\n"
+" ALERT, CRITICAL, ERROR, WARNING, INFO, DEBUG.\n"
+;
+
+
+static const char* helpTextPurgeStaleSessions =
+"---------------------------------------------------------------------------\n"
+" NDB Cluster -- Management Client -- Help for PURGE STALE SESSIONS command\n"
+"---------------------------------------------------------------------------\n"
+"PURGE STALE SESSIONS Reset reserved nodeid's in the mgmt server\n\n"
+"PURGE STALE SESSIONS \n"
+" Running this statement forces all reserved \n"
+" node IDs to be checked; any that are not \n"
+" being used by nodes acutally connected to \n"
+" the cluster are then freed.\n\n"
+" This command is not normally needed, but may be\n"
+" required in some situations where failed nodes \n"
+" cannot rejoin the cluster due to failing to\n"
+" allocate a node id.\n"
+;
+
+static const char* helpTextConnect =
+"---------------------------------------------------------------------------\n"
+" NDB Cluster -- Management Client -- Help for CONNECT command\n"
+"---------------------------------------------------------------------------\n"
+"CONNECT Connect to management server (reconnect if already connected)\n\n"
+"CONNECT [<connectstring>] \n"
+" Connect to management server.\n"
+" The optional parameter connectstring specifies the \n"
+" connect string to user.\n\n"
+" A connect string may be:\n"
+" mgm-server\n"
+" mgm-server:port\n"
+" mgm1:port,mgm2:port\n"
+" With multiple management servers comma separated.\n"
+" The management client with try to connect to the \n"
+" management servers in the order they are listed.\n\n"
+" If no connect string is specified, the default \n"
+" is used. \n"
+;
+
+static const char* helpTextQuit =
+"---------------------------------------------------------------------------\n"
+" NDB Cluster -- Management Client -- Help for QUIT command\n"
+"---------------------------------------------------------------------------\n"
+"QUIT Quit management client\n\n"
+"QUIT Terminates the management client. \n"
+;
+
+
#ifdef VM_TRACE // DEBUG ONLY
static const char* helpTextDebug =
"---------------------------------------------------------------------------\n"
@@ -315,6 +598,40 @@ static const char* helpTextDebug =
;
#endif
+struct {
+ const char *cmd;
+ const char * help;
+}help_items[]={
+ {"SHOW", helpTextShow},
+ {"HELP", helpTextHelp},
+ {"BACKUP", helpTextBackup},
+ {"START BACKUP", helpTextStartBackup},
+ {"START BACKUP NOWAIT", helpTextStartBackup},
+ {"START BACKUP WAIT STARTED", helpTextStartBackup},
+ {"START BACKUP WAIT", helpTextStartBackup},
+ {"START BACKUP WAIT COMPLETED", helpTextStartBackup},
+ {"ABORT BACKUP", helpTextAbortBackup},
+ {"SHUTDOWN", helpTextShutdown},
+ {"CLUSTERLOG ON", helpTextClusterlogOn},
+ {"CLUSTERLOG OFF", helpTextClusterlogOff},
+ {"CLUSTERLOG TOGGLE", helpTextClusterlogToggle},
+ {"CLUSTERLOG INFO", helpTextClusterlogInfo},
+ {"START", helpTextStart},
+ {"RESTART", helpTextRestart},
+ {"STOP", helpTextStop},
+ {"ENTER SINGLE USER MODE", helpTextEnterSingleUserMode},
+ {"EXIT SINGLE USER MODE", helpTextExitSingleUserMode},
+ {"STATUS", helpTextStatus},
+ {"CLUSTERLOG", helpTextClusterlog},
+ {"PURGE STALE SESSIONS", helpTextPurgeStaleSessions},
+ {"CONNECT", helpTextConnect},
+ {"QUIT", helpTextQuit},
+#ifdef VM_TRACE // DEBUG ONLY
+ {"DEBUG", helpTextDebug},
+#endif //VM_TRACE
+ {NULL, NULL}
+};
+
static bool
convert(const char* s, int& val) {
@@ -345,7 +662,7 @@ CommandInterpreter::CommandInterpreter(const char *_host,int verbose)
{
m_constr= _host;
m_connected= false;
- m_event_thread= 0;
+ m_event_thread= NULL;
try_reconnect = 0;
m_print_mutex= NdbMutex_Create();
}
@@ -435,7 +752,7 @@ event_thread_run(void* p)
}
bool
-CommandInterpreter::connect()
+CommandInterpreter::connect(bool interactive)
{
DBUG_ENTER("CommandInterpreter::connect");
@@ -447,10 +764,12 @@ CommandInterpreter::connect()
ndbout_c("Cannot create handle to management server.");
exit(-1);
}
- m_mgmsrv2 = ndb_mgm_create_handle();
- if(m_mgmsrv2 == NULL) {
- ndbout_c("Cannot create 2:nd handle to management server.");
- exit(-1);
+ if (interactive) {
+ m_mgmsrv2 = ndb_mgm_create_handle();
+ if(m_mgmsrv2 == NULL) {
+ ndbout_c("Cannot create 2:nd handle to management server.");
+ exit(-1);
+ }
}
if (ndb_mgm_set_connectstring(m_mgmsrv, m_constr))
@@ -464,62 +783,64 @@ CommandInterpreter::connect()
const char *host= ndb_mgm_get_connected_host(m_mgmsrv);
unsigned port= ndb_mgm_get_connected_port(m_mgmsrv);
- BaseString constr;
- constr.assfmt("%s:%d",host,port);
- if(!ndb_mgm_set_connectstring(m_mgmsrv2, constr.c_str()) &&
- !ndb_mgm_connect(m_mgmsrv2, try_reconnect-1, 5, 1))
- {
- DBUG_PRINT("info",("2:ndb connected to Management Server ok at: %s:%d",
- host, port));
- assert(m_event_thread == 0);
- assert(do_event_thread == 0);
- do_event_thread= 0;
- struct event_thread_param p;
- p.m= &m_mgmsrv2;
- p.p= &m_print_mutex;
- m_event_thread = NdbThread_Create(event_thread_run,
- (void**)&p,
- 32768,
- "CommandInterpreted_event_thread",
- NDB_THREAD_PRIO_LOW);
- if (m_event_thread != 0)
- {
- DBUG_PRINT("info",("Thread created ok, waiting for started..."));
- int iter= 1000; // try for 30 seconds
- while(do_event_thread == 0 &&
- iter-- > 0)
- NdbSleep_MilliSleep(30);
- }
- if (m_event_thread == 0 ||
- do_event_thread == 0 ||
- do_event_thread == -1)
+ if (interactive) {
+ BaseString constr;
+ constr.assfmt("%s:%d",host,port);
+ if(!ndb_mgm_set_connectstring(m_mgmsrv2, constr.c_str()) &&
+ !ndb_mgm_connect(m_mgmsrv2, try_reconnect-1, 5, 1))
{
- DBUG_PRINT("info",("Warning, event thread startup failed, "
- "degraded printouts as result, errno=%d",
- errno));
- printf("Warning, event thread startup failed, "
- "degraded printouts as result, errno=%d\n", errno);
+ DBUG_PRINT("info",("2:ndb connected to Management Server ok at: %s:%d",
+ host, port));
+ assert(m_event_thread == NULL);
+ assert(do_event_thread == 0);
do_event_thread= 0;
+ struct event_thread_param p;
+ p.m= &m_mgmsrv2;
+ p.p= &m_print_mutex;
+ m_event_thread = NdbThread_Create(event_thread_run,
+ (void**)&p,
+ 32768,
+ "CommandInterpreted_event_thread",
+ NDB_THREAD_PRIO_LOW);
if (m_event_thread)
{
- void *res;
- NdbThread_WaitFor(m_event_thread, &res);
- NdbThread_Destroy(&m_event_thread);
+ DBUG_PRINT("info",("Thread created ok, waiting for started..."));
+ int iter= 1000; // try for 30 seconds
+ while(do_event_thread == 0 &&
+ iter-- > 0)
+ NdbSleep_MilliSleep(30);
+ }
+ if (m_event_thread == NULL ||
+ do_event_thread == 0 ||
+ do_event_thread == -1)
+ {
+ DBUG_PRINT("info",("Warning, event thread startup failed, "
+ "degraded printouts as result, errno=%d",
+ errno));
+ printf("Warning, event thread startup failed, "
+ "degraded printouts as result, errno=%d\n", errno);
+ do_event_thread= 0;
+ if (m_event_thread)
+ {
+ void *res;
+ NdbThread_WaitFor(m_event_thread, &res);
+ NdbThread_Destroy(&m_event_thread);
+ }
+ ndb_mgm_disconnect(m_mgmsrv2);
}
- ndb_mgm_disconnect(m_mgmsrv2);
}
- }
- else
- {
- DBUG_PRINT("warning",
- ("Could not do 2:nd connect to mgmtserver for event listening"));
- DBUG_PRINT("info", ("code: %d, msg: %s",
- ndb_mgm_get_latest_error(m_mgmsrv2),
- ndb_mgm_get_latest_error_msg(m_mgmsrv2)));
- printf("Warning, event connect failed, degraded printouts as result\n");
- printf("code: %d, msg: %s\n",
- ndb_mgm_get_latest_error(m_mgmsrv2),
- ndb_mgm_get_latest_error_msg(m_mgmsrv2));
+ else
+ {
+ DBUG_PRINT("warning",
+ ("Could not do 2:nd connect to mgmtserver for event listening"));
+ DBUG_PRINT("info", ("code: %d, msg: %s",
+ ndb_mgm_get_latest_error(m_mgmsrv2),
+ ndb_mgm_get_latest_error_msg(m_mgmsrv2)));
+ printf("Warning, event connect failed, degraded printouts as result\n");
+ printf("code: %d, msg: %s\n",
+ ndb_mgm_get_latest_error(m_mgmsrv2),
+ ndb_mgm_get_latest_error_msg(m_mgmsrv2));
+ }
}
m_connected= true;
DBUG_PRINT("info",("Connected to Management Server at: %s:%d", host, port));
@@ -542,7 +863,7 @@ CommandInterpreter::disconnect()
do_event_thread= 0;
NdbThread_WaitFor(m_event_thread, &res);
NdbThread_Destroy(&m_event_thread);
- m_event_thread= 0;
+ m_event_thread= NULL;
ndb_mgm_destroy_handle(&m_mgmsrv2);
}
if (m_connected)
@@ -558,11 +879,11 @@ CommandInterpreter::disconnect()
int
CommandInterpreter::execute(const char *_line, int _try_reconnect,
- int *error)
+ bool interactive, int *error)
{
if (_try_reconnect >= 0)
try_reconnect=_try_reconnect;
- int result= execute_impl(_line);
+ int result= execute_impl(_line, interactive);
if (error)
*error= m_error;
@@ -577,7 +898,7 @@ invalid_command(const char *cmd)
}
int
-CommandInterpreter::execute_impl(const char *_line)
+CommandInterpreter::execute_impl(const char *_line, bool interactive)
{
DBUG_ENTER("CommandInterpreter::execute_impl");
DBUG_PRINT("enter",("line=\"%s\"",_line));
@@ -585,6 +906,7 @@ CommandInterpreter::execute_impl(const char *_line)
char * line;
if(_line == NULL) {
+ m_error = -1;
DBUG_RETURN(false);
}
line = my_strdup(_line,MYF(MY_WME));
@@ -622,16 +944,17 @@ CommandInterpreter::execute_impl(const char *_line)
if (strcasecmp(firstToken, "HELP") == 0 ||
strcasecmp(firstToken, "?") == 0) {
- executeHelp(allAfterFirstToken);
+ m_error = executeHelp(allAfterFirstToken);
DBUG_RETURN(true);
}
else if (strcasecmp(firstToken, "CONNECT") == 0) {
- executeConnect(allAfterFirstToken);
+ m_error = executeConnect(allAfterFirstToken, interactive);
DBUG_RETURN(true);
}
else if (strcasecmp(firstToken, "SLEEP") == 0) {
if (allAfterFirstToken)
- sleep(atoi(allAfterFirstToken));
+ if (sleep(atoi(allAfterFirstToken)) != 0 )
+ m_error = -1;
DBUG_RETURN(true);
}
else if((strcasecmp(firstToken, "QUIT") == 0 ||
@@ -641,12 +964,20 @@ CommandInterpreter::execute_impl(const char *_line)
DBUG_RETURN(false);
}
- if (!connect())
+ if (!connect(interactive)){
+ m_error = -1;
DBUG_RETURN(true);
+ }
+
+ if (ndb_mgm_check_connection(m_mgmsrv))
+ {
+ disconnect();
+ connect(interactive);
+ }
if (strcasecmp(firstToken, "SHOW") == 0) {
Guard g(m_print_mutex);
- executeShow(allAfterFirstToken);
+ m_error = executeShow(allAfterFirstToken);
DBUG_RETURN(true);
}
else if (strcasecmp(firstToken, "SHUTDOWN") == 0) {
@@ -666,29 +997,29 @@ CommandInterpreter::execute_impl(const char *_line)
else if(strcasecmp(firstToken, "ABORT") == 0 &&
allAfterFirstToken != NULL &&
strncasecmp(allAfterFirstToken, "BACKUP", sizeof("BACKUP") - 1) == 0){
- executeAbortBackup(allAfterFirstToken);
+ m_error = executeAbortBackup(allAfterFirstToken);
DBUG_RETURN(true);
}
else if (strcasecmp(firstToken, "PURGE") == 0) {
- executePurge(allAfterFirstToken);
+ m_error = executePurge(allAfterFirstToken);
DBUG_RETURN(true);
- }
+ }
else if(strcasecmp(firstToken, "ENTER") == 0 &&
allAfterFirstToken != NULL &&
strncasecmp(allAfterFirstToken, "SINGLE USER MODE ",
sizeof("SINGLE USER MODE") - 1) == 0){
- executeEnterSingleUser(allAfterFirstToken);
+ m_error = executeEnterSingleUser(allAfterFirstToken);
DBUG_RETURN(true);
}
else if(strcasecmp(firstToken, "EXIT") == 0 &&
allAfterFirstToken != NULL &&
strncasecmp(allAfterFirstToken, "SINGLE USER MODE ",
sizeof("SINGLE USER MODE") - 1) == 0){
- executeExitSingleUser(allAfterFirstToken);
+ m_error = executeExitSingleUser(allAfterFirstToken);
DBUG_RETURN(true);
}
else if (strcasecmp(firstToken, "ALL") == 0) {
- analyseAfterFirstToken(-1, allAfterFirstToken);
+ m_error = analyseAfterFirstToken(-1, allAfterFirstToken);
} else {
/**
* First tokens should be digits, node ID's
@@ -700,7 +1031,7 @@ CommandInterpreter::execute_impl(const char *_line)
int node_id;
if (convert(command_list[pos].c_str(), node_id))
{
- if (node_id <= 0) {
+ if (node_id <= 0 || node_id > MAX_NODES) {
ndbout << "Invalid node ID: " << command_list[pos].c_str()
<< "." << endl;
DBUG_RETURN(true);
@@ -715,20 +1046,22 @@ CommandInterpreter::execute_impl(const char *_line)
{
/* No digit found */
invalid_command(_line);
+ m_error = -1;
DBUG_RETURN(true);
}
if (pos == command_list.size())
{
/* No command found */
invalid_command(_line);
+ m_error = -1;
DBUG_RETURN(true);
}
if (no_of_nodes == 1)
{
- analyseAfterFirstToken(node_ids[0], allAfterFirstToken);
+ m_error = analyseAfterFirstToken(node_ids[0], allAfterFirstToken);
DBUG_RETURN(true);
}
- executeCommand(command_list, pos, node_ids, no_of_nodes);
+ m_error = executeCommand(command_list, pos, node_ids, no_of_nodes);
DBUG_RETURN(true);
}
DBUG_RETURN(true);
@@ -762,14 +1095,15 @@ static const CommandInterpreter::CommandFunctionPair commands[] = {
//*****************************************************************************
//*****************************************************************************
-void
+int
CommandInterpreter::analyseAfterFirstToken(int processId,
char* allAfterFirstToken) {
+ int retval = 0;
if (emptyString(allAfterFirstToken)) {
ndbout << "Expected a command after "
<< ((processId == -1) ? "ALL." : "node ID.") << endl;
- return;
+ return -1;
}
char* secondToken = strtok(allAfterFirstToken, " ");
@@ -788,36 +1122,39 @@ CommandInterpreter::analyseAfterFirstToken(int processId,
if(fun == 0){
invalid_command(secondToken);
- return;
+ return -1;
}
if(processId == -1){
- executeForAll(command, fun, allAfterSecondToken);
+ retval = executeForAll(command, fun, allAfterSecondToken);
} else {
- (this->*fun)(processId, allAfterSecondToken, false);
+ retval = (this->*fun)(processId, allAfterSecondToken, false);
}
ndbout << endl;
+ return retval;
}
-void
+int
CommandInterpreter::executeCommand(Vector<BaseString> &command_list,
unsigned command_pos,
int *node_ids, int no_of_nodes)
{
const char *cmd= command_list[command_pos].c_str();
+ int retval = 0;
+
if (strcasecmp("STOP", cmd) == 0)
{
- executeStop(command_list, command_pos+1, node_ids, no_of_nodes);
- return;
+ retval = executeStop(command_list, command_pos+1, node_ids, no_of_nodes);
+ return retval;
}
if (strcasecmp("RESTART", cmd) == 0)
{
- executeRestart(command_list, command_pos+1, node_ids, no_of_nodes);
- return;
+ retval = executeRestart(command_list, command_pos+1, node_ids, no_of_nodes);
+ return retval;
}
ndbout_c("Invalid command: '%s' after multi node id list. "
"Expected STOP or RESTART.", cmd);
- return;
+ return -1;
}
/**
@@ -858,18 +1195,20 @@ get_next_nodeid(struct ndb_mgm_cluster_state *cl,
return 0;
}
-void
+int
CommandInterpreter::executeForAll(const char * cmd, ExecuteFunction fun,
const char * allAfterSecondToken)
{
int nodeId = 0;
+ int retval = 0;
+
if(strcasecmp(cmd, "STOP") == 0) {
ndbout_c("Executing STOP on all nodes.");
- (this->*fun)(nodeId, allAfterSecondToken, true);
+ retval = (this->*fun)(nodeId, allAfterSecondToken, true);
} else if(strcasecmp(cmd, "RESTART") == 0) {
ndbout_c("Executing RESTART on all nodes.");
ndbout_c("Starting shutdown. This may take a while. Please wait...");
- (this->*fun)(nodeId, allAfterSecondToken, true);
+ retval = (this->*fun)(nodeId, allAfterSecondToken, true);
ndbout_c("Trying to start all nodes of system.");
ndbout_c("Use ALL STATUS to see the system start-up phases.");
} else {
@@ -878,12 +1217,13 @@ CommandInterpreter::executeForAll(const char * cmd, ExecuteFunction fun,
if(cl == 0){
ndbout_c("Unable get status from management server");
printError();
- return;
+ return -1;
}
NdbAutoPtr<char> ap1((char*)cl);
while(get_next_nodeid(cl, &nodeId, NDB_MGM_NODE_TYPE_NDB))
- (this->*fun)(nodeId, allAfterSecondToken, true);
+ retval = (this->*fun)(nodeId, allAfterSecondToken, true);
}
+ return retval;
}
//*****************************************************************************
@@ -953,7 +1293,7 @@ CommandInterpreter::parseBlockSpecification(const char* allAfterLog,
/*****************************************************************************
* HELP
*****************************************************************************/
-void
+int
CommandInterpreter::executeHelp(char* parameters)
{
if (emptyString(parameters)) {
@@ -978,15 +1318,23 @@ CommandInterpreter::executeHelp(char* parameters)
ndbout << "<level> = " << "0 - 15" << endl;
ndbout << "<id> = " << "ALL | Any database node id" << endl;
ndbout << endl;
- } else if (strcasecmp(parameters, "SHOW") == 0) {
- ndbout << helpTextShow;
-#ifdef VM_TRACE // DEBUG ONLY
- } else if (strcasecmp(parameters, "DEBUG") == 0) {
- ndbout << helpTextDebug;
-#endif
+ ndbout << "For detailed help on COMMAND, use HELP COMMAND." << endl;
} else {
- invalid_command(parameters);
+ int i = 0;
+ for (i = 0; help_items[i].cmd != NULL; i++)
+ {
+ if (strcasecmp(parameters, help_items[i].cmd) == 0)
+ {
+ ndbout << help_items[i].help;
+ break;
+ }
+ }
+ if (help_items[i].cmd == NULL){
+ ndbout << "No help for " << parameters << " available" << endl;
+ return -1;
+ }
}
+ return 0;
}
@@ -1109,7 +1457,7 @@ print_nodes(ndb_mgm_cluster_state *state, ndb_mgm_configuration_iterator *it,
ndbout << endl;
}
-void
+int
CommandInterpreter::executePurge(char* parameters)
{
int command_ok= 0;
@@ -1128,7 +1476,7 @@ CommandInterpreter::executePurge(char* parameters)
if (!command_ok) {
ndbout_c("Unexpected command, expected: PURGE STALE SESSIONS");
- return;
+ return -1;
}
int i;
@@ -1136,7 +1484,7 @@ CommandInterpreter::executePurge(char* parameters)
if (ndb_mgm_purge_stale_sessions(m_mgmsrv, &str)) {
ndbout_c("Command failed");
- return;
+ return -1;
}
if (str) {
ndbout_c("Purged sessions with node id's: %s", str);
@@ -1146,9 +1494,10 @@ CommandInterpreter::executePurge(char* parameters)
{
ndbout_c("No sessions purged");
}
+ return 0;
}
-void
+int
CommandInterpreter::executeShow(char* parameters)
{
int i;
@@ -1157,7 +1506,7 @@ CommandInterpreter::executeShow(char* parameters)
if(state == NULL) {
ndbout_c("Could not get status");
printError();
- return;
+ return -1;
}
NdbAutoPtr<char> ap1((char*)state);
@@ -1165,7 +1514,7 @@ CommandInterpreter::executeShow(char* parameters)
if(conf == 0){
ndbout_c("Could not get configuration");
printError();
- return;
+ return -1;
}
ndb_mgm_configuration_iterator * it;
@@ -1174,7 +1523,7 @@ CommandInterpreter::executeShow(char* parameters)
if(it == 0){
ndbout_c("Unable to create config iterator");
ndb_mgm_destroy_configuration(conf);
- return;
+ return -1;
}
NdbAutoPtr<ndb_mgm_configuration_iterator> ptr(it);
@@ -1208,7 +1557,7 @@ CommandInterpreter::executeShow(char* parameters)
break;
case NDB_MGM_NODE_TYPE_UNKNOWN:
ndbout << "Error: Unknown Node Type" << endl;
- return;
+ return -1;
}
}
@@ -1219,7 +1568,7 @@ CommandInterpreter::executeShow(char* parameters)
print_nodes(state, it, "mysqld", api_nodes, NDB_MGM_NODE_TYPE_API, 0);
// ndbout << helpTextShow;
ndb_mgm_destroy_configuration(conf);
- return;
+ return 0;
} else if (strcasecmp(parameters, "PROPERTIES") == 0 ||
strcasecmp(parameters, "PROP") == 0) {
ndbout << "SHOW PROPERTIES is not yet implemented." << endl;
@@ -1236,17 +1585,29 @@ CommandInterpreter::executeShow(char* parameters)
// << endl; /* XXX */
} else {
ndbout << "Invalid argument." << endl;
+ return -1;
}
+ return 0;
}
-void
-CommandInterpreter::executeConnect(char* parameters)
+int
+CommandInterpreter::executeConnect(char* parameters, bool interactive)
{
+ BaseString *basestring = NULL;
+
+ int retval;
disconnect();
if (!emptyString(parameters)) {
- m_constr= BaseString(parameters).trim().c_str();
+ basestring= new BaseString(parameters);
+ m_constr= basestring->trim().c_str();
+ }
+ if ( connect(interactive) == false ){
+ return -1;
}
- connect();
+ if (basestring != NULL)
+ delete basestring;
+
+ return 0;
}
//*****************************************************************************
@@ -1259,6 +1620,7 @@ CommandInterpreter::executeClusterLog(char* parameters)
if (emptyString(parameters))
{
ndbout << "Missing argument." << endl;
+ m_error = -1;
DBUG_VOID_RETURN;
}
@@ -1274,6 +1636,7 @@ CommandInterpreter::executeClusterLog(char* parameters)
if(enabled == NULL) {
ndbout << "Couldn't get status" << endl;
printError();
+ m_error = -1;
DBUG_VOID_RETURN;
}
@@ -1285,6 +1648,7 @@ CommandInterpreter::executeClusterLog(char* parameters)
if(enabled[0] == 0)
{
ndbout << "Cluster logging is disabled." << endl;
+ m_error = 0;
DBUG_VOID_RETURN;
}
#if 0
@@ -1303,6 +1667,7 @@ CommandInterpreter::executeClusterLog(char* parameters)
ndbout << BaseString(str).ndb_toupper() << " ";
}
ndbout << endl;
+ m_error = 0;
DBUG_VOID_RETURN;
}
@@ -1321,6 +1686,7 @@ CommandInterpreter::executeClusterLog(char* parameters)
enable= 1;
} else {
ndbout << "Invalid argument." << endl;
+ m_error = -1;
DBUG_VOID_RETURN;
}
@@ -1335,9 +1701,11 @@ CommandInterpreter::executeClusterLog(char* parameters)
{
ndbout << "Couldn't set filter" << endl;
printError();
+ m_error = -1;
DBUG_VOID_RETURN;
}
ndbout << "Cluster logging is " << (res_enable ? "enabled.":"disabled") << endl;
+ m_error = 0;
DBUG_VOID_RETURN;
}
@@ -1364,6 +1732,7 @@ CommandInterpreter::executeClusterLog(char* parameters)
}
if (severity == NDB_MGM_ILLEGAL_EVENT_SEVERITY) {
ndbout << "Invalid severity level: " << item << endl;
+ m_error = -1;
DBUG_VOID_RETURN;
}
@@ -1373,23 +1742,27 @@ CommandInterpreter::executeClusterLog(char* parameters)
{
ndbout << "Couldn't set filter" << endl;
printError();
+ m_error = -1;
DBUG_VOID_RETURN;
}
ndbout << BaseString(item).ndb_toupper().c_str() << " " << (res_enable ? "enabled":"disabled") << endl;
item = strtok_r(NULL, " ", &tmpPtr);
} while(item != NULL);
-
+
+ m_error = 0;
DBUG_VOID_RETURN;
}
//*****************************************************************************
//*****************************************************************************
-void
+int
CommandInterpreter::executeStop(int processId, const char *parameters,
bool all)
{
+ int retval = 0;
+
Vector<BaseString> command_list;
if (parameters)
{
@@ -1399,18 +1772,22 @@ CommandInterpreter::executeStop(int processId, const char *parameters,
command_list[i].c_str()[0] ? i++ : (command_list.erase(i),0);
}
if (all)
- executeStop(command_list, 0, 0, 0);
+ retval = executeStop(command_list, 0, 0, 0);
else
- executeStop(command_list, 0, &processId, 1);
+ retval = executeStop(command_list, 0, &processId, 1);
+
+ return retval;
}
-void
+int
CommandInterpreter::executeStop(Vector<BaseString> &command_list,
unsigned command_pos,
int *node_ids, int no_of_nodes)
{
int need_disconnect;
int abort= 0;
+ int retval = 0;
+
for (; command_pos < command_list.size(); command_pos++)
{
const char *item= command_list[command_pos].c_str();
@@ -1421,7 +1798,7 @@ CommandInterpreter::executeStop(Vector<BaseString> &command_list,
}
ndbout_c("Invalid option: %s. Expecting -A after STOP",
item);
- return;
+ return -1;
}
int result= ndb_mgm_stop3(m_mgmsrv, no_of_nodes, node_ids, abort,
@@ -1430,6 +1807,7 @@ CommandInterpreter::executeStop(Vector<BaseString> &command_list,
{
ndbout_c("Shutdown failed.");
printError();
+ retval = -1;
}
else
{
@@ -1450,9 +1828,10 @@ CommandInterpreter::executeStop(Vector<BaseString> &command_list,
disconnect();
}
+ return retval;
}
-void
+int
CommandInterpreter::executeEnterSingleUser(char* parameters)
{
strtok(parameters, " ");
@@ -1464,37 +1843,42 @@ CommandInterpreter::executeEnterSingleUser(char* parameters)
if(id == 0 || sscanf(id, "%d", &nodeId) != 1){
ndbout_c("Invalid arguments: expected <NodeId>");
ndbout_c("Use SHOW to see what API nodes are configured");
- return;
+ return -1;
}
int result = ndb_mgm_enter_single_user(m_mgmsrv, nodeId, &reply);
if (result != 0) {
ndbout_c("Entering single user mode for node %d failed", nodeId);
printError();
+ return -1;
} else {
ndbout_c("Single user mode entered");
ndbout_c("Access is granted for API node %d only.", nodeId);
}
+ return 0;
}
-void
+int
CommandInterpreter::executeExitSingleUser(char* parameters)
{
int result = ndb_mgm_exit_single_user(m_mgmsrv, 0);
if (result != 0) {
ndbout_c("Exiting single user mode failed.");
printError();
+ return -1;
} else {
ndbout_c("Exiting single user mode in progress.");
ndbout_c("Use ALL STATUS or SHOW to see when single user mode has been exited.");
+ return 0;
}
}
-void
+int
CommandInterpreter::executeStart(int processId, const char* parameters,
bool all)
{
int result;
+ int retval = 0;
if(all) {
result = ndb_mgm_start(m_mgmsrv, 0, 0);
} else {
@@ -1504,6 +1888,7 @@ CommandInterpreter::executeStart(int processId, const char* parameters,
if (result <= 0) {
ndbout << "Start failed." << endl;
printError();
+ retval = -1;
} else
{
if(all)
@@ -1511,13 +1896,16 @@ CommandInterpreter::executeStart(int processId, const char* parameters,
else
ndbout_c("Database node %d is being started.", processId);
}
+ return retval;
}
-void
+int
CommandInterpreter::executeRestart(int processId, const char* parameters,
bool all)
{
Vector<BaseString> command_list;
+ int retval = 0;
+
if (parameters)
{
BaseString tmp(parameters);
@@ -1526,17 +1914,20 @@ CommandInterpreter::executeRestart(int processId, const char* parameters,
command_list[i].c_str()[0] ? i++ : (command_list.erase(i),0);
}
if (all)
- executeRestart(command_list, 0, 0, 0);
+ retval = executeRestart(command_list, 0, 0, 0);
else
- executeRestart(command_list, 0, &processId, 1);
+ retval = executeRestart(command_list, 0, &processId, 1);
+
+ return retval;
}
-void
+int
CommandInterpreter::executeRestart(Vector<BaseString> &command_list,
unsigned command_pos,
int *node_ids, int no_of_nodes)
{
int result;
+ int retval = 0;
int nostart= 0;
int initialstart= 0;
int abort= 0;
@@ -1562,7 +1953,7 @@ CommandInterpreter::executeRestart(Vector<BaseString> &command_list,
}
ndbout_c("Invalid option: %s. Expecting -A,-N or -I after RESTART",
item);
- return;
+ return -1;
}
result= ndb_mgm_restart3(m_mgmsrv, no_of_nodes, node_ids,
@@ -1571,6 +1962,7 @@ CommandInterpreter::executeRestart(Vector<BaseString> &command_list,
if (result <= 0) {
ndbout_c("Restart failed.");
printError();
+ retval = -1;
}
else
{
@@ -1586,15 +1978,16 @@ CommandInterpreter::executeRestart(Vector<BaseString> &command_list,
if(need_disconnect)
disconnect();
}
+ return retval;
}
-void
+int
CommandInterpreter::executeDumpState(int processId, const char* parameters,
bool all)
{
if(emptyString(parameters)){
ndbout << "Expected argument" << endl;
- return;
+ return -1;
}
Uint32 no = 0;
@@ -1611,7 +2004,7 @@ CommandInterpreter::executeDumpState(int processId, const char* parameters,
ndbout << "Illegal value in argument to signal." << endl
<< "(Value must be between 0 and 0xffffffff.)"
<< endl;
- return;
+ return -1;
}
no++;
item = strtok_r(NULL, " ", &tmpPtr);
@@ -1623,16 +2016,16 @@ CommandInterpreter::executeDumpState(int processId, const char* parameters,
}
struct ndb_mgm_reply reply;
- ndb_mgm_dump_state(m_mgmsrv, processId, pars, no, &reply);
+ return ndb_mgm_dump_state(m_mgmsrv, processId, pars, no, &reply);
}
-void
+int
CommandInterpreter::executeStatus(int processId,
const char* parameters, bool all)
{
if (! emptyString(parameters)) {
ndbout_c("No parameters expected to this command.");
- return;
+ return -1;
}
ndb_mgm_node_status status;
@@ -1644,7 +2037,7 @@ CommandInterpreter::executeStatus(int processId,
if(cl == NULL) {
ndbout_c("Cannot get status of node %d.", processId);
printError();
- return;
+ return -1;
}
NdbAutoPtr<char> ap1((char*)cl);
@@ -1653,7 +2046,7 @@ CommandInterpreter::executeStatus(int processId,
i++;
if(cl->node_states[i].node_id != processId) {
ndbout << processId << ": Node not found" << endl;
- return;
+ return -1;
}
status = cl->node_states[i].node_status;
startPhase = cl->node_states[i].start_phase;
@@ -1677,27 +2070,29 @@ CommandInterpreter::executeStatus(int processId,
getBuild(version));
else
ndbout << endl;
+
+ return 0;
}
//*****************************************************************************
//*****************************************************************************
-void
+int
CommandInterpreter::executeLogLevel(int processId, const char* parameters,
bool all)
{
(void) all;
if (emptyString(parameters)) {
ndbout << "Expected argument" << endl;
- return;
+ return -1;
}
BaseString tmp(parameters);
Vector<BaseString> spec;
tmp.split(spec, "=");
if(spec.size() != 2){
ndbout << "Invalid loglevel specification: " << parameters << endl;
- return;
+ return -1;
}
spec[0].trim().ndb_toupper();
@@ -1707,14 +2102,14 @@ CommandInterpreter::executeLogLevel(int processId, const char* parameters,
if(category < NDB_MGM_MIN_EVENT_CATEGORY ||
category > NDB_MGM_MAX_EVENT_CATEGORY){
ndbout << "Unknown category: \"" << spec[0].c_str() << "\"" << endl;
- return;
+ return -1;
}
}
int level = atoi(spec[1].c_str());
if(level < 0 || level > 15){
ndbout << "Invalid level: " << spec[1].c_str() << endl;
- return;
+ return -1;
}
ndbout << "Executing LOGLEVEL on node " << processId << flush;
@@ -1730,20 +2125,22 @@ CommandInterpreter::executeLogLevel(int processId, const char* parameters,
if (result < 0) {
ndbout_c(" failed.");
printError();
+ return -1;
} else {
ndbout_c(" OK!");
}
-
+ return 0;
}
//*****************************************************************************
//*****************************************************************************
-void CommandInterpreter::executeError(int processId,
+int CommandInterpreter::executeError(int processId,
const char* parameters, bool /* all */)
{
+ int retval = 0;
if (emptyString(parameters)) {
ndbout << "Missing error number." << endl;
- return;
+ return -1;
}
// Copy parameters since strtok will modify it
@@ -1754,29 +2151,30 @@ void CommandInterpreter::executeError(int processId,
int errorNo;
if (! convert(firstParameter, errorNo)) {
ndbout << "Expected an integer." << endl;
- return;
+ return -1;
}
char* allAfterFirstParameter = strtok(NULL, "\0");
if (! emptyString(allAfterFirstParameter)) {
ndbout << "Nothing expected after error number." << endl;
- return;
+ return -1;
}
- ndb_mgm_insert_error(m_mgmsrv, processId, errorNo, NULL);
+ retval = ndb_mgm_insert_error(m_mgmsrv, processId, errorNo, NULL);
+ return retval;
}
//*****************************************************************************
//*****************************************************************************
-void
+int
CommandInterpreter::executeLog(int processId,
const char* parameters, bool all)
{
struct ndb_mgm_reply reply;
Vector<const char *> blocks;
if (! parseBlockSpecification(parameters, blocks)) {
- return;
+ return -1;
}
int len=1;
Uint32 i;
@@ -1800,82 +2198,91 @@ CommandInterpreter::executeLog(int processId,
if (result != 0) {
ndbout_c("Execute LOG on node %d failed.", processId);
printError();
+ return -1;
}
+ return 0;
}
//*****************************************************************************
//*****************************************************************************
-void
+int
CommandInterpreter::executeLogIn(int /* processId */,
const char* parameters, bool /* all */)
{
ndbout << "Command LOGIN not implemented." << endl;
+ return 0;
}
//*****************************************************************************
//*****************************************************************************
-void
+int
CommandInterpreter::executeLogOut(int /*processId*/,
const char* parameters, bool /*all*/)
{
ndbout << "Command LOGOUT not implemented." << endl;
+ return 0;
}
//*****************************************************************************
//*****************************************************************************
-void
+int
CommandInterpreter::executeLogOff(int /*processId*/,
const char* parameters, bool /*all*/)
{
ndbout << "Command LOGOFF not implemented." << endl;
+ return 0;
}
//*****************************************************************************
//*****************************************************************************
-void
+int
CommandInterpreter::executeTestOn(int processId,
const char* parameters, bool /*all*/)
{
if (! emptyString(parameters)) {
ndbout << "No parameters expected to this command." << endl;
- return;
+ return -1;
}
struct ndb_mgm_reply reply;
int result = ndb_mgm_start_signallog(m_mgmsrv, processId, &reply);
if (result != 0) {
ndbout_c("Execute TESTON failed.");
printError();
+ return -1;
}
+ return 0;
}
//*****************************************************************************
//*****************************************************************************
-void
+int
CommandInterpreter::executeTestOff(int processId,
const char* parameters, bool /*all*/)
{
if (! emptyString(parameters)) {
ndbout << "No parameters expected to this command." << endl;
- return;
+ return -1;
}
struct ndb_mgm_reply reply;
int result = ndb_mgm_stop_signallog(m_mgmsrv, processId, &reply);
if (result != 0) {
ndbout_c("Execute TESTOFF failed.");
printError();
+ return -1;
}
+ return 0;
}
//*****************************************************************************
//*****************************************************************************
-void
+int
CommandInterpreter::executeSet(int /*processId*/,
const char* parameters, bool /*all*/)
{
if (emptyString(parameters)) {
ndbout << "Missing parameter name." << endl;
- return;
+ return -1;
}
#if 0
// Copy parameters since strtok will modify it
@@ -1939,17 +2346,18 @@ CommandInterpreter::executeSet(int /*processId*/,
abort();
}
}
-#endif
+#endif
+ return 0;
}
//*****************************************************************************
//*****************************************************************************
-void CommandInterpreter::executeGetStat(int /*processId*/,
+int CommandInterpreter::executeGetStat(int /*processId*/,
const char* parameters, bool /*all*/)
{
if (! emptyString(parameters)) {
ndbout << "No parameters expected to this command." << endl;
- return;
+ return -1;
}
#if 0
@@ -1965,19 +2373,21 @@ void CommandInterpreter::executeGetStat(int /*processId*/,
ndbout << "Number of GETSTAT commands: "
<< statistics._test1 << endl;
*/
+ return 0;
}
//*****************************************************************************
//*****************************************************************************
-void
+int
CommandInterpreter::executeEventReporting(int processId,
const char* parameters,
bool all)
{
+ int retval = 0;
if (emptyString(parameters)) {
ndbout << "Expected argument" << endl;
- return;
+ return -1;
}
BaseString tmp(parameters);
Vector<BaseString> specs;
@@ -2024,10 +2434,12 @@ CommandInterpreter::executeEventReporting(int processId,
if (result != 0) {
ndbout_c(" failed.");
printError();
+ retval = -1;
} else {
ndbout_c(" OK!");
}
}
+ return retval;
}
/*****************************************************************************
@@ -2087,7 +2499,7 @@ CommandInterpreter::executeStartBackup(char* parameters)
}
if (result != 0) {
- ndbout << "Start of backup failed" << endl;
+ ndbout << "Backup failed" << endl;
printError();
#if 0
close(fd);
@@ -2128,7 +2540,7 @@ CommandInterpreter::executeStartBackup(char* parameters)
return 0;
}
-void
+int
CommandInterpreter::executeAbortBackup(char* parameters)
{
int bid = -1;
@@ -2147,14 +2559,15 @@ CommandInterpreter::executeAbortBackup(char* parameters)
if (result != 0) {
ndbout << "Abort of backup " << bid << " failed" << endl;
printError();
+ return -1;
} else {
ndbout << "Abort of backup " << bid << " ordered" << endl;
}
}
- return;
+ return 0;
executeAbortBackupError1:
ndbout << "Invalid arguments: expected <BackupId>" << endl;
- return;
+ return -1;
}
template class Vector<char const*>;
diff --git a/storage/ndb/src/mgmclient/main.cpp b/storage/ndb/src/mgmclient/main.cpp
index 73a18f98c9d..9dc3672bedd 100644
--- a/storage/ndb/src/mgmclient/main.cpp
+++ b/storage/ndb/src/mgmclient/main.cpp
@@ -38,6 +38,7 @@ extern "C" int add_history(const char *command); /* From readline directory */
#include "ndb_mgmclient.hpp"
const char *progname = "ndb_mgm";
+const char *load_default_groups[]= { "mysql_cluster","ndb_mgm",0 };
static Ndb_mgmclient* com;
@@ -87,6 +88,8 @@ static void usage()
{
short_usage_sub();
ndb_std_print_version();
+ print_defaults(MYSQL_CONFIG_NAME,load_default_groups);
+ puts("");
my_print_help(my_long_options);
my_print_variables(my_long_options);
}
@@ -121,14 +124,13 @@ read_and_execute(int _try_reconnect)
line_read= strdup(linebuffer);
}
#endif
- return com->execute(line_read,_try_reconnect);
+ return com->execute(line_read, _try_reconnect, 1);
}
int main(int argc, char** argv){
NDB_INIT(argv[0]);
const char *_host = 0;
int _port = 0;
- const char *load_default_groups[]= { "mysql_cluster","ndb_mgm",0 };
load_defaults("my",load_default_groups,&argc,&argv);
int ho_error;
@@ -163,7 +165,7 @@ int main(int argc, char** argv){
}
else
{
- com->execute(opt_execute_str,_try_reconnect, &ret);
+ com->execute(opt_execute_str,_try_reconnect, 0, &ret);
}
delete com;
diff --git a/storage/ndb/src/mgmclient/ndb_mgmclient.hpp b/storage/ndb/src/mgmclient/ndb_mgmclient.hpp
index bffdf69f920..956caebe803 100644
--- a/storage/ndb/src/mgmclient/ndb_mgmclient.hpp
+++ b/storage/ndb/src/mgmclient/ndb_mgmclient.hpp
@@ -23,8 +23,8 @@ class Ndb_mgmclient
public:
Ndb_mgmclient(const char*,int verbose=0);
~Ndb_mgmclient();
- int execute(const char *_line, int _try_reconnect=-1, int *error= 0);
- int execute(int argc, char** argv, int _try_reconnect=-1, int *error= 0);
+ int execute(const char *_line, int _try_reconnect=-1, bool interactive=1, int *error= 0);
+ int execute(int argc, char** argv, int _try_reconnect=-1, bool interactive=1, int *error= 0);
int disconnect();
private:
CommandInterpreter *m_cmd;
diff --git a/storage/ndb/src/mgmsrv/ConfigInfo.cpp b/storage/ndb/src/mgmsrv/ConfigInfo.cpp
index fb15e35ecc7..6d36662e516 100644
--- a/storage/ndb/src/mgmsrv/ConfigInfo.cpp
+++ b/storage/ndb/src/mgmsrv/ConfigInfo.cpp
@@ -2688,6 +2688,13 @@ transformNode(InitConfigFileParser::Context & ctx, const char * data){
return false;
}
+ if(id >= MAX_NODES)
+ {
+ ctx.reportError("too many nodes configured, only up to %d nodes supported.",
+ MAX_NODES);
+ return false;
+ }
+
// next node id _always_ next numbers after last used id
ctx.m_userProperties.put("NextNodeId", id+1, true);
@@ -3579,11 +3586,11 @@ sanity_checks(Vector<ConfigInfo::ConfigRuleSection>&sections,
Uint32 mgm_nodes = 0;
Uint32 api_nodes = 0;
if (!ctx.m_userProperties.get("DB", &db_nodes)) {
- ctx.reportError("At least one database node should be defined in config file");
+ ctx.reportError("At least one database node (ndbd) should be defined in config file");
return false;
}
if (!ctx.m_userProperties.get("MGM", &mgm_nodes)) {
- ctx.reportError("At least one management server node should be defined in config file");
+ ctx.reportError("At least one management server node (ndb_mgmd) should be defined in config file");
return false;
}
if (!ctx.m_userProperties.get("API", &api_nodes)) {
diff --git a/storage/ndb/src/mgmsrv/MgmtSrvr.cpp b/storage/ndb/src/mgmsrv/MgmtSrvr.cpp
index a2a56905392..222b71dbaac 100644
--- a/storage/ndb/src/mgmsrv/MgmtSrvr.cpp
+++ b/storage/ndb/src/mgmsrv/MgmtSrvr.cpp
@@ -449,7 +449,10 @@ MgmtSrvr::MgmtSrvr(SocketServer *socket_server,
// read config locally
_config= readConfig();
if (_config == 0) {
- ndbout << "Unable to read config file" << endl;
+ if (config_filename != NULL)
+ ndbout << "Invalid configuration file: " << config_filename << endl;
+ else
+ ndbout << "Invalid configuration file" << endl;
exit(-1);
}
}
@@ -1006,6 +1009,11 @@ int MgmtSrvr::sendSTOP_REQ(const Vector<NodeId> &node_ids,
{
nodeId= node_ids[i];
ndbout << "asked to stop " << nodeId << endl;
+
+ if ((getNodeType(nodeId) != NDB_MGM_NODE_TYPE_MGM)
+ &&(getNodeType(nodeId) != NDB_MGM_NODE_TYPE_NDB))
+ return WRONG_PROCESS_TYPE;
+
if (getNodeType(nodeId) != NDB_MGM_NODE_TYPE_MGM)
nodes_to_stop.set(nodeId);
else if (nodeId != getOwnNodeId())
diff --git a/storage/ndb/src/mgmsrv/Services.cpp b/storage/ndb/src/mgmsrv/Services.cpp
index 5132b343fbd..4a84095aa9f 100644
--- a/storage/ndb/src/mgmsrv/Services.cpp
+++ b/storage/ndb/src/mgmsrv/Services.cpp
@@ -33,6 +33,7 @@
#include "../mgmapi/ndb_logevent.hpp"
#include <base64.h>
+#include <ndberror.h>
extern bool g_StopServer;
extern bool g_RestartServer;
@@ -144,6 +145,7 @@ ParserRow<MgmApiSession> commands[] = {
MGM_CMD("get status", &MgmApiSession::getStatus, ""),
MGM_CMD("get info clusterlog", &MgmApiSession::getInfoClusterLog, ""),
+ MGM_CMD("get cluster loglevel", &MgmApiSession::getClusterLogLevel, ""),
MGM_CMD("restart node", &MgmApiSession::restart_v1, ""),
MGM_ARG("node", String, Mandatory, "Nodes to restart"),
@@ -268,6 +270,13 @@ ParserRow<MgmApiSession> commands[] = {
MGM_ARG("length", Int, Mandatory, "Length"),
MGM_ARG("data", String, Mandatory, "Data"),
+ MGM_CMD("list sessions", &MgmApiSession::listSessions, ""),
+
+ MGM_CMD("get session id", &MgmApiSession::getSessionId, ""),
+
+ MGM_CMD("get session", &MgmApiSession::getSession, ""),
+ MGM_ARG("id", Int, Mandatory, "SessionID"),
+
MGM_END()
};
@@ -280,7 +289,7 @@ struct PurgeStruct
NDB_TICKS tick;
};
-MgmApiSession::MgmApiSession(class MgmtSrvr & mgm, NDB_SOCKET_TYPE sock)
+MgmApiSession::MgmApiSession(class MgmtSrvr & mgm, NDB_SOCKET_TYPE sock, Uint64 session_id)
: SocketServer::Session(sock), m_mgmsrv(mgm)
{
DBUG_ENTER("MgmApiSession::MgmApiSession");
@@ -289,6 +298,9 @@ MgmApiSession::MgmApiSession(class MgmtSrvr & mgm, NDB_SOCKET_TYPE sock)
m_parser = new Parser_t(commands, *m_input, true, true, true);
m_allocated_resources= new MgmtSrvr::Allocated_resources(m_mgmsrv);
m_stopSelf= 0;
+ m_ctx= NULL;
+ m_session_id= session_id;
+ m_mutex= NdbMutex_Create();
DBUG_VOID_RETURN;
}
@@ -312,6 +324,7 @@ MgmApiSession::~MgmApiSession()
g_RestartServer= true;
if(m_stopSelf)
g_StopServer= true;
+ NdbMutex_Destroy(m_mutex);
DBUG_VOID_RETURN;
}
@@ -321,11 +334,19 @@ MgmApiSession::runSession()
DBUG_ENTER("MgmApiSession::runSession");
Parser_t::Context ctx;
- while(!m_stop) {
+ ctx.m_mutex= m_mutex;
+ m_ctx= &ctx;
+ bool stop= false;
+ while(!stop) {
+ NdbMutex_Lock(m_mutex);
+
m_parser->run(ctx, *this);
if(ctx.m_currentToken == 0)
+ {
+ NdbMutex_Unlock(m_mutex);
break;
+ }
switch(ctx.m_status) {
case Parser_t::UnknownCommand:
@@ -346,13 +367,19 @@ MgmApiSession::runSession()
default:
break;
}
- }
+
+ stop= m_stop;
+ NdbMutex_Unlock(m_mutex);
+ };
+
+ NdbMutex_Lock(m_mutex);
+ m_ctx= NULL;
if(m_socket != NDB_INVALID_SOCKET)
{
NDB_CLOSE_SOCKET(m_socket);
m_socket= NDB_INVALID_SOCKET;
}
-
+ NdbMutex_Unlock(m_mutex);
DBUG_VOID_RETURN;
}
@@ -793,6 +820,32 @@ MgmApiSession::endSession(Parser<MgmApiSession>::Context &,
}
void
+MgmApiSession::getClusterLogLevel(Parser<MgmApiSession>::Context & , Properties const &) {
+ const char* names[] = { "startup",
+ "shutdown",
+ "statistics",
+ "checkpoint",
+ "noderestart",
+ "connection",
+ "info",
+ "warning",
+ "error",
+ "congestion",
+ "debug",
+ "backup" };
+
+ int loglevel_count = (CFG_MAX_LOGLEVEL - CFG_MIN_LOGLEVEL + 1) ;
+ LogLevel::EventCategory category;
+
+ m_output->println("get cluster loglevel");
+ for(int i = 0; i < loglevel_count; i++) {
+ category = (LogLevel::EventCategory) i;
+ m_output->println("%s: %d", names[i], m_mgmsrv.m_event_listner[0].m_logLevel.getLogLevel(category));
+ }
+ m_output->println("");
+}
+
+void
MgmApiSession::setClusterLogLevel(Parser<MgmApiSession>::Context &,
Properties const &args) {
const char *reply= "set cluster loglevel reply";
@@ -1315,6 +1368,12 @@ Ndb_mgmd_event_service::log(int eventType, const Uint32* theData, NodeId nodeId)
if (ndb_logevent_body[i].index_fn)
val= (*(ndb_logevent_body[i].index_fn))(val);
str.appfmt("%s=%d\n",ndb_logevent_body[i].token, val);
+ if(strcmp(ndb_logevent_body[i].token,"error") == 0)
+ {
+ int m_text_len= strlen(m_text);
+ snprintf(m_text+m_text_len, 4 , " - ");
+ ndb_error_string(theData[3], m_text+(m_text_len+3), sizeof(m_text)-m_text_len-3);
+ }
}
Vector<NDB_SOCKET_TYPE> copy;
@@ -1558,11 +1617,6 @@ MgmApiSession::listen_event(Parser<MgmApiSession>::Context & ctx,
result = -1;
goto done;
}
-
- m_mgmsrv.m_event_listner.add_listener(le);
-
- m_stop = true;
- m_socket = NDB_INVALID_SOCKET;
done:
m_output->println("listen event");
@@ -1570,6 +1624,13 @@ done:
if(result != 0)
m_output->println("msg: %s", msg.c_str());
m_output->println("");
+
+ if(result==0)
+ {
+ m_mgmsrv.m_event_listner.add_listener(le);
+ m_stop = true;
+ m_socket = NDB_INVALID_SOCKET;
+ }
}
void
@@ -1672,5 +1733,122 @@ MgmApiSession::report_event(Parser_t::Context &ctx,
m_output->println("");
}
+void
+MgmApiSession::list_session(SocketServer::Session *_s, void *data)
+{
+ MgmApiSession *s= (MgmApiSession *)_s;
+ MgmApiSession *lister= (MgmApiSession*) data;
+
+ if(s!=lister)
+ NdbMutex_Lock(s->m_mutex);
+
+ Uint64 id= s->m_session_id;
+ lister->m_output->println("session: %llu",id);
+ lister->m_output->println("session.%llu.m_stopSelf: %d",id,s->m_stopSelf);
+ lister->m_output->println("session.%llu.m_stop: %d",id,s->m_stop);
+ lister->m_output->println("session.%llu.allocated.nodeid: %d",id,s->m_allocated_resources->get_nodeid());
+ if(s->m_ctx)
+ {
+ int l= strlen(s->m_ctx->m_tokenBuffer);
+ char *buf= (char*) malloc(2*l+1);
+ char *b= buf;
+ for(int i=0; i<l;i++)
+ if(s->m_ctx->m_tokenBuffer[i]=='\n')
+ {
+ *b++='\\';
+ *b++='n';
+ }
+ else
+ {
+ *b++= s->m_ctx->m_tokenBuffer[i];
+ }
+ *b= '\0';
+
+ lister->m_output->println("session.%llu.parser.buffer.len: %u",id,l);
+ lister->m_output->println("session.%llu.parser.buffer: %s",id,buf);
+ lister->m_output->println("session.%llu.parser.status: %d",id,s->m_ctx->m_status);
+
+ free(buf);
+ }
+
+ if(s!=lister)
+ NdbMutex_Unlock(s->m_mutex);
+}
+
+void
+MgmApiSession::listSessions(Parser_t::Context &ctx,
+ Properties const &args) {
+ m_mgmsrv.get_socket_server()->foreachSession(list_session,(void*)this);
+
+ m_output->println("");
+}
+
+void
+MgmApiSession::getSessionId(Parser_t::Context &ctx,
+ Properties const &args) {
+ m_output->println("get session id reply");
+ m_output->println("id: %llu",m_session_id);
+ m_output->println("");
+}
+
+struct get_session_param {
+ MgmApiSession *l;
+ Uint64 id;
+ int found;
+};
+
+void
+MgmApiSession::get_session(SocketServer::Session *_s, void *data)
+{
+ struct get_session_param *p= (struct get_session_param*)data;
+ MgmApiSession *s= (MgmApiSession *)_s;
+
+ if(s!=p->l)
+ NdbMutex_Lock(s->m_mutex);
+
+ if(p->id != s->m_session_id)
+ {
+ if(s!=p->l)
+ NdbMutex_Unlock(s->m_mutex);
+ return;
+ }
+
+ p->found= true;
+ p->l->m_output->println("id: %llu",s->m_session_id);
+ p->l->m_output->println("m_stopSelf: %d",s->m_stopSelf);
+ p->l->m_output->println("m_stop: %d",s->m_stop);
+ p->l->m_output->println("nodeid: %d",s->m_allocated_resources->get_nodeid());
+ if(s->m_ctx)
+ {
+ int l= strlen(s->m_ctx->m_tokenBuffer);
+ p->l->m_output->println("parser_buffer_len: %u",l);
+ p->l->m_output->println("parser_status: %d",s->m_ctx->m_status);
+ }
+
+ if(s!=p->l)
+ NdbMutex_Unlock(s->m_mutex);
+}
+
+void
+MgmApiSession::getSession(Parser_t::Context &ctx,
+ Properties const &args) {
+ Uint64 id;
+ struct get_session_param p;
+
+ args.get("id", &id);
+
+ p.l= this;
+ p.id= id;
+ p.found= false;
+
+ m_output->println("get session reply");
+ m_mgmsrv.get_socket_server()->foreachSession(get_session,(void*)&p);
+
+ if(p.found==false)
+ m_output->println("id: 0");
+
+ m_output->println("");
+}
+
template class MutexVector<int>;
template class Vector<ParserRow<MgmApiSession> const*>;
diff --git a/storage/ndb/src/mgmsrv/Services.hpp b/storage/ndb/src/mgmsrv/Services.hpp
index d0a61b3f91d..8b9ca7156b9 100644
--- a/storage/ndb/src/mgmsrv/Services.hpp
+++ b/storage/ndb/src/mgmsrv/Services.hpp
@@ -32,6 +32,8 @@ class MgmApiSession : public SocketServer::Session
{
static void stop_session_if_timed_out(SocketServer::Session *_s, void *data);
static void stop_session_if_not_connected(SocketServer::Session *_s, void *data);
+ static void list_session(SocketServer::Session *_s, void *data);
+ static void get_session(SocketServer::Session *_s, void *data);
private:
typedef Parser<MgmApiSession> Parser_t;
@@ -42,6 +44,11 @@ private:
MgmtSrvr::Allocated_resources *m_allocated_resources;
char m_err_str[1024];
int m_stopSelf; // -1 is restart, 0 do nothing, 1 stop
+ NdbMutex *m_mutex;
+
+ // for listing sessions and other fun:
+ Parser_t::Context *m_ctx;
+ Uint64 m_session_id;
void getConfig_common(Parser_t::Context &ctx,
const class Properties &args,
@@ -50,7 +57,7 @@ private:
{ return m_mgmsrv.getErrorText(err_no, m_err_str, sizeof(m_err_str)); }
public:
- MgmApiSession(class MgmtSrvr & mgm, NDB_SOCKET_TYPE sock);
+ MgmApiSession(class MgmtSrvr & mgm, NDB_SOCKET_TYPE sock, Uint64 session_id);
virtual ~MgmApiSession();
void runSession();
@@ -86,6 +93,8 @@ public:
void bye(Parser_t::Context &ctx, const class Properties &args);
void endSession(Parser_t::Context &ctx, const class Properties &args);
void setLogLevel(Parser_t::Context &ctx, const class Properties &args);
+ void getClusterLogLevel(Parser_t::Context &ctx,
+ const class Properties &args);
void setClusterLogLevel(Parser_t::Context &ctx,
const class Properties &args);
void setLogFilter(Parser_t::Context &ctx, const class Properties &args);
@@ -106,13 +115,20 @@ public:
void get_mgmd_nodeid(Parser_t::Context &ctx, Properties const &args);
void report_event(Parser_t::Context &ctx, Properties const &args);
+
+ void listSessions(Parser_t::Context &ctx, Properties const &args);
+
+ void getSessionId(Parser_t::Context &ctx, Properties const &args);
+ void getSession(Parser_t::Context &ctx, Properties const &args);
};
class MgmApiService : public SocketServer::Service {
class MgmtSrvr * m_mgmsrv;
+ Uint64 m_next_session_id; // Protected by m_sessions mutex it SocketServer
public:
MgmApiService(){
m_mgmsrv = 0;
+ m_next_session_id= 1;
}
void setMgm(class MgmtSrvr * mgmsrv){
@@ -120,7 +136,7 @@ public:
}
SocketServer::Session * newSession(NDB_SOCKET_TYPE socket){
- return new MgmApiSession(* m_mgmsrv, socket);
+ return new MgmApiSession(* m_mgmsrv, socket, m_next_session_id++);
}
};
diff --git a/storage/ndb/src/mgmsrv/main.cpp b/storage/ndb/src/mgmsrv/main.cpp
index 26cb0951d3a..9eb4ad9bde3 100644
--- a/storage/ndb/src/mgmsrv/main.cpp
+++ b/storage/ndb/src/mgmsrv/main.cpp
@@ -47,6 +47,7 @@
#define DEBUG(x) ndbout << x << endl;
const char progname[] = "mgmtsrvr";
+const char *load_default_groups[]= { "mysql_cluster","ndb_mgmd",0 };
// copied from mysql.cc to get readline
extern "C" {
@@ -183,6 +184,8 @@ static void usage()
{
short_usage_sub();
ndb_std_print_version();
+ print_defaults(MYSQL_CONFIG_NAME,load_default_groups);
+ puts("");
my_print_help(my_long_options);
my_print_variables(my_long_options);
}
@@ -196,7 +199,6 @@ int main(int argc, char** argv)
NDB_INIT(argv[0]);
- const char *load_default_groups[]= { "mysql_cluster","ndb_mgmd",0 };
load_defaults("my",load_default_groups,&argc,&argv);
int ho_error;
diff --git a/storage/ndb/src/ndbapi/Ndb.cpp b/storage/ndb/src/ndbapi/Ndb.cpp
index 973b400f5a2..15ef596deef 100644
--- a/storage/ndb/src/ndbapi/Ndb.cpp
+++ b/storage/ndb/src/ndbapi/Ndb.cpp
@@ -1147,9 +1147,14 @@ error_handler:
theError.code = tOperation->theError.code;
DBUG_ASSERT(theError.code != 0);
+ NdbError savedError;
+ savedError = theError;
+
if (tConnection != NULL)
this->closeTransaction(tConnection);
+ theError = savedError;
+
DBUG_RETURN(-1);
}
diff --git a/storage/ndb/src/ndbapi/NdbDictionary.cpp b/storage/ndb/src/ndbapi/NdbDictionary.cpp
index 269994e01f4..e0fbe46aca4 100644
--- a/storage/ndb/src/ndbapi/NdbDictionary.cpp
+++ b/storage/ndb/src/ndbapi/NdbDictionary.cpp
@@ -204,12 +204,12 @@ NdbDictionary::Column::getPrimaryKey() const {
void
NdbDictionary::Column::setPartitionKey(bool val){
- m_impl.m_distributionKey = (val ? 2 : 0);
+ m_impl.m_distributionKey = true;
}
bool
NdbDictionary::Column::getPartitionKey() const{
- return (bool)m_impl.m_distributionKey;
+ return m_impl.m_distributionKey;
}
const NdbDictionary::Table *
@@ -353,7 +353,6 @@ NdbDictionary::Table::addColumn(const Column & c){
NdbColumnImpl* col = new NdbColumnImpl;
(* col) = NdbColumnImpl::getImpl(c);
m_impl.m_columns.push_back(col);
- m_impl.computeAggregates();
m_impl.buildColumnHash();
}
@@ -699,6 +698,18 @@ NdbDictionary::Table::getRowGCIIndicator() const {
return m_impl.m_row_gci;
}
+int
+NdbDictionary::Table::aggregate(NdbError& error)
+{
+ return m_impl.aggregate(error);
+}
+
+int
+NdbDictionary::Table::validate(NdbError& error)
+{
+ return m_impl.validate(error);
+}
+
/*****************************************************************
* Index facade
diff --git a/storage/ndb/src/ndbapi/NdbDictionaryImpl.cpp b/storage/ndb/src/ndbapi/NdbDictionaryImpl.cpp
index 4e621e69c47..42ef7bbbaee 100644
--- a/storage/ndb/src/ndbapi/NdbDictionaryImpl.cpp
+++ b/storage/ndb/src/ndbapi/NdbDictionaryImpl.cpp
@@ -295,7 +295,7 @@ NdbColumnImpl::equal(const NdbColumnImpl& col) const
DBUG_RETURN(false);
}
if (m_pk) {
- if ((bool)m_distributionKey != (bool)col.m_distributionKey) {
+ if (m_distributionKey != col.m_distributionKey) {
DBUG_RETURN(false);
}
}
@@ -773,6 +773,7 @@ NdbTableImpl::computeAggregates()
m_keyLenInWords = 0;
m_noOfDistributionKeys = 0;
m_noOfBlobs = 0;
+ m_noOfDiskColumns = 0;
Uint32 i, n;
for (i = 0; i < m_columns.size(); i++) {
NdbColumnImpl* col = m_columns[i];
@@ -780,11 +781,15 @@ NdbTableImpl::computeAggregates()
m_noOfKeys++;
m_keyLenInWords += (col->m_attrSize * col->m_arraySize + 3) / 4;
}
- if (col->m_distributionKey == 2) // set by user
- m_noOfDistributionKeys++;
+ if (col->m_distributionKey)
+ m_noOfDistributionKeys++; // XXX check PK
if (col->getBlobType())
m_noOfBlobs++;
+
+ if (col->getStorageType() == NdbDictionary::Column::StorageTypeDisk)
+ m_noOfDiskColumns++;
+
col->m_keyInfoPos = ~0;
}
if (m_noOfDistributionKeys == m_noOfKeys) {
@@ -798,19 +803,7 @@ NdbTableImpl::computeAggregates()
for (i = 0, n = m_noOfKeys; n != 0; i++) {
NdbColumnImpl* col = m_columns[i];
if (col->m_pk) {
- col->m_distributionKey = true; // set by us
- n--;
- }
- }
- }
- else
- {
- for (i = 0, n = m_noOfKeys; n != 0; i++) {
- NdbColumnImpl* col = m_columns[i];
- if (col->m_pk)
- {
- if(col->m_distributionKey == 1)
- col->m_distributionKey = 0;
+ col->m_distributionKey = true;
n--;
}
}
@@ -826,6 +819,22 @@ NdbTableImpl::computeAggregates()
}
}
+// TODO add error checks
+// TODO use these internally at create and retrieve
+int
+NdbTableImpl::aggregate(NdbError& error)
+{
+ computeAggregates();
+ return 0;
+}
+int
+NdbTableImpl::validate(NdbError& error)
+{
+ if (aggregate(error) == -1)
+ return -1;
+ return 0;
+}
+
const void*
NdbTableImpl::getTablespaceNames() const
{
@@ -1064,6 +1073,54 @@ NdbTableImpl::get_nodes(Uint32 hashValue, const Uint16 ** nodes) const
}
return 0;
}
+
+int
+NdbDictionary::Table::checkColumns(const Uint32* map, Uint32 len) const
+{
+ int ret = 0;
+ Uint32 colCnt = m_impl.m_columns.size();
+ if (map == 0)
+ {
+ ret |= 1;
+ ret |= (m_impl.m_noOfDiskColumns) ? 2 : 0;
+ ret |= (colCnt > m_impl.m_noOfDiskColumns) ? 4 : 0;
+ return ret;
+ }
+
+ NdbColumnImpl** cols = m_impl.m_columns.getBase();
+ const char * ptr = reinterpret_cast<const char*>(map);
+ const char * end = ptr + len;
+ Uint32 no = 0;
+ while (ptr < end)
+ {
+ Uint32 val = (Uint32)* ptr;
+ Uint32 idx = 1;
+ for (Uint32 i = 0; i<8; i++)
+ {
+ if (val & idx)
+ {
+ if (cols[no]->getPrimaryKey())
+ ret |= 1;
+ else
+ {
+ if (cols[no]->getStorageType() == NdbDictionary::Column::StorageTypeDisk)
+ ret |= 2;
+ else
+ ret |= 4;
+ }
+ }
+ no ++;
+ idx *= 2;
+ if (no == colCnt)
+ return ret;
+ }
+
+ ptr++;
+ }
+ return ret;
+}
+
+
/**
* NdbIndexImpl
@@ -2113,9 +2170,9 @@ NdbDictInterface::parseTableInfo(NdbTableImpl ** ret,
col->m_storageType = attrDesc.AttributeStorageType;
col->m_pk = attrDesc.AttributeKeyFlag;
- col->m_distributionKey = attrDesc.AttributeDKey ? 2 : 0;
+ col->m_distributionKey = (attrDesc.AttributeDKey != 0);
col->m_nullable = attrDesc.AttributeNullableFlag;
- col->m_autoIncrement = (attrDesc.AttributeAutoIncrement ? true : false);
+ col->m_autoIncrement = (attrDesc.AttributeAutoIncrement != 0);
col->m_autoIncrementInitialValue = ~0;
col->m_defaultValue.assign(attrDesc.AttributeDefaultValue);
@@ -2606,7 +2663,7 @@ loop:
tmpAttr.AttributeId = col->m_attrId;
tmpAttr.AttributeKeyFlag = col->m_pk;
tmpAttr.AttributeNullableFlag = col->m_nullable;
- tmpAttr.AttributeDKey = distKeys ? (bool)col->m_distributionKey : 0;
+ tmpAttr.AttributeDKey = distKeys ? col->m_distributionKey : 0;
tmpAttr.AttributeExtType = (Uint32)col->m_type;
tmpAttr.AttributeExtPrecision = ((unsigned)col->m_precision & 0xFFFF);
diff --git a/storage/ndb/src/ndbapi/NdbDictionaryImpl.hpp b/storage/ndb/src/ndbapi/NdbDictionaryImpl.hpp
index 4e8ef471014..e5f68cfcc81 100644
--- a/storage/ndb/src/ndbapi/NdbDictionaryImpl.hpp
+++ b/storage/ndb/src/ndbapi/NdbDictionaryImpl.hpp
@@ -85,11 +85,7 @@ public:
CHARSET_INFO * m_cs; // not const in MySQL
bool m_pk;
- /*
- * Since "none" is "all" we distinguish between
- * 1-set by us, 2-set by user
- */
- Uint32 m_distributionKey;
+ bool m_distributionKey;
bool m_nullable;
bool m_autoIncrement;
Uint64 m_autoIncrementInitialValue;
@@ -159,6 +155,9 @@ public:
const char * getMysqlName() const;
void updateMysqlName();
+ int aggregate(NdbError& error);
+ int validate(NdbError& error);
+
Uint32 m_changeMask;
Uint32 m_primaryTableId;
BaseString m_internalName;
@@ -226,7 +225,7 @@ public:
// if all pk = dk then this is zero!
Uint8 m_noOfDistributionKeys;
Uint8 m_noOfBlobs;
-
+ Uint8 m_noOfDiskColumns;
Uint8 m_replicaCount;
/**
diff --git a/storage/ndb/src/ndbapi/NdbOperation.cpp b/storage/ndb/src/ndbapi/NdbOperation.cpp
index 769ce0662ef..e56c101d550 100644
--- a/storage/ndb/src/ndbapi/NdbOperation.cpp
+++ b/storage/ndb/src/ndbapi/NdbOperation.cpp
@@ -312,13 +312,31 @@ NdbOperation::setValue(Uint32 anAttrId, const char* aValuePassed)
NdbBlob*
NdbOperation::getBlobHandle(const char* anAttrName)
{
- return getBlobHandle(theNdbCon, m_currentTable->getColumn(anAttrName));
+ const NdbColumnImpl* col = m_currentTable->getColumn(anAttrName);
+ if (col == NULL)
+ {
+ setErrorCode(4004);
+ return NULL;
+ }
+ else
+ {
+ return getBlobHandle(theNdbCon, col);
+ }
}
NdbBlob*
NdbOperation::getBlobHandle(Uint32 anAttrId)
{
- return getBlobHandle(theNdbCon, m_currentTable->getColumn(anAttrId));
+ const NdbColumnImpl* col = m_currentTable->getColumn(anAttrId);
+ if (col == NULL)
+ {
+ setErrorCode(4004);
+ return NULL;
+ }
+ else
+ {
+ return getBlobHandle(theNdbCon, col);
+ }
}
int
diff --git a/storage/ndb/src/ndbapi/NdbScanOperation.cpp b/storage/ndb/src/ndbapi/NdbScanOperation.cpp
index 21e4f215c65..4c39d4ee342 100644
--- a/storage/ndb/src/ndbapi/NdbScanOperation.cpp
+++ b/storage/ndb/src/ndbapi/NdbScanOperation.cpp
@@ -174,7 +174,12 @@ NdbScanOperation::readTuples(NdbScanOperation::LockMode lm,
}
}
#endif
-
+ if (scan_flags & SF_DiskScan)
+ {
+ tupScan = true;
+ m_no_disk_flag = false;
+ }
+
bool rangeScan = false;
if (m_accessTable->m_indexType == NdbDictionary::Index::OrderedIndex)
{
@@ -525,6 +530,8 @@ int NdbScanOperation::nextResultImpl(bool fetchAllowed, bool forceSend)
int ret_code= poll_guard.wait_scan(3*timeout, nodeId, forceSend);
if (ret_code == 0 && seq == tp->getNodeSequence(nodeId)) {
continue;
+ } else if(ret_code == -1){
+ retVal = -1;
} else {
idx = last;
retVal = -2; //return_code;
@@ -694,9 +701,27 @@ void NdbScanOperation::close(bool forceSend, bool releaseOp)
theNdbCon = NULL;
m_transConnection = NULL;
- if (releaseOp && tTransCon) {
+ if (tTransCon)
+ {
NdbIndexScanOperation* tOp = (NdbIndexScanOperation*)this;
- tTransCon->releaseScanOperation(tOp);
+
+ bool ret = true;
+ if (theStatus != WaitResponse)
+ {
+ /**
+ * Not executed yet
+ */
+ ret =
+ tTransCon->releaseScanOperation(&tTransCon->m_theFirstScanOperation,
+ &tTransCon->m_theLastScanOperation,
+ tOp);
+ }
+ else if (releaseOp)
+ {
+ ret = tTransCon->releaseScanOperation(&tTransCon->m_firstExecutedScanOp,
+ 0, tOp);
+ }
+ assert(ret);
}
tCon->theScanningOp = 0;
@@ -1436,7 +1461,11 @@ NdbIndexScanOperation::next_result_ordered(bool fetchAllowed,
continue;
}
if(DEBUG_NEXT_RESULT) ndbout_c("return -1");
- setErrorCode(4028);
+ if(ret_code == -1){
+ setErrorCode(4008);
+ } else {
+ setErrorCode(4028);
+ }
return -1;
}
diff --git a/storage/ndb/src/ndbapi/NdbTransaction.cpp b/storage/ndb/src/ndbapi/NdbTransaction.cpp
index 9788b9bdce6..dad866ff453 100644
--- a/storage/ndb/src/ndbapi/NdbTransaction.cpp
+++ b/storage/ndb/src/ndbapi/NdbTransaction.cpp
@@ -978,52 +978,61 @@ void releaseScanOperation();
Remark: Release scan op when hupp'ed trans closed (save memory)
******************************************************************************/
void
-NdbTransaction::releaseScanOperation(NdbIndexScanOperation* cursorOp)
+NdbTransaction::releaseExecutedScanOperation(NdbIndexScanOperation* cursorOp)
{
- DBUG_ENTER("NdbTransaction::releaseScanOperation");
+ DBUG_ENTER("NdbTransaction::releaseExecutedScanOperation");
DBUG_PRINT("enter", ("this=0x%x op=0x%x", (UintPtr)this, (UintPtr)cursorOp));
+
+ releaseScanOperation(&m_firstExecutedScanOp, 0, cursorOp);
+
+ DBUG_VOID_RETURN;
+}//NdbTransaction::releaseExecutedScanOperation()
- // here is one reason to make op lists doubly linked
- if (cursorOp->m_executed)
+bool
+NdbTransaction::releaseScanOperation(NdbIndexScanOperation** listhead,
+ NdbIndexScanOperation** listtail,
+ NdbIndexScanOperation* op)
+{
+ if (* listhead == op)
{
- if (m_firstExecutedScanOp == cursorOp) {
- m_firstExecutedScanOp = (NdbIndexScanOperation*)cursorOp->theNext;
- cursorOp->release();
- theNdb->releaseScanOperation(cursorOp);
- } else if (m_firstExecutedScanOp != NULL) {
- NdbIndexScanOperation* tOp = m_firstExecutedScanOp;
- while (tOp->theNext != NULL) {
- if (tOp->theNext == cursorOp) {
- tOp->theNext = cursorOp->theNext;
- cursorOp->release();
- theNdb->releaseScanOperation(cursorOp);
- break;
- }
- tOp = (NdbIndexScanOperation*)tOp->theNext;
- }
+ * listhead = (NdbIndexScanOperation*)op->theNext;
+ if (listtail && *listtail == op)
+ {
+ assert(* listhead == 0);
+ * listtail = 0;
}
+
}
else
{
- if (m_theFirstScanOperation == cursorOp) {
- m_theFirstScanOperation = (NdbIndexScanOperation*)cursorOp->theNext;
- cursorOp->release();
- theNdb->releaseScanOperation(cursorOp);
- } else if (m_theFirstScanOperation != NULL) {
- NdbIndexScanOperation* tOp = m_theFirstScanOperation;
- while (tOp->theNext != NULL) {
- if (tOp->theNext == cursorOp) {
- tOp->theNext = cursorOp->theNext;
- cursorOp->release();
- theNdb->releaseScanOperation(cursorOp);
- break;
- }
- tOp = (NdbIndexScanOperation*)tOp->theNext;
+ NdbIndexScanOperation* tmp = * listhead;
+ while (tmp != NULL)
+ {
+ if (tmp->theNext == op)
+ {
+ tmp->theNext = (NdbIndexScanOperation*)op->theNext;
+ if (listtail && *listtail == op)
+ {
+ assert(op->theNext == 0);
+ *listtail = tmp;
+ }
+ break;
}
+ tmp = (NdbIndexScanOperation*)tmp->theNext;
}
+ if (tmp == NULL)
+ op = NULL;
}
- DBUG_VOID_RETURN;
-}//NdbTransaction::releaseScanOperation()
+
+ if (op != NULL)
+ {
+ op->release();
+ theNdb->releaseScanOperation(op);
+ return true;
+ }
+
+ return false;
+}
/*****************************************************************************
NdbOperation* getNdbOperation(const char* aTableName);
diff --git a/storage/ndb/src/ndbapi/ndberror.c b/storage/ndb/src/ndbapi/ndberror.c
index 460c4fa443b..083830e8b44 100644
--- a/storage/ndb/src/ndbapi/ndberror.c
+++ b/storage/ndb/src/ndbapi/ndberror.c
@@ -442,7 +442,7 @@ ErrorBundle ErrorCodes[] = {
{ 1305, DMEC, IE, "Backup definition not implemented" },
{ 1306, DMEC, AE, "Backup not supported in diskless mode (change Diskless)" },
- { 1321, DMEC, IE, "Backup aborted by application" },
+ { 1321, DMEC, UD, "Backup aborted by user request" },
{ 1322, DMEC, IE, "Backup already completed" },
{ 1323, DMEC, IE, "1323" },
{ 1324, DMEC, IE, "Backup log buffer full" },
@@ -489,7 +489,7 @@ ErrorBundle ErrorCodes[] = {
{ 1420, DMEC, TR, "Subscriber manager busy with adding/removing a table" },
- { 4004, DMEC, AE, "Attribute name not found in the Table" },
+ { 4004, DMEC, AE, "Attribute name or id not found in the table" },
{ 4100, DMEC, AE, "Status Error in NDB" },
{ 4101, DMEC, AE, "No connections to NDB available and connect failed" },
diff --git a/storage/ndb/test/include/NDBT_Table.hpp b/storage/ndb/test/include/NDBT_Table.hpp
index 93dc5a1b994..2b679166cb3 100644
--- a/storage/ndb/test/include/NDBT_Table.hpp
+++ b/storage/ndb/test/include/NDBT_Table.hpp
@@ -65,6 +65,11 @@ public:
//setStoredTable(stored);
for(int i = 0; i<noOfAttributes; i++)
addColumn(attributes[i]);
+
+ // validate() might cause initialization order problem with charset
+ NdbError error;
+ int ret = aggregate(error);
+ assert(ret == 0);
}
static const NdbDictionary::Table * discoverTableFromDb(Ndb* ndb,
diff --git a/storage/ndb/test/ndbapi/flexScan.cpp b/storage/ndb/test/ndbapi/flexScan.cpp
index 4d2c85d6955..1f001bd0210 100644
--- a/storage/ndb/test/ndbapi/flexScan.cpp
+++ b/storage/ndb/test/ndbapi/flexScan.cpp
@@ -27,7 +27,7 @@
verify delete
Arguments:
- -f Location of Ndb.cfg file, default Ndb.cfg
+ -f Location of my.cnf file, default my.cnf
-t Number of threads to start, default 1
-o Number of operations per loop, default 500 -l Number of loops to run, default 1, 0=infinite
-a Number of attributes, default 25
@@ -829,7 +829,7 @@ static int createTables(Ndb* pMyNdb)
static void printUsage()
{
ndbout << "Usage of flexScan:" << endl;
- ndbout << "-f <path> Location of Ndb.cfg file, default: Ndb.cfg" << endl;
+ ndbout << "-f <path> Location of my.cnf file, default: my.cnf" << endl;
ndbout << "-t <int> Number of threads to start, default 1" << endl;
ndbout << "-o <int> Number of operations per loop, default 500" << endl;
ndbout << "-l <int> Number of loops to run, default 1, 0=infinite" << endl;
diff --git a/storage/ndb/test/ndbapi/testMgm.cpp b/storage/ndb/test/ndbapi/testMgm.cpp
index ef653d3f972..cd0efb34a97 100644
--- a/storage/ndb/test/ndbapi/testMgm.cpp
+++ b/storage/ndb/test/ndbapi/testMgm.cpp
@@ -21,6 +21,8 @@
#include <NdbRestarter.hpp>
#include <Vector.hpp>
#include <random.h>
+#include <mgmapi.h>
+#include <mgmapi_debug.h>
int runLoadTable(NDBT_Context* ctx, NDBT_Step* step){
@@ -167,6 +169,44 @@ int runTestSingleUserMode(NDBT_Context* ctx, NDBT_Step* step){
return result;
}
+int runTestApiSession(NDBT_Context* ctx, NDBT_Step* step)
+{
+ char *mgm= ctx->getRemoteMgm();
+ Uint64 session_id= 0;
+
+ NdbMgmHandle h;
+ h= ndb_mgm_create_handle();
+ ndb_mgm_set_connectstring(h, mgm);
+ ndb_mgm_connect(h,0,0,0);
+ int s= ndb_mgm_get_fd(h);
+ session_id= ndb_mgm_get_session_id(h);
+ ndbout << "MGM Session id: " << session_id << endl;
+ write(s,"get",3);
+ ndb_mgm_disconnect(h);
+ ndb_mgm_destroy_handle(&h);
+
+ struct NdbMgmSession sess;
+ int slen= sizeof(struct NdbMgmSession);
+
+ h= ndb_mgm_create_handle();
+ ndb_mgm_set_connectstring(h, mgm);
+ ndb_mgm_connect(h,0,0,0);
+
+ if(ndb_mgm_get_session(h,session_id,&sess,&slen))
+ {
+ ndbout << "Failed, session still exists" << endl;
+ ndb_mgm_disconnect(h);
+ ndb_mgm_destroy_handle(&h);
+ return NDBT_FAILED;
+ }
+ else
+ {
+ ndbout << "SUCCESS: session is gone" << endl;
+ ndb_mgm_disconnect(h);
+ ndb_mgm_destroy_handle(&h);
+ return NDBT_OK;
+ }
+}
NDBT_TESTSUITE(testMgm);
@@ -175,6 +215,11 @@ TESTCASE("SingleUserMode",
INITIALIZER(runTestSingleUserMode);
FINALIZER(runClearTable);
}
+TESTCASE("ApiSessionFailure",
+ "Test failures in MGMAPI session"){
+ INITIALIZER(runTestApiSession);
+
+}
NDBT_TESTSUITE_END(testMgm);
int main(int argc, const char** argv){
diff --git a/storage/ndb/test/ndbapi/testTimeout.cpp b/storage/ndb/test/ndbapi/testTimeout.cpp
index 36fb34a50e2..e719cdf03e9 100644
--- a/storage/ndb/test/ndbapi/testTimeout.cpp
+++ b/storage/ndb/test/ndbapi/testTimeout.cpp
@@ -388,6 +388,45 @@ int runBuddyTransNoTimeout(NDBT_Context* ctx, NDBT_Step* step){
return result;
}
+int runBuddyTransTimeout(NDBT_Context* ctx, NDBT_Step* step){
+ int result = NDBT_OK;
+ int loops = ctx->getNumLoops();
+ int records = ctx->getNumRecords();
+ int stepNo = step->getStepNo();
+ ndbout << "TransactionInactiveTimeout="<< TIMEOUT <<endl;
+
+ HugoOperations hugoOps(*ctx->getTab());
+ Ndb* pNdb = GETNDB(step);
+
+ for (int l = 1; l < loops && result == NDBT_OK; l++){
+
+ NdbTransaction* pTrans = 0;
+ do{
+ pTrans = pNdb->startTransaction();
+ NdbScanOperation* pOp = pTrans->getNdbScanOperation(ctx->getTab());
+ CHECK(pOp->readTuples(NdbOperation::LM_Read, 0, 0, 1) == 0);
+ CHECK(pTrans->execute(NoCommit) == 0);
+
+ int sleep = 2 * TIMEOUT;
+ ndbout << "Sleeping for " << sleep << " milliseconds" << endl;
+ NdbSleep_MilliSleep(sleep);
+
+ int res = 0;
+ while((res = pOp->nextResult()) == 0);
+ ndbout_c("res: %d", res);
+ CHECK(res == -1);
+
+ } while(false);
+
+ if (pTrans)
+ {
+ pTrans->close();
+ }
+ }
+
+ return result;
+}
+
int
runError4012(NDBT_Context* ctx, NDBT_Step* step){
int result = NDBT_OK;
@@ -495,6 +534,15 @@ TESTCASE("BuddyTransNoTimeout5",
FINALIZER(resetTransactionTimeout);
FINALIZER(runClearTable);
}
+TESTCASE("BuddyTransTimeout1",
+ "Start a scan and check that it gets aborted"){
+ INITIALIZER(runLoadTable);
+ INITIALIZER(setTransactionTimeout);
+ STEPS(runBuddyTransTimeout, 1);
+ FINALIZER(resetTransactionTimeout);
+ FINALIZER(runClearTable);
+}
+#if 0
TESTCASE("Error4012", ""){
TC_PROPERTY("TransactionDeadlockTimeout", 120000);
INITIALIZER(runLoadTable);
@@ -503,7 +551,7 @@ TESTCASE("Error4012", ""){
STEPS(runError4012, 2);
FINALIZER(runClearTable);
}
-
+#endif
NDBT_TESTSUITE_END(testTimeout);
int main(int argc, const char** argv){
diff --git a/storage/ndb/test/src/NDBT_Tables.cpp b/storage/ndb/test/src/NDBT_Tables.cpp
index 0f0fcf6ab36..520892f17da 100644
--- a/storage/ndb/test/src/NDBT_Tables.cpp
+++ b/storage/ndb/test/src/NDBT_Tables.cpp
@@ -977,6 +977,11 @@ NDBT_Tables::createTable(Ndb* pNdb, const char* _name, bool _temp,
do {
NdbDictionary::Table tmpTab(* tab);
tmpTab.setStoredTable(_temp ? 0 : 1);
+ {
+ NdbError error;
+ int ret = tmpTab.validate(error);
+ assert(ret == 0);
+ }
if(f != 0 && f(pNdb, tmpTab, 0, arg))
{
ndbout << "Failed to create table" << endl;
diff --git a/storage/ndb/tools/delete_all.cpp b/storage/ndb/tools/delete_all.cpp
index fcf9b425bd0..95c3c7be0ce 100644
--- a/storage/ndb/tools/delete_all.cpp
+++ b/storage/ndb/tools/delete_all.cpp
@@ -27,8 +27,12 @@ static int clear_table(Ndb* pNdb, const NdbDictionary::Table* pTab,
NDB_STD_OPTS_VARS;
+const char *load_default_groups[]= { "mysql_cluster",0 };
+
static const char* _dbname = "TEST_DB";
static my_bool _transactional = false;
+static my_bool _tupscan = 0;
+static my_bool _diskscan = 0;
static struct my_option my_long_options[] =
{
NDB_STD_OPTS("ndb_desc"),
@@ -38,6 +42,12 @@ static struct my_option my_long_options[] =
{ "transactional", 't', "Single transaction (may run out of operations)",
(gptr*) &_transactional, (gptr*) &_transactional, 0,
GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0 },
+ { "tupscan", 999, "Run tupscan",
+ (gptr*) &_tupscan, (gptr*) &_tupscan, 0,
+ GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0 },
+ { "diskscan", 999, "Run diskcan",
+ (gptr*) &_diskscan, (gptr*) &_diskscan, 0,
+ GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0 },
{ 0, 0, 0, 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}
};
static void usage()
@@ -46,13 +56,14 @@ static void usage()
"tabname\n"\
"This program will delete all records in the specified table using scan delete.\n";
ndb_std_print_version();
+ print_defaults(MYSQL_CONFIG_NAME,load_default_groups);
+ puts("");
my_print_help(my_long_options);
my_print_variables(my_long_options);
}
int main(int argc, char** argv){
NDB_INIT(argv[0]);
- const char *load_default_groups[]= { "mysql_cluster",0 };
load_defaults("my",load_default_groups,&argc,&argv);
int ho_error;
#ifndef DBUG_OFF
@@ -139,8 +150,11 @@ int clear_table(Ndb* pNdb, const NdbDictionary::Table* pTab,
goto failed;
}
+ int flags = 0;
+ flags |= _tupscan ? NdbScanOperation::SF_TupScan : 0;
+ flags |= _diskscan ? NdbScanOperation::SF_DiskScan : 0;
if( pOp->readTuples(NdbOperation::LM_Exclusive,
- NdbScanOperation::SF_TupScan, par) ) {
+ flags, par) ) {
goto failed;
}
diff --git a/storage/ndb/tools/desc.cpp b/storage/ndb/tools/desc.cpp
index 49f188d12c0..c042f745d9d 100644
--- a/storage/ndb/tools/desc.cpp
+++ b/storage/ndb/tools/desc.cpp
@@ -32,6 +32,9 @@ NDB_STD_OPTS_VARS;
static const char* _dbname = "TEST_DB";
static int _unqualified = 0;
static int _partinfo = 0;
+
+const char *load_default_groups[]= { "mysql_cluster",0 };
+
static int _retries = 0;
static struct my_option my_long_options[] =
{
@@ -57,6 +60,8 @@ static void usage()
"This program list all properties of table(s) in NDB Cluster.\n"\
" ex: desc T1 T2 T4\n";
ndb_std_print_version();
+ print_defaults(MYSQL_CONFIG_NAME,load_default_groups);
+ puts("");
my_print_help(my_long_options);
my_print_variables(my_long_options);
}
@@ -65,7 +70,6 @@ static void print_part_info(Ndb* pNdb, NDBT_Table* pTab);
int main(int argc, char** argv){
NDB_INIT(argv[0]);
- const char *load_default_groups[]= { "mysql_cluster",0 };
load_defaults("my",load_default_groups,&argc,&argv);
int ho_error;
#ifndef DBUG_OFF
diff --git a/storage/ndb/tools/drop_index.cpp b/storage/ndb/tools/drop_index.cpp
index 24116f22784..aa207212dbe 100644
--- a/storage/ndb/tools/drop_index.cpp
+++ b/storage/ndb/tools/drop_index.cpp
@@ -24,6 +24,9 @@
NDB_STD_OPTS_VARS;
static const char* _dbname = "TEST_DB";
+
+const char *load_default_groups[]= { "mysql_cluster",0 };
+
static struct my_option my_long_options[] =
{
NDB_STD_OPTS("ndb_desc"),
@@ -38,13 +41,14 @@ static void usage()
"[<table> <index>]+\n"\
"This program will drop index(es) in Ndb\n";
ndb_std_print_version();
+ print_defaults(MYSQL_CONFIG_NAME,load_default_groups);
+ puts("");
my_print_help(my_long_options);
my_print_variables(my_long_options);
}
int main(int argc, char** argv){
NDB_INIT(argv[0]);
- const char *load_default_groups[]= { "mysql_cluster",0 };
load_defaults("my",load_default_groups,&argc,&argv);
int ho_error;
#ifndef DBUG_OFF
diff --git a/storage/ndb/tools/drop_tab.cpp b/storage/ndb/tools/drop_tab.cpp
index 991e1505486..d14c60a2c6d 100644
--- a/storage/ndb/tools/drop_tab.cpp
+++ b/storage/ndb/tools/drop_tab.cpp
@@ -24,6 +24,9 @@
NDB_STD_OPTS_VARS;
static const char* _dbname = "TEST_DB";
+
+const char *load_default_groups[]= { "mysql_cluster",0 };
+
static struct my_option my_long_options[] =
{
NDB_STD_OPTS("ndb_desc"),
@@ -37,14 +40,15 @@ static void usage()
char desc[] =
"tabname\n"\
"This program will drop one table in Ndb\n";
- ndb_std_print_version();
+ ndb_std_print_version();
+ print_defaults(MYSQL_CONFIG_NAME,load_default_groups);
+ puts("");
my_print_help(my_long_options);
my_print_variables(my_long_options);
}
int main(int argc, char** argv){
NDB_INIT(argv[0]);
- const char *load_default_groups[]= { "mysql_cluster",0 };
load_defaults("my",load_default_groups,&argc,&argv);
int ho_error;
#ifndef DBUG_OFF
diff --git a/storage/ndb/tools/listTables.cpp b/storage/ndb/tools/listTables.cpp
index 0e32d802d2d..3c891041879 100644
--- a/storage/ndb/tools/listTables.cpp
+++ b/storage/ndb/tools/listTables.cpp
@@ -34,6 +34,8 @@ static int _unqualified = 0;
static int _parsable = 0;
static int show_temp_status = 0;
+const char *load_default_groups[]= { "mysql_cluster",0 };
+
static void
fatal(char const* fmt, ...)
{
@@ -284,6 +286,8 @@ static void usage()
"To show all indexes for a table write table name as final argument\n"\
" ex: ndb_show_tables T1\n";
ndb_std_print_version();
+ print_defaults(MYSQL_CONFIG_NAME,load_default_groups);
+ puts("");
my_print_help(my_long_options);
my_print_variables(my_long_options);
}
@@ -291,7 +295,6 @@ static void usage()
int main(int argc, char** argv){
NDB_INIT(argv[0]);
const char* _tabname;
- const char *load_default_groups[]= { "mysql_cluster",0 };
load_defaults("my",load_default_groups,&argc,&argv);
int ho_error;
#ifndef DBUG_OFF
diff --git a/storage/ndb/tools/ndb_condig.cpp b/storage/ndb/tools/ndb_condig.cpp
index 135bec7ef72..8b862391c8e 100644
--- a/storage/ndb/tools/ndb_condig.cpp
+++ b/storage/ndb/tools/ndb_condig.cpp
@@ -19,6 +19,8 @@
*/
#include <ndb_global.h>
+#include <ndb_opts.h>
+
#include <my_sys.h>
#include <my_getopt.h>
#include <mysql_version.h>
@@ -29,6 +31,7 @@
#include <mgmapi.h>
#include <mgmapi_configuration.hpp>
#include <ConfigInfo.hpp>
+#include <NdbAutoPtr.hpp>
static int g_verbose = 0;
static int try_reconnect = 3;
@@ -45,34 +48,17 @@ static const char * g_row_delimiter=" ";
static const char * g_config_file = 0;
static int g_mycnf = 0;
-int g_print_full_config, opt_ndb_shm;
-my_bool opt_core;
+const char *load_default_groups[]= { "mysql_cluster",0 };
-typedef ndb_mgm_configuration_iterator Iter;
+NDB_STD_OPTS_VARS;
-static void ndb_std_print_version()
-{
- printf("MySQL distrib %s, for %s (%s)\n",
- MYSQL_SERVER_VERSION,SYSTEM_TYPE,MACHINE_TYPE);
-}
+int g_print_full_config;
+
+typedef ndb_mgm_configuration_iterator Iter;
static struct my_option my_long_options[] =
{
- { "usage", '?', "Display this help and exit.",
- 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0 },
- { "help", '?', "Display this help and exit.",
- 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0 },
- { "version", 'V', "Output version information and exit.", 0, 0, 0,
- GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0 },
- { "ndb-connectstring", 256,
- "Set connect string for connecting to ndb_mgmd. "
- "Syntax: \"[nodeid=<id>;][host=]<hostname>[:<port>]\". "
- "Overides specifying entries in NDB_CONNECTSTRING and Ndb.cfg",
- (gptr*) &g_connectstring, (gptr*) &g_connectstring,
- 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0 },
- { "ndb-shm", 256, "Print nodes",
- (gptr*) &opt_ndb_shm, (gptr*) &opt_ndb_shm,
- 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
+ NDB_STD_OPTS("ndb_config"),
{ "nodes", 256, "Print nodes",
(gptr*) &g_nodes, (gptr*) &g_nodes,
0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
@@ -114,24 +100,11 @@ static void usage()
char desc[] =
"This program will retreive config options for a ndb cluster\n";
ndb_std_print_version();
+ print_defaults(MYSQL_CONFIG_NAME,load_default_groups);
+ puts("");
my_print_help(my_long_options);
my_print_variables(my_long_options);
}
-static my_bool
-ndb_std_get_one_option(int optid,
- const struct my_option *opt __attribute__((unused)),
- char *argument)
-{
- switch (optid) {
- case 'V':
- ndb_std_print_version();
- exit(0);
- case '?':
- usage();
- exit(0);
- }
- return 0;
-}
/**
* Match/Apply framework
@@ -176,7 +149,6 @@ static ndb_mgm_configuration* load_configuration();
int
main(int argc, char** argv){
NDB_INIT(argv[0]);
- const char *load_default_groups[]= { "mysql_cluster",0 };
load_defaults("my",load_default_groups,&argc,&argv);
int ho_error;
if ((ho_error=handle_options(&argc, &argv, my_long_options,
@@ -408,28 +380,36 @@ HostMatch::eval(const Iter& iter)
if(iter.get(m_key, &valc) == 0)
{
- struct hostent *h1, *h2;
+ struct hostent *h1, *h2, copy1;
+ char *addr1;
h1 = gethostbyname(m_value.c_str());
if (h1 == NULL) {
return 0;
}
+ // gethostbyname returns a pointer to a static structure
+ // so we need to copy the results before doing the next call
+ memcpy(&copy1, h1, sizeof(struct hostent));
+ addr1 = (char *)malloc(copy1.h_length);
+ NdbAutoPtr<char> tmp_aptr(addr1);
+ memcpy(addr1, h1->h_addr, copy1.h_length);
+
h2 = gethostbyname(valc);
if (h2 == NULL) {
return 0;
}
- if (h1->h_addrtype != h2->h_addrtype) {
+ if (copy1.h_addrtype != h2->h_addrtype) {
return 0;
}
- if (h1->h_length != h2->h_length)
+ if (copy1.h_length != h2->h_length)
{
return 0;
}
- return 0 == memcmp(h1->h_addr, h2->h_addr, h1->h_length);
+ return 0 == memcmp(addr1, h2->h_addr, copy1.h_length);
}
return 0;
diff --git a/storage/ndb/tools/restore/consumer.hpp b/storage/ndb/tools/restore/consumer.hpp
index 5a09bf54270..d5c6d38985a 100644
--- a/storage/ndb/tools/restore/consumer.hpp
+++ b/storage/ndb/tools/restore/consumer.hpp
@@ -39,6 +39,7 @@ public:
virtual bool update_apply_status(const RestoreMetaData &metaData){return true;}
NODE_GROUP_MAP *m_nodegroup_map;
uint m_nodegroup_map_len;
+ virtual bool has_temp_error() {return false;}
};
#endif
diff --git a/storage/ndb/tools/restore/consumer_restore.cpp b/storage/ndb/tools/restore/consumer_restore.cpp
index 44f4b770b05..507058e2743 100644
--- a/storage/ndb/tools/restore/consumer_restore.cpp
+++ b/storage/ndb/tools/restore/consumer_restore.cpp
@@ -607,6 +607,11 @@ BackupRestore::object(Uint32 type, const void * ptr)
}
bool
+BackupRestore::has_temp_error(){
+ return m_temp_error;
+}
+
+bool
BackupRestore::update_apply_status(const RestoreMetaData &metaData)
{
if (!m_restore_epoch)
@@ -1100,6 +1105,7 @@ bool BackupRestore::errorHandler(restore_callback_t *cb)
case NdbError::TemporaryError:
err << "Temporary error: " << error << endl;
+ m_temp_error = true;
NdbSleep_MilliSleep(sleepTime);
return true;
// RETRY
diff --git a/storage/ndb/tools/restore/consumer_restore.hpp b/storage/ndb/tools/restore/consumer_restore.hpp
index 4389f71724e..c1d9472aea0 100644
--- a/storage/ndb/tools/restore/consumer_restore.hpp
+++ b/storage/ndb/tools/restore/consumer_restore.hpp
@@ -51,6 +51,7 @@ public:
m_parallelism = parallelism;
m_callback = 0;
m_free_callback = 0;
+ m_temp_error = false;
m_transactions = 0;
m_cache.m_old_table = 0;
}
@@ -71,6 +72,7 @@ public:
virtual void logEntry(const LogEntry &);
virtual void endOfLogEntrys();
virtual bool finalize_table(const TableS &);
+ virtual bool has_temp_error();
virtual bool update_apply_status(const RestoreMetaData &metaData);
void connectToMysql();
bool map_in_frm(char *new_data, const char *data,
@@ -96,6 +98,7 @@ public:
restore_callback_t *m_callback;
restore_callback_t *m_free_callback;
+ bool m_temp_error;
/**
* m_new_table_ids[X] = Y;
diff --git a/storage/ndb/tools/restore/restore_main.cpp b/storage/ndb/tools/restore/restore_main.cpp
index d76cf441dd6..c6947f3bf01 100644
--- a/storage/ndb/tools/restore/restore_main.cpp
+++ b/storage/ndb/tools/restore/restore_main.cpp
@@ -60,6 +60,8 @@ static int _restore_meta = 0;
static int _no_restore_disk = 0;
BaseString g_options("ndb_restore");
+const char *load_default_groups[]= { "mysql_cluster","ndb_restore",0 };
+
static struct my_option my_long_options[] =
{
NDB_STD_OPTS("ndb_restore"),
@@ -240,6 +242,8 @@ static void usage()
{
short_usage_sub();
ndb_std_print_version();
+ print_defaults(MYSQL_CONFIG_NAME,load_default_groups);
+ puts("");
my_print_help(my_long_options);
my_print_variables(my_long_options);
}
@@ -668,6 +672,7 @@ main(int argc, char** argv)
}
}
}
+
if (ga_restore_epoch)
{
for (i= 0; i < g_consumers.size(); i++)
@@ -678,6 +683,16 @@ main(int argc, char** argv)
}
}
+ for(Uint32 i= 0; i < g_consumers.size(); i++)
+ {
+ if (g_consumers[i]->has_temp_error())
+ {
+ clearConsumers();
+ ndbout_c("\nRestore successful, but encountered temporary error, "
+ "please look at configuration.");
+ }
+ }
+
clearConsumers();
return NDBT_ProgramExit(NDBT_OK);
} // main
diff --git a/storage/ndb/tools/select_all.cpp b/storage/ndb/tools/select_all.cpp
index fecb55cf734..87a083dad90 100644
--- a/storage/ndb/tools/select_all.cpp
+++ b/storage/ndb/tools/select_all.cpp
@@ -43,6 +43,8 @@ static const char* _delimiter = "\t";
static int _unqualified, _header, _parallelism, _useHexFormat, _lock,
_order, _descending;
+const char *load_default_groups[]= { "mysql_cluster",0 };
+
static int _tup = 0;
static int _dumpDisk = 0;
static int use_rowid = 0;
@@ -103,13 +105,14 @@ static void usage()
"It can also be used to dump the content of a table to file \n"\
" ex: select_all --no-header --delimiter=';' T4 > T4.data\n";
ndb_std_print_version();
+ print_defaults(MYSQL_CONFIG_NAME,load_default_groups);
+ puts("");
my_print_help(my_long_options);
my_print_variables(my_long_options);
}
int main(int argc, char** argv){
NDB_INIT(argv[0]);
- const char *load_default_groups[]= { "mysql_cluster",0 };
load_defaults("my",load_default_groups,&argc,&argv);
const char* _tabname;
int ho_error;
diff --git a/storage/ndb/tools/select_count.cpp b/storage/ndb/tools/select_count.cpp
index 6fa3c77f15a..0d5d4684878 100644
--- a/storage/ndb/tools/select_count.cpp
+++ b/storage/ndb/tools/select_count.cpp
@@ -37,6 +37,9 @@ NDB_STD_OPTS_VARS;
static const char* _dbname = "TEST_DB";
static int _parallelism = 240;
static int _lock = 0;
+
+const char *load_default_groups[]= { "mysql_cluster",0 };
+
static struct my_option my_long_options[] =
{
NDB_STD_OPTS("ndb_desc"),
@@ -57,13 +60,14 @@ static void usage()
"tabname1 ... tabnameN\n"\
"This program will count the number of records in tables\n";
ndb_std_print_version();
+ print_defaults(MYSQL_CONFIG_NAME,load_default_groups);
+ puts("");
my_print_help(my_long_options);
my_print_variables(my_long_options);
}
int main(int argc, char** argv){
NDB_INIT(argv[0]);
- const char *load_default_groups[]= { "mysql_cluster",0 };
load_defaults("my",load_default_groups,&argc,&argv);
int ho_error;
#ifndef DBUG_OFF
diff --git a/storage/ndb/tools/waiter.cpp b/storage/ndb/tools/waiter.cpp
index e3d8733b0ed..c34463fba0e 100644
--- a/storage/ndb/tools/waiter.cpp
+++ b/storage/ndb/tools/waiter.cpp
@@ -38,6 +38,9 @@ NDB_STD_OPTS_VARS;
static int _no_contact = 0;
static int _not_started = 0;
static int _timeout = 120;
+
+const char *load_default_groups[]= { "mysql_cluster",0 };
+
static struct my_option my_long_options[] =
{
NDB_STD_OPTS("ndb_desc"),
@@ -56,13 +59,14 @@ static struct my_option my_long_options[] =
static void usage()
{
ndb_std_print_version();
+ print_defaults(MYSQL_CONFIG_NAME,load_default_groups);
+ puts("");
my_print_help(my_long_options);
my_print_variables(my_long_options);
}
int main(int argc, char** argv){
NDB_INIT(argv[0]);
- const char *load_default_groups[]= { "mysql_cluster",0 };
load_defaults("my",load_default_groups,&argc,&argv);
const char* _hostName = NULL;
int ho_error;
diff --git a/strings/ctype-big5.c b/strings/ctype-big5.c
index 3f604abde2e..d2dacf2d0a3 100644
--- a/strings/ctype-big5.c
+++ b/strings/ctype-big5.c
@@ -6371,6 +6371,7 @@ static MY_CHARSET_HANDLER my_charset_big5_handler=
my_strntoull_8bit,
my_strntod_8bit,
my_strtoll10_8bit,
+ my_strntoull10rnd_8bit,
my_scan_8bit
};
diff --git a/strings/ctype-bin.c b/strings/ctype-bin.c
index e35aee79fd1..5758960ef6c 100644
--- a/strings/ctype-bin.c
+++ b/strings/ctype-bin.c
@@ -518,6 +518,7 @@ static MY_CHARSET_HANDLER my_charset_handler=
my_strntoull_8bit,
my_strntod_8bit,
my_strtoll10_8bit,
+ my_strntoull10rnd_8bit,
my_scan_8bit
};
diff --git a/strings/ctype-cp932.c b/strings/ctype-cp932.c
index a1c2812c6f6..4b9d09e06b5 100644
--- a/strings/ctype-cp932.c
+++ b/strings/ctype-cp932.c
@@ -5493,6 +5493,7 @@ static MY_CHARSET_HANDLER my_charset_handler=
my_strntoull_8bit,
my_strntod_8bit,
my_strtoll10_8bit,
+ my_strntoull10rnd_8bit,
my_scan_8bit
};
diff --git a/strings/ctype-euc_kr.c b/strings/ctype-euc_kr.c
index 6dc5ccdfe2a..82189d64b6c 100644
--- a/strings/ctype-euc_kr.c
+++ b/strings/ctype-euc_kr.c
@@ -8712,6 +8712,7 @@ static MY_CHARSET_HANDLER my_charset_handler=
my_strntoull_8bit,
my_strntod_8bit,
my_strtoll10_8bit,
+ my_strntoull10rnd_8bit,
my_scan_8bit
};
diff --git a/strings/ctype-eucjpms.c b/strings/ctype-eucjpms.c
index 0f59cc2b305..4d09bc0e01e 100644
--- a/strings/ctype-eucjpms.c
+++ b/strings/ctype-eucjpms.c
@@ -8678,6 +8678,7 @@ static MY_CHARSET_HANDLER my_charset_handler=
my_strntoull_8bit,
my_strntod_8bit,
my_strtoll10_8bit,
+ my_strntoull10rnd_8bit,
my_scan_8bit
};
diff --git a/strings/ctype-gb2312.c b/strings/ctype-gb2312.c
index 8d0bc80e695..8c85c0e79d3 100644
--- a/strings/ctype-gb2312.c
+++ b/strings/ctype-gb2312.c
@@ -5763,6 +5763,7 @@ static MY_CHARSET_HANDLER my_charset_handler=
my_strntoull_8bit,
my_strntod_8bit,
my_strtoll10_8bit,
+ my_strntoull10rnd_8bit,
my_scan_8bit
};
diff --git a/strings/ctype-gbk.c b/strings/ctype-gbk.c
index 7eb332da3bd..20deab9be6c 100644
--- a/strings/ctype-gbk.c
+++ b/strings/ctype-gbk.c
@@ -10016,6 +10016,7 @@ static MY_CHARSET_HANDLER my_charset_handler=
my_strntoull_8bit,
my_strntod_8bit,
my_strtoll10_8bit,
+ my_strntoull10rnd_8bit,
my_scan_8bit
};
diff --git a/strings/ctype-latin1.c b/strings/ctype-latin1.c
index 95ea87114d6..2c326a2826e 100644
--- a/strings/ctype-latin1.c
+++ b/strings/ctype-latin1.c
@@ -412,6 +412,7 @@ static MY_CHARSET_HANDLER my_charset_handler=
my_strntoull_8bit,
my_strntod_8bit,
my_strtoll10_8bit,
+ my_strntoull10rnd_8bit,
my_scan_8bit
};
diff --git a/strings/ctype-simple.c b/strings/ctype-simple.c
index a9fd5b8852e..9b45d5a03b7 100644
--- a/strings/ctype-simple.c
+++ b/strings/ctype-simple.c
@@ -17,6 +17,7 @@
#include <my_global.h>
#include "m_string.h"
#include "m_ctype.h"
+#include "my_sys.h" /* Needed for MY_ERRNO_ERANGE */
#include <errno.h>
#include "stdarg.h"
@@ -1367,6 +1368,341 @@ int my_mb_ctype_8bit(CHARSET_INFO *cs, int *ctype,
}
+#undef ULONGLONG_MAX
+/*
+ Needed under MetroWerks Compiler, since MetroWerks compiler does not
+ properly handle a constant expression containing a mod operator
+*/
+#if defined(__NETWARE__) && defined(__MWERKS__)
+static ulonglong ulonglong_max= ~(ulonglong) 0;
+#define ULONGLONG_MAX ulonglong_max
+#else
+#define ULONGLONG_MAX (~(ulonglong) 0)
+#endif /* __NETWARE__ && __MWERKS__ */
+
+
+#define CUTOFF (ULONGLONG_MAX / 10)
+#define CUTLIM (ULONGLONG_MAX % 10)
+#define DIGITS_IN_ULONGLONG 20
+
+static ulonglong d10[DIGITS_IN_ULONGLONG]=
+{
+ 1,
+ 10,
+ 100,
+ 1000,
+ 10000,
+ 100000,
+ 1000000,
+ 10000000,
+ 100000000,
+ 1000000000,
+ 10000000000ULL,
+ 100000000000ULL,
+ 1000000000000ULL,
+ 10000000000000ULL,
+ 100000000000000ULL,
+ 1000000000000000ULL,
+ 10000000000000000ULL,
+ 100000000000000000ULL,
+ 1000000000000000000ULL,
+ 10000000000000000000ULL
+};
+
+
+/*
+
+ Convert a string to unsigned long long integer value
+ with rounding.
+
+ SYNOPSYS
+ my_strntoull10_8bit()
+ cs in pointer to character set
+ str in pointer to the string to be converted
+ length in string length
+ unsigned_flag in whether the number is unsigned
+ endptr out pointer to the stop character
+ error out returned error code
+
+ DESCRIPTION
+ This function takes the decimal representation of integer number
+ from string str and converts it to an signed or unsigned
+ long long integer value.
+ Space characters and tab are ignored.
+ A sign character might precede the digit characters.
+ The number may have any number of pre-zero digits.
+ The number may have decimal point and exponent.
+ Rounding is always done in "away from zero" style:
+ 0.5 -> 1
+ -0.5 -> -1
+
+ The function stops reading the string str after "length" bytes
+ or at the first character that is not a part of correct number syntax:
+
+ <signed numeric literal> ::=
+ [ <sign> ] <exact numeric literal> [ E [ <sign> ] <unsigned integer> ]
+
+ <exact numeric literal> ::=
+ <unsigned integer> [ <period> [ <unsigned integer> ] ]
+ | <period> <unsigned integer>
+ <unsigned integer> ::= <digit>...
+
+ RETURN VALUES
+ Value of string as a signed/unsigned longlong integer
+
+ endptr cannot be NULL. The function will store the end pointer
+ to the stop character here.
+
+ The error parameter contains information how things went:
+ 0 ok
+ ERANGE If the the value of the converted number is out of range
+ In this case the return value is:
+ - ULONGLONG_MAX if unsigned_flag and the number was too big
+ - 0 if unsigned_flag and the number was negative
+ - LONGLONG_MAX if no unsigned_flag and the number is too big
+ - LONGLONG_MIN if no unsigned_flag and the number it too big negative
+
+ EDOM If the string didn't contain any digits.
+ In this case the return value is 0.
+*/
+
+ulonglong
+my_strntoull10rnd_8bit(CHARSET_INFO *cs __attribute__((unused)),
+ const char *str, uint length, int unsigned_flag,
+ char **endptr, int *error)
+{
+ const char *dot, *end9, *beg, *end= str + length;
+ ulonglong ull;
+ ulong ul;
+ unsigned char ch;
+ int shift= 0, digits= 0, negative, addon;
+
+ /* Skip leading spaces and tabs */
+ for ( ; str < end && (*str == ' ' || *str == '\t') ; str++);
+
+ if (str >= end)
+ goto ret_edom;
+
+ if ((negative= (*str == '-')) || *str=='+') /* optional sign */
+ {
+ if (++str == end)
+ goto ret_edom;
+ }
+
+ beg= str;
+ end9= (str + 9) > end ? end : (str + 9);
+ /* Accumulate small number into ulong, for performance purposes */
+ for (ul= 0 ; str < end9 && (ch= (unsigned char) (*str - '0')) < 10; str++)
+ {
+ ul= ul * 10 + ch;
+ }
+
+ if (str >= end) /* Small number without dots and expanents */
+ {
+ *endptr= (char*) str;
+ if (negative)
+ {
+ if (unsigned_flag)
+ {
+ *error= ul ? MY_ERRNO_ERANGE : 0;
+ return 0;
+ }
+ else
+ {
+ *error= 0;
+ return (ulonglong) (longlong) (long) -ul;
+ }
+ }
+ else
+ {
+ *error=0;
+ return (ulonglong) ul;
+ }
+ }
+
+ digits= str - beg;
+
+ /* Continue to accumulate into ulonglong */
+ for (dot= NULL, ull= ul; str < end; str++)
+ {
+ if ((ch= (unsigned char) (*str - '0')) < 10)
+ {
+ if (ull < CUTOFF || (ull == CUTOFF && ch <= CUTLIM))
+ {
+ ull= ull * 10 + ch;
+ digits++;
+ continue;
+ }
+ /*
+ Adding the next digit would overflow.
+ Remember the next digit in "addon", for rounding.
+ Scan all digits with an optional single dot.
+ */
+ if (ull == CUTOFF)
+ {
+ ull= ULONGLONG_MAX;
+ addon= 1;
+ str++;
+ }
+ else
+ addon= (*str >= '5');
+ for ( ; str < end && (ch= (unsigned char) (*str - '0')) < 10; str++)
+ {
+ if (!dot)
+ shift++;
+ }
+ if (str < end && *str == '.' && !dot)
+ {
+ str++;
+ for ( ; str < end && (ch= (unsigned char) (*str - '0')) < 10; str++);
+ }
+ goto exp;
+ }
+
+ if (*str == '.')
+ {
+ if (dot)
+ {
+ /* The second dot character */
+ addon= 0;
+ goto exp;
+ }
+ else
+ {
+ dot= str + 1;
+ }
+ continue;
+ }
+
+ /* Unknown character, exit the loop */
+ break;
+ }
+ shift= dot ? dot - str : 0; /* Right shift */
+ addon= 0;
+
+exp: /* [ E [ <sign> ] <unsigned integer> ] */
+
+ if (!digits)
+ {
+ str= beg;
+ goto ret_edom;
+ }
+
+ if (str < end && (*str == 'e' || *str == 'E'))
+ {
+ str++;
+ if (str < end)
+ {
+ int negative_exp, exp;
+ if ((negative_exp= (*str == '-')) || *str=='+')
+ {
+ if (++str == end)
+ goto ret_sign;
+ }
+ for (exp= 0 ;
+ str < end && (ch= (unsigned char) (*str - '0')) < 10;
+ str++)
+ {
+ exp= exp * 10 + ch;
+ }
+ shift+= negative_exp ? -exp : exp;
+ }
+ }
+
+ if (shift == 0) /* No shift, check addon digit */
+ {
+ if (addon)
+ {
+ if (ull == ULONGLONG_MAX)
+ goto ret_too_big;
+ ull++;
+ }
+ goto ret_sign;
+ }
+
+ if (shift < 0) /* Right shift */
+ {
+ ulonglong d, r;
+
+ if (-shift >= DIGITS_IN_ULONGLONG)
+ goto ret_zero; /* Exponent is a big negative number, return 0 */
+
+ d= d10[-shift];
+ r= (ull % d) * 2;
+ ull /= d;
+ if (r >= d)
+ ull++;
+ goto ret_sign;
+ }
+
+ if (shift > DIGITS_IN_ULONGLONG) /* Huge left shift */
+ {
+ if (!ull)
+ goto ret_sign;
+ goto ret_too_big;
+ }
+
+ for ( ; shift > 0; shift--, ull*= 10) /* Left shift */
+ {
+ if (ull > CUTOFF)
+ goto ret_too_big; /* Overflow, number too big */
+ }
+
+ret_sign:
+ *endptr= (char*) str;
+
+ if (!unsigned_flag)
+ {
+ if (negative)
+ {
+ if (ull > (ulonglong) LONGLONG_MIN)
+ {
+ *error= MY_ERRNO_ERANGE;
+ return (ulonglong) LONGLONG_MIN;
+ }
+ *error= 0;
+ return (ulonglong) -ull;
+ }
+ else
+ {
+ if (ull > (ulonglong) LONGLONG_MAX)
+ {
+ *error= MY_ERRNO_ERANGE;
+ return (ulonglong) LONGLONG_MAX;
+ }
+ *error= 0;
+ return ull;
+ }
+ }
+
+ /* Unsigned number */
+ if (negative && ull)
+ {
+ *error= MY_ERRNO_ERANGE;
+ return 0;
+ }
+ *error= 0;
+ return ull;
+
+ret_zero:
+ *endptr= (char*) str;
+ *error= 0;
+ return 0;
+
+ret_edom:
+ *endptr= (char*) str;
+ *error= MY_ERRNO_EDOM;
+ return 0;
+
+ret_too_big:
+ *endptr= (char*) str;
+ *error= MY_ERRNO_ERANGE;
+ return unsigned_flag ?
+ ULONGLONG_MAX :
+ negative ? (ulonglong) LONGLONG_MIN : (ulonglong) LONGLONG_MAX;
+}
+
+
/*
Check if a constant can be propagated
@@ -1448,6 +1784,7 @@ MY_CHARSET_HANDLER my_charset_8bit_handler=
my_strntoull_8bit,
my_strntod_8bit,
my_strtoll10_8bit,
+ my_strntoull10rnd_8bit,
my_scan_8bit
};
diff --git a/strings/ctype-sjis.c b/strings/ctype-sjis.c
index 59156e444c1..0ce085a330e 100644
--- a/strings/ctype-sjis.c
+++ b/strings/ctype-sjis.c
@@ -4664,6 +4664,7 @@ static MY_CHARSET_HANDLER my_charset_handler=
my_strntoull_8bit,
my_strntod_8bit,
my_strtoll10_8bit,
+ my_strntoull10rnd_8bit,
my_scan_8bit
};
diff --git a/strings/ctype-tis620.c b/strings/ctype-tis620.c
index 98cc41dd26f..c5144d28b57 100644
--- a/strings/ctype-tis620.c
+++ b/strings/ctype-tis620.c
@@ -892,6 +892,7 @@ static MY_CHARSET_HANDLER my_charset_handler=
my_strntoull_8bit,
my_strntod_8bit,
my_strtoll10_8bit,
+ my_strntoull10rnd_8bit,
my_scan_8bit
};
diff --git a/strings/ctype-ucs2.c b/strings/ctype-ucs2.c
index 2ab2fdc1657..df43eff3d73 100644
--- a/strings/ctype-ucs2.c
+++ b/strings/ctype-ucs2.c
@@ -974,6 +974,35 @@ double my_strntod_ucs2(CHARSET_INFO *cs __attribute__((unused)),
}
+ulonglong my_strntoull10rnd_ucs2(CHARSET_INFO *cs __attribute__((unused)),
+ const char *nptr, uint length, int unsign_fl,
+ char **endptr, int *err)
+{
+ char buf[256], *b= buf;
+ ulonglong res;
+ const uchar *end, *s= (const uchar*) nptr;
+ my_wc_t wc;
+ int cnv;
+
+ /* Cut too long strings */
+ if (length >= sizeof(buf))
+ length= sizeof(buf)-1;
+ end= s + length;
+
+ while ((cnv= cs->cset->mb_wc(cs,&wc,s,end)) > 0)
+ {
+ s+= cnv;
+ if (wc > (int) (uchar) 'e' || !wc)
+ break; /* Can't be a number part */
+ *b++= (char) wc;
+ }
+
+ res= my_strntoull10rnd_8bit(cs, buf, b - buf, unsign_fl, endptr, err);
+ *endptr= (char*) nptr + 2 * (uint) (*endptr- buf);
+ return res;
+}
+
+
/*
This is a fast version optimized for the case of radix 10 / -10
*/
@@ -1630,6 +1659,7 @@ MY_CHARSET_HANDLER my_charset_ucs2_handler=
my_strntoull_ucs2,
my_strntod_ucs2,
my_strtoll10_ucs2,
+ my_strntoull10rnd_ucs2,
my_scan_ucs2
};
diff --git a/strings/ctype-ujis.c b/strings/ctype-ujis.c
index 06c4540e464..5474377631e 100644
--- a/strings/ctype-ujis.c
+++ b/strings/ctype-ujis.c
@@ -8546,6 +8546,7 @@ static MY_CHARSET_HANDLER my_charset_handler=
my_strntoull_8bit,
my_strntod_8bit,
my_strtoll10_8bit,
+ my_strntoull10rnd_8bit,
my_scan_8bit
};
diff --git a/strings/ctype-utf8.c b/strings/ctype-utf8.c
index 1a952a07042..e221297eb55 100644
--- a/strings/ctype-utf8.c
+++ b/strings/ctype-utf8.c
@@ -2551,6 +2551,7 @@ MY_CHARSET_HANDLER my_charset_utf8_handler=
my_strntoull_8bit,
my_strntod_8bit,
my_strtoll10_8bit,
+ my_strntoull10rnd_8bit,
my_scan_8bit
};
diff --git a/strings/strtod.c b/strings/strtod.c
index 7171a6e0801..ddb570718a0 100644
--- a/strings/strtod.c
+++ b/strings/strtod.c
@@ -30,7 +30,8 @@
#include "m_ctype.h"
#define MAX_DBL_EXP 308
-#define MAX_RESULT_FOR_MAX_EXP 1.79769313486232
+#define MAX_RESULT_FOR_MAX_EXP 1.7976931348623157
+#define MIN_RESULT_FOR_MIN_EXP 2.225073858507202
static double scaler10[] = {
1.0, 1e10, 1e20, 1e30, 1e40, 1e50, 1e60, 1e70, 1e80, 1e90
};
@@ -57,10 +58,11 @@ double my_strtod(const char *str, char **end_ptr, int *error)
{
double result= 0.0;
uint negative= 0, ndigits, dec_digits= 0, neg_exp= 0;
- int exp= 0, digits_after_dec_point= 0;
+ int exp= 0, digits_after_dec_point= 0, tmp_exp;
const char *old_str, *end= *end_ptr, *start_of_number;
char next_char;
my_bool overflow=0;
+ double scaler= 1.0;
*error= 0;
if (str >= end)
@@ -91,6 +93,7 @@ double my_strtod(const char *str, char **end_ptr, int *error)
while ((next_char= *str) >= '0' && next_char <= '9')
{
result= result*10.0 + (next_char - '0');
+ scaler= scaler*10.0;
if (++str == end)
{
next_char= 0; /* Found end of string */
@@ -114,6 +117,7 @@ double my_strtod(const char *str, char **end_ptr, int *error)
{
result= result*10.0 + (next_char - '0');
digits_after_dec_point++;
+ scaler= scaler*10.0;
if (++str == end)
{
next_char= 0;
@@ -144,39 +148,54 @@ double my_strtod(const char *str, char **end_ptr, int *error)
} while (str < end && my_isdigit(&my_charset_latin1, *str));
}
}
- if ((exp= (neg_exp ? exp + digits_after_dec_point :
- exp - digits_after_dec_point)))
+ tmp_exp= neg_exp ? exp + digits_after_dec_point : exp - digits_after_dec_point;
+ if (tmp_exp)
{
- double scaler;
- if (exp < 0)
- {
- exp= -exp;
- neg_exp= 1; /* neg_exp was 0 before */
- }
- if (exp + ndigits >= MAX_DBL_EXP + 1 && result)
+ int order;
+ /*
+ Check for underflow/overflow.
+ order is such an integer number that f = C * 10 ^ order,
+ where f is the resulting floating point number and 1 <= C < 10.
+ Here we compute the modulus
+ */
+ order= exp + (neg_exp ? -1 : 1) * (ndigits - 1);
+ if (order < 0)
+ order= -order;
+ if (order >= MAX_DBL_EXP && result)
{
- /*
- This is not 100 % as we actually will give an owerflow for
- 17E307 but not for 1.7E308 but lets cut some corners to make life
- simpler
- */
- if (exp + ndigits > MAX_DBL_EXP + 1 ||
- result >= MAX_RESULT_FOR_MAX_EXP)
+ double c;
+ /* Compute modulus of C (see comment above) */
+ c= result / scaler * 10.0;
+ if (neg_exp)
{
- if (neg_exp)
+ if (order > MAX_DBL_EXP || c < MIN_RESULT_FOR_MIN_EXP)
+ {
result= 0.0;
- else
+ goto done;
+ }
+ }
+ else
+ {
+ if (order > MAX_DBL_EXP || c > MAX_RESULT_FOR_MAX_EXP)
+ {
overflow= 1;
- goto done;
+ goto done;
+ }
}
}
- scaler= 1.0;
+
+ exp= tmp_exp;
+ if (exp < 0)
+ {
+ exp= -exp;
+ neg_exp= 1; /* neg_exp was 0 before */
+ }
while (exp >= 100)
{
- scaler*= 1.0e100;
+ result= neg_exp ? result/1.0e100 : result*1.0e100;
exp-= 100;
}
- scaler*= scaler10[exp/10]*scaler1[exp%10];
+ scaler= scaler10[exp/10]*scaler1[exp%10];
if (neg_exp)
result/= scaler;
else
diff --git a/strings/xml.c b/strings/xml.c
index 51649dcb343..7f7c531d051 100644
--- a/strings/xml.c
+++ b/strings/xml.c
@@ -19,6 +19,7 @@
#include "my_xml.h"
+#define MY_XML_UNKNOWN 'U'
#define MY_XML_EOF 'E'
#define MY_XML_STRING 'S'
#define MY_XML_IDENT 'I'
@@ -39,6 +40,46 @@ typedef struct xml_attr_st
} MY_XML_ATTR;
+/*
+ XML ctype:
+*/
+#define MY_XML_ID0 0x01 /* Identifier initial character */
+#define MY_XML_ID1 0x02 /* Identifier medial character */
+#define MY_XML_SPC 0x08 /* Spacing character */
+
+
+/*
+ http://www.w3.org/TR/REC-xml/
+ [4] NameChar ::= Letter | Digit | '.' | '-' | '_' | ':' |
+ CombiningChar | Extender
+ [5] Name ::= (Letter | '_' | ':') (NameChar)*
+*/
+
+static char my_xml_ctype[256]=
+{
+/*00*/ 0,0,0,0,0,0,0,0,0,8,8,0,0,8,0,0,
+/*10*/ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+/*20*/ 8,0,0,0,0,0,0,0,0,0,0,0,0,2,2,0, /* !"#$%&'()*+,-./ */
+/*30*/ 2,2,2,2,2,2,2,2,2,2,3,0,0,0,0,0, /* 0123456789:;<=>? */
+/*40*/ 0,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3, /* @ABCDEFGHIJKLMNO */
+/*50*/ 3,3,3,3,3,3,3,3,3,3,3,0,0,0,0,3, /* PQRSTUVWXYZ[\]^_ */
+/*60*/ 0,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3, /* `abcdefghijklmno */
+/*70*/ 3,3,3,3,3,3,3,3,3,3,3,0,0,0,0,0, /* pqrstuvwxyz{|}~ */
+/*80*/ 3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,
+/*90*/ 3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,
+/*A0*/ 3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,
+/*B0*/ 3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,
+/*C0*/ 3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,
+/*D0*/ 3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,
+/*E0*/ 3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,
+/*F0*/ 3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3
+};
+
+#define my_xml_is_space(c) (my_xml_ctype[(uchar) (c)] & MY_XML_SPC)
+#define my_xml_is_id0(c) (my_xml_ctype[(uchar) (c)] & MY_XML_ID0)
+#define my_xml_is_id1(c) (my_xml_ctype[(uchar) (c)] & MY_XML_ID1)
+
+
static const char *lex2str(int lex)
{
switch(lex)
@@ -56,13 +97,13 @@ static const char *lex2str(int lex)
case MY_XML_QUESTION: return "'?'";
case MY_XML_EXCLAM: return "'!'";
}
- return "UNKNOWN";
+ return "unknown token";
}
static void my_xml_norm_text(MY_XML_ATTR *a)
{
- for ( ; (a->beg < a->end) && strchr(" \t\r\n",a->beg[0]) ; a->beg++ );
- for ( ; (a->beg < a->end) && strchr(" \t\r\n",a->end[-1]) ; a->end-- );
+ for ( ; (a->beg < a->end) && my_xml_is_space(a->beg[0]) ; a->beg++ );
+ for ( ; (a->beg < a->end) && my_xml_is_space(a->end[-1]) ; a->end-- );
}
@@ -70,7 +111,7 @@ static int my_xml_scan(MY_XML_PARSER *p,MY_XML_ATTR *a)
{
int lex;
- for( ; ( p->cur < p->end) && strchr(" \t\r\n",p->cur[0]) ; p->cur++);
+ for( ; ( p->cur < p->end) && my_xml_is_space(p->cur[0]) ; p->cur++);
if (p->cur >= p->end)
{
@@ -124,16 +165,17 @@ static int my_xml_scan(MY_XML_PARSER *p,MY_XML_ATTR *a)
my_xml_norm_text(a);
lex=MY_XML_STRING;
}
- else
+ else if (my_xml_is_id0(p->cur[0]))
{
- for(;
- (p->cur < p->end) && !strchr("?'\"=/<> \t\r\n", p->cur[0]);
- p->cur++)
- {}
+ p->cur++;
+ while (p->cur < p->end && my_xml_is_id1(p->cur[0]))
+ p->cur++;
a->end=p->cur;
my_xml_norm_text(a);
lex=MY_XML_IDENT;
}
+ else
+ lex= MY_XML_UNKNOWN;
#if 0
printf("LEX=%s[%d]\n",lex2str(lex),a->end-a->beg);
diff --git a/support-files/mysql.spec.sh b/support-files/mysql.spec.sh
index 4dc9c2e1be4..29b19d86e89 100644
--- a/support-files/mysql.spec.sh
+++ b/support-files/mysql.spec.sh
@@ -644,7 +644,6 @@ fi
%defattr(-, root, root, 0755)
%doc mysql-release-%{mysql_version}/EXCEPTIONS-CLIENT
%doc %attr(644, root, man) %{_mandir}/man1/mysql_config.1*
-%attr(755, root, root) %{_bindir}/comp_err
%attr(755, root, root) %{_bindir}/mysql_config
%dir %attr(755, root, root) %{_includedir}/mysql
%dir %attr(755, root, root) %{_libdir}/mysql
diff --git a/tests/mysql_client_test.c b/tests/mysql_client_test.c
index cd9ac675c25..148295398f4 100644
--- a/tests/mysql_client_test.c
+++ b/tests/mysql_client_test.c
@@ -15438,6 +15438,43 @@ static void test_bug21206()
DBUG_VOID_RETURN;
}
+/*
+ Bug#21726: Incorrect result with multiple invocations of
+ LAST_INSERT_ID
+
+ Test that client gets updated value of insert_id on UPDATE that uses
+ LAST_INSERT_ID(expr).
+*/
+static void test_bug21726()
+{
+ const char *create_table[]=
+ {
+ "DROP TABLE IF EXISTS t1",
+ "CREATE TABLE t1 (i INT)",
+ "INSERT INTO t1 VALUES (1)",
+ };
+ const char *update_query= "UPDATE t1 SET i= LAST_INSERT_ID(i + 1)";
+ int rc;
+ my_ulonglong insert_id;
+
+ DBUG_ENTER("test_bug21726");
+ myheader("test_bug21726");
+
+ fill_tables(create_table, sizeof(create_table) / sizeof(*create_table));
+
+ rc= mysql_query(mysql, update_query);
+ myquery(rc);
+ insert_id= mysql_insert_id(mysql);
+ DIE_UNLESS(insert_id == 2);
+
+ rc= mysql_query(mysql, update_query);
+ myquery(rc);
+ insert_id= mysql_insert_id(mysql);
+ DIE_UNLESS(insert_id == 3);
+
+ DBUG_VOID_RETURN;
+}
+
/*
Read and parse arguments and MySQL options from my.cnf
@@ -15713,8 +15750,9 @@ static struct my_tests_st my_tests[]= {
{ "test_bug17667", test_bug17667 },
{ "test_bug15752", test_bug15752 },
{ "test_mysql_insert_id", test_mysql_insert_id },
- { "test_bug19671", test_bug19671},
- { "test_bug21206", test_bug21206},
+ { "test_bug19671", test_bug19671 },
+ { "test_bug21206", test_bug21206 },
+ { "test_bug21726", test_bug21726 },
{ 0, 0 }
};
diff --git a/unittest/mysys/base64-t.c b/unittest/mysys/base64-t.c
index 6d85964b20d..ccec0c77086 100644
--- a/unittest/mysys/base64-t.c
+++ b/unittest/mysys/base64-t.c
@@ -54,7 +54,7 @@ main(void)
/* Decode */
dst= (char *) malloc(base64_needed_decoded_length(strlen(str)));
- dst_len= base64_decode(str, strlen(str), dst);
+ dst_len= base64_decode(str, strlen(str), dst, NULL);
ok(dst_len == src_len, "Comparing lengths");
cmp= memcmp(src, dst, src_len);
diff --git a/vio/viossl.c b/vio/viossl.c
index e869493c604..180c7a50fa7 100644
--- a/vio/viossl.c
+++ b/vio/viossl.c
@@ -167,10 +167,9 @@ int sslaccept(struct st_VioSSLFd *ptr, Vio *vio, long 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)
+ if (SSL_accept(ssl) < 1)
{
- DBUG_PRINT("error", ("SSL_do_handshake failure"));
+ DBUG_PRINT("error", ("SSL_accept failure"));
report_errors(ssl);
SSL_free(ssl);
vio->ssl_arg= 0;
@@ -242,10 +241,9 @@ int sslconnect(struct st_VioSSLFd *ptr, Vio *vio, long 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)
+ if (SSL_connect(ssl) < 1)
{
- DBUG_PRINT("error", ("SSL_do_handshake failure"));
+ DBUG_PRINT("error", ("SSL_connect failure"));
report_errors(ssl);
SSL_free(ssl);
vio->ssl_arg= 0;
diff --git a/zlib/Makefile.am b/zlib/Makefile.am
index 40258ec589a..75100dc3f7b 100644
--- a/zlib/Makefile.am
+++ b/zlib/Makefile.am
@@ -18,6 +18,8 @@
INCLUDES= -I$(top_builddir)/include -I$(top_srcdir)/include
+LIBS= $(NON_THREADED_LIBS)
+
pkglib_LTLIBRARIES=libz.la
libz_la_LDFLAGS= -version-info 3:3:2