diff options
116 files changed, 1408 insertions, 597 deletions
diff --git a/VC++Files/libmysqld/libmysqld.dsp b/VC++Files/libmysqld/libmysqld.dsp index 9c4485210a6..1c80147a8f5 100644 --- a/VC++Files/libmysqld/libmysqld.dsp +++ b/VC++Files/libmysqld/libmysqld.dsp @@ -363,6 +363,10 @@ SOURCE=..\mysys\my_getopt.c SOURCE=..\sql-common\my_time.c # End Source File # Begin Source File + +SOURCE=..\sql-common\my_user.c +# End Source File +# Begin Source File SOURCE=..\sql\net_serv.cpp
# End Source File
diff --git a/VC++Files/libmysqld/libmysqld_ia64.dsp b/VC++Files/libmysqld/libmysqld_ia64.dsp index b5223e38f2d..9668193fc1d 100644 --- a/VC++Files/libmysqld/libmysqld_ia64.dsp +++ b/VC++Files/libmysqld/libmysqld_ia64.dsp @@ -338,6 +338,10 @@ SOURCE="..\sql-common\my_time.c" # End Source File # Begin Source File +SOURCE="..\sql-common\my_user.c" +# End Source File +# Begin Source File + SOURCE=..\sql\net_serv.cpp # End Source File # Begin Source File diff --git a/client/mysqltest.c b/client/mysqltest.c index 21ca1d6e3a1..ce876708fbc 100644 --- a/client/mysqltest.c +++ b/client/mysqltest.c @@ -688,10 +688,11 @@ static void die(const char *fmt, ...) /* Note that we will get some memory leaks when calling this! */ -static void abort_not_supported_test() +static void abort_not_supported_test(const char *fname) { DBUG_ENTER("abort_not_supported_test"); - fprintf(stderr, "This test is not supported by this installation\n"); + fprintf(stderr, "The test '%s' is not supported by this installation\n", + fname); if (!silent) printf("skipped\n"); free_used_memory(); @@ -814,7 +815,7 @@ static void check_result(DYNAMIC_STRING* ds, const char *fname, DBUG_ENTER("check_result"); if (res && require_option) - abort_not_supported_test(); + abort_not_supported_test(fname); switch (res) { case RESULT_OK: break; /* ok */ @@ -1036,7 +1037,7 @@ int do_wait_for_slave_to_stop(struct st_query *q __attribute__((unused))) int do_require_manager(struct st_query *query __attribute__((unused)) ) { if (!manager) - abort_not_supported_test(); + abort_not_supported_test("manager"); return 0; } @@ -1305,7 +1306,9 @@ int var_query_set(VAR* var, const char *query, const char** query_end) uint i; ulong *lengths; char *end; +#ifdef NOT_YET MYSQL_FIELD *fields= mysql_fetch_fields(res); +#endif init_dynamic_string(&result, "", 16384, 65536); lengths= mysql_fetch_lengths(res); @@ -1920,7 +1923,7 @@ static void set_charset(struct st_query *q) q->last_argument= p; charset_info= get_charset_by_csname(charset_name,MY_CS_PRIMARY,MYF(MY_WME)); if (!charset_info) - abort_not_supported_test(); + abort_not_supported_test(charset_name); } static uint get_errcodes(match_err *to,struct st_query *q) @@ -1963,7 +1966,7 @@ static uint get_errcodes(match_err *to,struct st_query *q) (as in ER_WRONG_VALUE vs. ER_WRONG_VALUE_COUNT). */ if (!strncmp(start, e->name, (int) (p - start)) && - strlen(e->name) == (p - start)) + (uint) strlen(e->name) == (uint) (p - start)) { to[count].code.errnum= (uint) e->code; to[count].type= ERR_ERRNO; @@ -4329,7 +4332,7 @@ static void handle_error(const char *query, struct st_query *q, if (err_errno == CR_SERVER_LOST || err_errno == CR_SERVER_GONE_ERROR) die("require query '%s' failed: %d: %s", query, err_errno, err_error); - abort_not_supported_test(); + abort_not_supported_test("failed_query"); } if (q->abort_on_error) @@ -5101,7 +5104,7 @@ static void init_var_hash(MYSQL *mysql) DBUG_VOID_RETURN; } -static void mark_progress(int line) +static void mark_progress(int line __attribute__((unused))) { #ifdef NOT_YET static FILE* fp = NULL; diff --git a/configure.in b/configure.in index 162bff48b7f..e159a5803f1 100644 --- a/configure.in +++ b/configure.in @@ -48,92 +48,9 @@ czech danish dutch english estonian french german greek hungarian \ italian japanese korean norwegian norwegian-ny polish portuguese \ romanian russian serbian slovak spanish swedish ukrainian" -#-------------------------------------------------------------------- -# Declare our plugin modules -#-------------------------------------------------------------------- - -MYSQL_STORAGE_ENGINE(archive,, [Archive Storage Engine], - [Archive Storage Engine], [max,max-no-ndb]) -MYSQL_PLUGIN_DIRECTORY(archive, [storage/archive]) -MYSQL_PLUGIN_STATIC(archive, [libarchive.a]) -MYSQL_PLUGIN_DYNAMIC(archive, [ha_archive.la]) - -MYSQL_STORAGE_ENGINE(berkeley, berkeley-db, [BerkeleyDB Storage Engine], - [Transactional Tables using BerkeleyDB], [max,max-no-ndb]) -MYSQL_PLUGIN_DIRECTORY(berkeley,[storage/bdb]) -MYSQL_PLUGIN_STATIC(berkeley, [[\$(bdb_libs_with_path)]]) -MYSQL_PLUGIN_ACTIONS(berkeley, [MYSQL_SETUP_BERKELEY_DB]) - -MYSQL_STORAGE_ENGINE(blackhole,,[Blackhole Storage Engine], - [Basic Write-only Read-never tables], [max,max-no-ndb]) -MYSQL_PLUGIN_DIRECTORY(blackhole, [storage/blackhole]) -MYSQL_PLUGIN_STATIC(blackhole, [libblackhole.a]) -MYSQL_PLUGIN_DYNAMIC(blackhole, [ha_blackhole.la]) - -MYSQL_STORAGE_ENGINE(csv,, [CSV Storage Engine], - [Stores tables in text CSV format]) -MYSQL_PLUGIN_DIRECTORY(csv, [storage/csv]) -MYSQL_PLUGIN_STATIC(csv, [libcsv.a]) -MYSQL_PLUGIN_MANDATORY(csv) dnl Used for logging - -MYSQL_STORAGE_ENGINE(example,, [Example Storage Engine], - [Skeleton for Storage Engines for developers], [max,max-no-ndb]) -MYSQL_PLUGIN_DIRECTORY(example, [storage/example]) -MYSQL_PLUGIN_STATIC(example, [libexample.a]) -MYSQL_PLUGIN_DYNAMIC(example, [ha_example.la]) - -MYSQL_STORAGE_ENGINE(federated,,[Federated Storage Engine], - [Connects to tables on remote MySQL servers], [max,max-no-ndb]) - -MYSQL_PLUGIN(ftexample, [Simple Parser], - [Simple full-text parser plugin]) -MYSQL_PLUGIN_DIRECTORY(ftexample, [plugin/fulltext]) -MYSQL_PLUGIN_DYNAMIC(ftexample, [mypluglib.la]) - -MYSQL_STORAGE_ENGINE(heap,no, [Memory Storage Engine], - [Volatile memory based tables]) -MYSQL_PLUGIN_DIRECTORY(heap, [storage/heap]) -MYSQL_PLUGIN_STATIC(heap, [libheap.a]) -MYSQL_PLUGIN_MANDATORY(heap) dnl Memory tables - -MYSQL_STORAGE_ENGINE(innobase, innodb, [InnoDB Storage Engine], - [Transactional Tables using InnoDB], [max,max-no-ndb]) -MYSQL_PLUGIN_DIRECTORY(innobase, [storage/innobase]) -MYSQL_PLUGIN_STATIC(innobase, [libinnobase.a]) -MYSQL_PLUGIN_ACTIONS(innobase, [ - AC_CHECK_LIB(rt, aio_read, [innodb_system_libs="-lrt"]) - AC_SUBST(innodb_system_libs) -]) - -MYSQL_STORAGE_ENGINE(myisam,no, [MyISAM Storage Engine], - [Traditional non-transactional MySQL tables]) -MYSQL_PLUGIN_DIRECTORY(myisam, [storage/myisam]) -MYSQL_PLUGIN_STATIC(myisam, [libmyisam.a]) -MYSQL_PLUGIN_MANDATORY(myisam) dnl Default - -MYSQL_STORAGE_ENGINE(myisammrg,no,[MyISAM MERGE Engine], - [Merge multiple MySQL tables into one]) -MYSQL_PLUGIN_DIRECTORY(myisammrg,[storage/myisammrg]) -MYSQL_PLUGIN_STATIC(myisammrg, [libmyisammrg.a]) -MYSQL_PLUGIN_MANDATORY(myisammrg) - -MYSQL_STORAGE_ENGINE(ndbcluster, ndbcluster, [Cluster Storage Engine], - [High Availability Clustered tables], [max]) -MYSQL_PLUGIN_DIRECTORY(ndbcluster,[storage/ndb]) -MYSQL_PLUGIN_STATIC(ndbcluster, [[\$(ndbcluster_libs) \$(ndbcluster_system_libs) \$(NDB_SCI_LIBS)]]) -MYSQL_PLUGIN_ACTIONS(ndbcluster,[MYSQL_SETUP_NDBCLUSTER]) - -MYSQL_STORAGE_ENGINE(partition, partition, [Partition Support], - [MySQL Partitioning Support], [max,max-no-ndb]) - -dnl -- ndbcluster requires partition to be enabled -MYSQL_PLUGIN_DEPENDS(ndbcluster, [partition]) - - ##### ##### - AC_SUBST(MYSQL_NO_DASH_VERSION) AC_SUBST(MYSQL_BASE_VERSION) AC_SUBST(MYSQL_VERSION_ID) @@ -763,16 +680,6 @@ MYSQL_SYS_LARGEFILE AC_TYPE_SIZE_T #-------------------------------------------------------------------- -# Check for requested features -#-------------------------------------------------------------------- - -MYSQL_CHECK_BIG_TABLES -MYSQL_CHECK_MAX_INDEXES -MYSQL_CHECK_REPLICATION - -MYSQL_CONFIGURE_PLUGINS([none]) - -#-------------------------------------------------------------------- # Check for system header files #-------------------------------------------------------------------- @@ -2288,6 +2195,102 @@ then fi AC_MSG_RESULT("$netinet_inc") +#-------------------------------------------------------------------- +# Check for requested features +#-------------------------------------------------------------------- + +MYSQL_CHECK_BIG_TABLES +MYSQL_CHECK_MAX_INDEXES +MYSQL_CHECK_REPLICATION +MYSQL_CHECK_VIO +MYSQL_CHECK_OPENSSL +MYSQL_CHECK_YASSL + +#-------------------------------------------------------------------- +# Declare our plugin modules +# Has to be done late, as the plugin may need to check for existence of +# functions tested above +#-------------------------------------------------------------------- + +MYSQL_STORAGE_ENGINE(archive,, [Archive Storage Engine], + [Archive Storage Engine], [max,max-no-ndb]) +MYSQL_PLUGIN_DIRECTORY(archive, [storage/archive]) +MYSQL_PLUGIN_STATIC(archive, [libarchive.a]) +MYSQL_PLUGIN_DYNAMIC(archive, [ha_archive.la]) + +MYSQL_STORAGE_ENGINE(berkeley, berkeley-db, [BerkeleyDB Storage Engine], + [Transactional Tables using BerkeleyDB], [max,max-no-ndb]) +MYSQL_PLUGIN_DIRECTORY(berkeley,[storage/bdb]) +MYSQL_PLUGIN_STATIC(berkeley, [[\$(bdb_libs_with_path)]]) +MYSQL_PLUGIN_ACTIONS(berkeley, [MYSQL_SETUP_BERKELEY_DB]) + +MYSQL_STORAGE_ENGINE(blackhole,,[Blackhole Storage Engine], + [Basic Write-only Read-never tables], [max,max-no-ndb]) +MYSQL_PLUGIN_DIRECTORY(blackhole, [storage/blackhole]) +MYSQL_PLUGIN_STATIC(blackhole, [libblackhole.a]) +MYSQL_PLUGIN_DYNAMIC(blackhole, [ha_blackhole.la]) + +MYSQL_STORAGE_ENGINE(csv,, [CSV Storage Engine], + [Stores tables in text CSV format]) +MYSQL_PLUGIN_DIRECTORY(csv, [storage/csv]) +MYSQL_PLUGIN_STATIC(csv, [libcsv.a]) +MYSQL_PLUGIN_MANDATORY(csv) dnl Used for logging + +MYSQL_STORAGE_ENGINE(example,, [Example Storage Engine], + [Skeleton for Storage Engines for developers], [max,max-no-ndb]) +MYSQL_PLUGIN_DIRECTORY(example, [storage/example]) +MYSQL_PLUGIN_STATIC(example, [libexample.a]) +MYSQL_PLUGIN_DYNAMIC(example, [ha_example.la]) + +MYSQL_STORAGE_ENGINE(federated,,[Federated Storage Engine], + [Connects to tables on remote MySQL servers], [max,max-no-ndb]) + +MYSQL_PLUGIN(ftexample, [Simple Parser], + [Simple full-text parser plugin]) +MYSQL_PLUGIN_DIRECTORY(ftexample, [plugin/fulltext]) +MYSQL_PLUGIN_DYNAMIC(ftexample, [mypluglib.la]) + +MYSQL_STORAGE_ENGINE(heap,no, [Memory Storage Engine], + [Volatile memory based tables]) +MYSQL_PLUGIN_DIRECTORY(heap, [storage/heap]) +MYSQL_PLUGIN_STATIC(heap, [libheap.a]) +MYSQL_PLUGIN_MANDATORY(heap) dnl Memory tables + +MYSQL_STORAGE_ENGINE(innobase, innodb, [InnoDB Storage Engine], + [Transactional Tables using InnoDB], [max,max-no-ndb]) +MYSQL_PLUGIN_DIRECTORY(innobase, [storage/innobase]) +MYSQL_PLUGIN_STATIC(innobase, [libinnobase.a]) +MYSQL_PLUGIN_ACTIONS(innobase, [ + AC_CHECK_LIB(rt, aio_read, [innodb_system_libs="-lrt"]) + AC_SUBST(innodb_system_libs) +]) + +MYSQL_STORAGE_ENGINE(myisam,no, [MyISAM Storage Engine], + [Traditional non-transactional MySQL tables]) +MYSQL_PLUGIN_DIRECTORY(myisam, [storage/myisam]) +MYSQL_PLUGIN_STATIC(myisam, [libmyisam.a]) +MYSQL_PLUGIN_MANDATORY(myisam) dnl Default + +MYSQL_STORAGE_ENGINE(myisammrg,no,[MyISAM MERGE Engine], + [Merge multiple MySQL tables into one]) +MYSQL_PLUGIN_DIRECTORY(myisammrg,[storage/myisammrg]) +MYSQL_PLUGIN_STATIC(myisammrg, [libmyisammrg.a]) +MYSQL_PLUGIN_MANDATORY(myisammrg) + +MYSQL_STORAGE_ENGINE(ndbcluster, ndbcluster, [Cluster Storage Engine], + [High Availability Clustered tables], [max]) +MYSQL_PLUGIN_DIRECTORY(ndbcluster,[storage/ndb]) +MYSQL_PLUGIN_STATIC(ndbcluster, [[\$(ndbcluster_libs) \$(ndbcluster_system_libs) \$(NDB_SCI_LIBS)]]) +MYSQL_PLUGIN_ACTIONS(ndbcluster,[MYSQL_SETUP_NDBCLUSTER]) + +MYSQL_STORAGE_ENGINE(partition, partition, [Partition Support], + [MySQL Partitioning Support], [max,max-no-ndb]) + +dnl -- ndbcluster requires partition to be enabled +MYSQL_PLUGIN_DEPENDS(ndbcluster, [partition]) + +MYSQL_CONFIGURE_PLUGINS([none]) + # Only build client code? AC_ARG_WITH(server, [ --without-server Only build the client.], @@ -2353,9 +2356,6 @@ fi AC_SUBST(tools_dirs) #MYSQL_CHECK_CPU -MYSQL_CHECK_VIO -MYSQL_CHECK_OPENSSL -MYSQL_CHECK_YASSL libmysqld_dirs= linked_libmysqld_targets= diff --git a/include/my_base.h b/include/my_base.h index b9a806cc02f..e014f7c33b7 100644 --- a/include/my_base.h +++ b/include/my_base.h @@ -231,6 +231,7 @@ enum ha_base_keytype { #define HA_VAR_LENGTH_KEY 8 #define HA_NULL_PART_KEY 64 #define HA_USES_PARSER 16384 /* Fulltext index uses [pre]parser */ +#define HA_USES_BLOCK_SIZE ((uint) 32768) #define HA_SORT_ALLOWS_SAME 512 /* Intern bit when sorting records */ /* Key has a part that can have end space. If this is an unique key diff --git a/include/my_sys.h b/include/my_sys.h index aab92f80c8e..1540d820777 100644 --- a/include/my_sys.h +++ b/include/my_sys.h @@ -558,6 +558,7 @@ extern File my_open(const char *FileName,int Flags,myf MyFlags); extern File my_register_filename(File fd, const char *FileName, enum file_type type_of_file, uint error_message_number, myf MyFlags); +extern void my_print_open_files(void); extern File my_create(const char *FileName,int CreateFlags, int AccessFlags, myf MyFlags); extern int my_close(File Filedes,myf MyFlags); @@ -647,6 +648,12 @@ extern void allow_break(void); #define allow_break() #endif +#ifdef EXTRA_DEBUG +void my_print_open_files(); +#else +#define my_print_open_files() +#endif + extern my_bool init_tmpdir(MY_TMPDIR *tmpdir, const char *pathlist); extern char *my_tmpdir(MY_TMPDIR *tmpdir); extern void free_tmpdir(MY_TMPDIR *tmpdir); @@ -817,6 +824,7 @@ extern int unpackfrm(const void **, uint *, const void *); extern ha_checksum my_checksum(ha_checksum crc, const byte *mem, uint count); extern uint my_bit_log2(ulong value); +extern uint32 my_round_up_to_next_power(uint32 v); extern uint my_count_bits(ulonglong v); extern uint my_count_bits_ushort(ushort v); extern void my_sleep(ulong m_seconds); diff --git a/include/my_tree.h b/include/my_tree.h index 14d8593b6dc..03dc9d5c829 100644 --- a/include/my_tree.h +++ b/include/my_tree.h @@ -84,7 +84,7 @@ TREE_ELEMENT *tree_insert(TREE *tree,void *key, uint key_size, void *tree_search(TREE *tree, void *key, void *custom_arg); int tree_walk(TREE *tree,tree_walk_action action, void *argument, TREE_WALK visit); -int tree_delete(TREE *tree, void *key, void *custom_arg); +int tree_delete(TREE *tree, void *key, uint key_size, void *custom_arg); void *tree_search_key(TREE *tree, const void *key, TREE_ELEMENT **parents, TREE_ELEMENT ***last_pos, enum ha_rkey_function flag, void *custom_arg); diff --git a/include/myisam.h b/include/myisam.h index 5116f48eeb5..db1a7bd984d 100644 --- a/include/myisam.h +++ b/include/myisam.h @@ -192,7 +192,7 @@ typedef struct st_mi_keydef /* Key definition with open & info */ uint16 keylength; /* Tot length of keyparts (auto) */ uint16 minlength; /* min length of (packed) key (auto) */ uint16 maxlength; /* max length of (packed) key (auto) */ - uint16 block_size; /* block_size (auto) */ + uint16 block_size_index; /* block_size (auto) */ uint32 version; /* For concurrent read/write */ uint32 ftparser_nr; /* distinct ftparser number */ diff --git a/include/mysys_err.h b/include/mysys_err.h index 341e6950792..9f104357f41 100644 --- a/include/mysys_err.h +++ b/include/mysys_err.h @@ -62,7 +62,8 @@ extern const char * NEAR globerrs[]; /* my_error_messages is here */ #define EE_SYNC 27 #define EE_UNKNOWN_COLLATION 28 #define EE_FILENOTFOUND 29 -#define EE_ERROR_LAST 29 /*Copy last error nr.*/ +#define EE_FILE_NOT_CLOSED 30 +#define EE_ERROR_LAST 30 /* Copy last error nr */ /* Add error numbers before EE_ERROR_LAST and change it accordingly. */ /* exit codes for all MySQL programs */ diff --git a/include/violite.h b/include/violite.h index b48f3724f5b..de2ae5386c0 100644 --- a/include/violite.h +++ b/include/violite.h @@ -132,6 +132,7 @@ struct st_VioSSLAcceptorFd const char *ca_file,const char *ca_path, const char *cipher); Vio *new_VioSSL(struct st_VioSSLAcceptorFd *fd, Vio *sd, int state); +void free_vio_ssl_acceptor_fd(struct st_VioSSLAcceptorFd *fd); #endif /* HAVE_OPENSSL */ #ifdef HAVE_SMEM diff --git a/mysql-test/extra/rpl_tests/rpl_failed_optimize.test b/mysql-test/extra/rpl_tests/rpl_failed_optimize.test index 598f9746fab..0c537ee188d 100644 --- a/mysql-test/extra/rpl_tests/rpl_failed_optimize.test +++ b/mysql-test/extra/rpl_tests/rpl_failed_optimize.test @@ -17,3 +17,8 @@ OPTIMIZE TABLE non_existing; sync_slave_with_master; # End of 4.1 tests + +connection master; +select * from t1; +commit; +drop table t1; diff --git a/mysql-test/include/have_ndb.inc b/mysql-test/include/have_ndb.inc index 721d79392b7..8c277ea82a0 100644 --- a/mysql-test/include/have_ndb.inc +++ b/mysql-test/include/have_ndb.inc @@ -5,6 +5,8 @@ show variables like "have_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; diff --git a/mysql-test/lib/mtr_report.pl b/mysql-test/lib/mtr_report.pl index 4587c8bc385..f2da89355f7 100644 --- a/mysql-test/lib/mtr_report.pl +++ b/mysql-test/lib/mtr_report.pl @@ -157,6 +157,7 @@ sub mtr_report_stats ($) { my $tot_passed= 0; my $tot_failed= 0; my $tot_tests= 0; + my $found_problems= 0; # Some warnings are errors... foreach my $tinfo (@$tests) { @@ -214,10 +215,11 @@ sub mtr_report_stats ($) { } else { - my $found_problems= 0; # Some warnings are errors... - # We report different types of problems in order - foreach my $pattern ( "^Warning:", "^Error:", "^==.* at 0x" ) + foreach my $pattern ( "^Warning:", "^Error:", "^==.* at 0x", + "InnoDB: Warning", "missing DBUG_RETURN", + "mysqld: Warning", + "Attempting backtrace", "Assertion .* failed" ) { foreach my $errlog ( sort glob("$::opt_vardir/log/*.err") ) { @@ -231,7 +233,8 @@ sub mtr_report_stats ($) { # Skip some non fatal warnings from the log files if ( /Warning:\s+Table:.* on (delete|rename)/ or /Warning:\s+Setting lower_case_table_names=2/ or - /Warning:\s+One can only use the --user.*root/ ) + /Warning:\s+One can only use the --user.*root/ or + /InnoDB: Warning: we did not need to do crash recovery/) { next; # Skip these lines } @@ -242,11 +245,11 @@ sub mtr_report_stats ($) { } } } - if ( $found_problems ) - { - mtr_warning("Got errors/warnings while running tests, please examine", - "\"$warnlog\" for details."); - } + } + if ( $found_problems ) + { + mtr_warning("Got errors/warnings while running tests, please examine", + "\"$warnlog\" for details."); } } } @@ -266,6 +269,9 @@ sub mtr_report_stats ($) { } } print "\n"; + } + if ( $tot_failed != 0 || $found_problems) + { mtr_error("there where failing test cases"); } } diff --git a/mysql-test/mysql-test-run.pl b/mysql-test/mysql-test-run.pl index 30ac61c80e8..0087459e1dd 100755 --- a/mysql-test/mysql-test-run.pl +++ b/mysql-test/mysql-test-run.pl @@ -1224,17 +1224,20 @@ sub environment_setup () { $ENV{MTR_BUILD_THREAD}= 0 unless $ENV{MTR_BUILD_THREAD}; # Set if not set # We are nice and report a bit about our settings - print "Using MTR_BUILD_THREAD = $ENV{MTR_BUILD_THREAD}\n"; - print "Using MASTER_MYPORT = $ENV{MASTER_MYPORT}\n"; - print "Using MASTER_MYPORT1 = $ENV{MASTER_MYPORT1}\n"; - print "Using SLAVE_MYPORT = $ENV{SLAVE_MYPORT}\n"; - print "Using SLAVE_MYPORT1 = $ENV{SLAVE_MYPORT1}\n"; - print "Using SLAVE_MYPORT2 = $ENV{SLAVE_MYPORT2}\n"; - print "Using NDBCLUSTER_PORT = $ENV{NDBCLUSTER_PORT}\n"; - print "Using NDBCLUSTER_PORT_SLAVE = $ENV{NDBCLUSTER_PORT_SLAVE}\n"; - print "Using IM_PORT = $ENV{IM_PORT}\n"; - print "Using IM_MYSQLD1_PORT = $ENV{IM_MYSQLD1_PORT}\n"; - print "Using IM_MYSQLD2_PORT = $ENV{IM_MYSQLD2_PORT}\n"; + if (!$opt_extern) + { + print "Using MTR_BUILD_THREAD = $ENV{MTR_BUILD_THREAD}\n"; + print "Using MASTER_MYPORT = $ENV{MASTER_MYPORT}\n"; + print "Using MASTER_MYPORT1 = $ENV{MASTER_MYPORT1}\n"; + print "Using SLAVE_MYPORT = $ENV{SLAVE_MYPORT}\n"; + print "Using SLAVE_MYPORT1 = $ENV{SLAVE_MYPORT1}\n"; + print "Using SLAVE_MYPORT2 = $ENV{SLAVE_MYPORT2}\n"; + print "Using NDBCLUSTER_PORT = $ENV{NDBCLUSTER_PORT}\n"; + print "Using NDBCLUSTER_PORT_SLAVE = $ENV{NDBCLUSTER_PORT_SLAVE}\n"; + print "Using IM_PORT = $ENV{IM_PORT}\n"; + print "Using IM_MYSQLD1_PORT = $ENV{IM_MYSQLD1_PORT}\n"; + print "Using IM_MYSQLD2_PORT = $ENV{IM_MYSQLD2_PORT}\n"; + } } @@ -1399,7 +1402,7 @@ sub check_running_as_root () { sub check_ssl_support () { - if ($opt_skip_ssl) + if ($opt_skip_ssl || $opt_extern) { mtr_report("Skipping SSL"); $opt_ssl_supported= 0; @@ -1857,7 +1860,7 @@ sub mysql_install_db () { } } - if ( ndbcluster_install_slave() ) + if ( $use_slaves and ndbcluster_install_slave() ) { if ( $opt_force) { diff --git a/mysql-test/mysql-test-run.sh b/mysql-test/mysql-test-run.sh index 7e1ae58a406..f56099f3a49 100644 --- a/mysql-test/mysql-test-run.sh +++ b/mysql-test/mysql-test-run.sh @@ -205,6 +205,7 @@ TOT_SKIP=0 TOT_PASS=0 TOT_FAIL=0 TOT_TEST=0 +GOT_WARNINGS=0 USERT=0 SYST=0 REALT=0 @@ -1072,22 +1073,21 @@ report_stats () { # $RM -f $MY_LOG_DIR/warnings $MY_LOG_DIR/warnings.tmp # Remove some non fatal warnings from the log files - $SED -e 's!Warning: Table:.* on delete!!g' -e 's!Warning: Setting lower_case_table_names=2!!g' -e 's!Warning: One can only use the --user.*root!!g' \ + $SED -e 's!Warning: Table:.* on delete!!g' -e 's!Warning: Setting lower_case_table_names=2!!g' -e 's!Warning: One can only use the --user.*root!!g' -e 's|InnoDB: Warning: we did not need to do crash recovery||g' \ $MY_LOG_DIR/*.err \ | $SED -e 's!Warning: Table:.* on rename!!g' \ > $MY_LOG_DIR/warnings.tmp - found_error=0 # Find errors - for i in "^Warning:" "^Error:" "^==.* at 0x" "InnoDB: Warning" "missing DBUG_RETURN" + for i in "^Warning:" "^Error:" "^==.* at 0x" "InnoDB: Warning" "missing DBUG_RETURN" "mysqld: Warning" "Attempting backtrace" "Assertion .* failed" do if $GREP "$i" $MY_LOG_DIR/warnings.tmp >> $MY_LOG_DIR/warnings then - found_error=1 + GOT_WARNINGS=1 fi done $RM -f $MY_LOG_DIR/warnings.tmp - if [ $found_error = "1" ] + if [ $GOT_WARNINGS = "1" ] then echo "WARNING: Got errors/warnings while running tests. Please examine" echo "$MY_LOG_DIR/warnings for details." @@ -2300,6 +2300,8 @@ if [ $TOT_FAIL -ne 0 ]; then $ECHO "mysql-test-run in $TEST_MODE mode: *** Failing the test(s):$FAILED_CASES" $ECHO exit 1 -else - exit 0 fi +if [ $GOT_WARNINGS -ne 0 ]; then + exit 1 +fi +exit 0 diff --git a/mysql-test/r/analyze.result b/mysql-test/r/analyze.result index 65c6955a959..fc267cb598d 100644 --- a/mysql-test/r/analyze.result +++ b/mysql-test/r/analyze.result @@ -46,4 +46,12 @@ Field_name Min_value Max_value Min_length Max_length Empties_or_zeros Nulls Avg_ execute stmt1; Field_name Min_value Max_value Min_length Max_length Empties_or_zeros Nulls Avg_value_or_avg_length Std Optimal_fieldtype deallocate prepare stmt1; +create temporary table t1(a int, index(a)); +insert into t1 values('1'),('2'),('3'),('4'),('5'); +analyze table t1; +Table Op Msg_type Msg_text +test.t1 analyze status OK +show index from t1; +Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Null Index_type Comment +t1 1 a 1 a A 5 NULL NULL YES BTREE drop table t1; diff --git a/mysql-test/r/delete.result b/mysql-test/r/delete.result index ddfeeac77b5..05f1c967e77 100644 --- a/mysql-test/r/delete.result +++ b/mysql-test/r/delete.result @@ -186,8 +186,8 @@ a b a b a b explain select * from t1,t2,t3 where t1.a=t2.a AND t2.b=t3.a and t1.b=t3.b; id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE t1 ALL NULL NULL NULL NULL 3 -1 SIMPLE t2 index PRIMARY PRIMARY 8 NULL 3 Using where; Using index -1 SIMPLE t3 index PRIMARY PRIMARY 8 NULL 3 Using where; Using index +1 SIMPLE t2 ref PRIMARY PRIMARY 4 test.t1.a 1 Using index +1 SIMPLE t3 eq_ref PRIMARY PRIMARY 8 test.t2.b,test.t1.b 1 Using index delete t2.*,t3.* from t1,t2,t3 where t1.a=t2.a AND t2.b=t3.a and t1.b=t3.b; select * from t3; a b diff --git a/mysql-test/r/exampledb.result b/mysql-test/r/exampledb.result index 9bfb77c1c0b..6eea24e2e1f 100644 --- a/mysql-test/r/exampledb.result +++ b/mysql-test/r/exampledb.result @@ -1,3 +1,5 @@ +drop database if exists events_test; +drop database if exists events_test2; drop table if exists t1; CREATE TABLE t1 ( Period smallint(4) unsigned zerofill DEFAULT '0000' NOT NULL, diff --git a/mysql-test/r/heap_btree.result b/mysql-test/r/heap_btree.result index a100266978b..7b944558a62 100644 --- a/mysql-test/r/heap_btree.result +++ b/mysql-test/r/heap_btree.result @@ -246,3 +246,13 @@ DELETE from t1 where a < 100; SELECT * from t1; a DROP TABLE t1; +CREATE TABLE t1(val INT, KEY USING BTREE(val)) ENGINE=memory; +INSERT INTO t1 VALUES(0); +SELECT INDEX_LENGTH FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_SCHEMA=DATABASE() AND TABLE_NAME='t1'; +INDEX_LENGTH +21 +UPDATE t1 SET val=1; +SELECT INDEX_LENGTH FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_SCHEMA=DATABASE() AND TABLE_NAME='t1'; +INDEX_LENGTH +21 +DROP TABLE t1; diff --git a/mysql-test/r/innodb.result b/mysql-test/r/innodb.result index f32d7ee264a..7ae87e42b8c 100644 --- a/mysql-test/r/innodb.result +++ b/mysql-test/r/innodb.result @@ -3455,3 +3455,12 @@ SELECT p0.a FROM t2 p0 WHERE BINARY p0.b = 'customer_over'; a 1 drop table t2, t1; +create table t1 (g geometry not null, spatial gk(g)) engine=innodb; +ERROR HY000: The used table type doesn't support SPATIAL indexes +CREATE TABLE t1 ( a int ) ENGINE=innodb; +BEGIN; +INSERT INTO t1 VALUES (1); +OPTIMIZE TABLE t1; +Table Op Msg_type Msg_text +test.t1 optimize status OK +DROP TABLE t1; diff --git a/mysql-test/r/myisam-system.result b/mysql-test/r/myisam-system.result new file mode 100644 index 00000000000..e0629d955ae --- /dev/null +++ b/mysql-test/r/myisam-system.result @@ -0,0 +1,13 @@ +drop table if exists t1,t2; +create table t1 (a int) engine=myisam; +drop table if exists t1; +Warnings: +Error 2 Can't find file: 't1' (errno: 2) +create table t1 (a int) engine=myisam; +drop table t1; +Got one of the listed errors +create table t1 (a int) engine=myisam; +drop table t1; +Got one of the listed errors +drop table t1; +ERROR 42S02: Unknown table 't1' diff --git a/mysql-test/r/myisam.result b/mysql-test/r/myisam.result index 60836408698..8976c98136b 100644 --- a/mysql-test/r/myisam.result +++ b/mysql-test/r/myisam.result @@ -1344,18 +1344,6 @@ drop table t1; create table t1 (v varchar(65535)); ERROR 42000: Row size too large. The maximum row size for the used table type, not counting BLOBs, is 65535. You have to change some columns to TEXT or BLOBs set storage_engine=MyISAM; -create table t1 (a int) engine=myisam; -drop table if exists t1; -Warnings: -Error 2 Can't find file: 't1' (errno: 2) -create table t1 (a int) engine=myisam; -drop table t1; -Got one of the listed errors -create table t1 (a int) engine=myisam; -drop table t1; -Got one of the listed errors -drop table t1; -ERROR 42S02: Unknown table 't1' set @save_concurrent_insert=@@concurrent_insert; set global concurrent_insert=1; create table t1 (a int); @@ -1433,3 +1421,157 @@ create table t3 (c1 int) engine=myisam pack_keys=default; create table t4 (c1 int) engine=myisam pack_keys=2; ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '2' at line 1 drop table t1, t2, t3; +create table t1 (a int not null, key `a` key_block_size=1024 (a)); +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` int(11) NOT NULL, + KEY `a` KEY_BLOCK_SIZE=1024 (`a`) +) ENGINE=MyISAM DEFAULT CHARSET=latin1 +drop table t1; +set @@new=1; +create table t1 (a int not null, key `a` (a) key_block_size=1024); +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` int(11) NOT NULL, + KEY `a` (`a`) KEY_BLOCK_SIZE=1024 +) ENGINE=MyISAM DEFAULT CHARSET=latin1 +drop table t1; +create table t1 (a int not null, key `a` (a) key_block_size=2048); +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` int(11) NOT NULL, + KEY `a` (`a`) KEY_BLOCK_SIZE=2048 +) ENGINE=MyISAM DEFAULT CHARSET=latin1 +drop table t1; +create table t1 (a varchar(2048), key `a` (a)); +Warnings: +Warning 1071 Specified key was too long; max key length is 1000 bytes +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` varchar(2048) DEFAULT NULL, + KEY `a` (`a`(1000)) +) ENGINE=MyISAM DEFAULT CHARSET=latin1 +drop table t1; +create table t1 (a varchar(2048), key `a` (a) key_block_size=1024); +Warnings: +Warning 1071 Specified key was too long; max key length is 1000 bytes +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` varchar(2048) DEFAULT NULL, + KEY `a` (`a`(1000)) KEY_BLOCK_SIZE=4096 +) ENGINE=MyISAM DEFAULT CHARSET=latin1 +drop table t1; +create table t1 (a int not null, b varchar(2048), key (a), key(b)) key_block_size=1024; +Warnings: +Warning 1071 Specified key was too long; max key length is 1000 bytes +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` int(11) NOT NULL, + `b` varchar(2048) DEFAULT NULL, + KEY `a` (`a`), + KEY `b` (`b`(1000)) KEY_BLOCK_SIZE=4096 +) ENGINE=MyISAM DEFAULT CHARSET=latin1 KEY_BLOCK_SIZE=1024 +alter table t1 key_block_size=2048; +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` int(11) NOT NULL, + `b` varchar(2048) DEFAULT NULL, + KEY `a` (`a`) KEY_BLOCK_SIZE=1024, + KEY `b` (`b`(1000)) KEY_BLOCK_SIZE=4096 +) ENGINE=MyISAM DEFAULT CHARSET=latin1 KEY_BLOCK_SIZE=2048 +alter table t1 add c int, add key (c); +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` int(11) NOT NULL, + `b` varchar(2048) DEFAULT NULL, + `c` int(11) DEFAULT NULL, + KEY `a` (`a`) KEY_BLOCK_SIZE=1024, + KEY `b` (`b`(1000)) KEY_BLOCK_SIZE=4096, + KEY `c` (`c`) +) ENGINE=MyISAM DEFAULT CHARSET=latin1 KEY_BLOCK_SIZE=2048 +alter table t1 key_block_size=0; +alter table t1 add d int, add key (d); +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` int(11) NOT NULL, + `b` varchar(2048) DEFAULT NULL, + `c` int(11) DEFAULT NULL, + `d` int(11) DEFAULT NULL, + KEY `a` (`a`) KEY_BLOCK_SIZE=1024, + KEY `b` (`b`(1000)) KEY_BLOCK_SIZE=4096, + KEY `c` (`c`) KEY_BLOCK_SIZE=2048, + KEY `d` (`d`) +) ENGINE=MyISAM DEFAULT CHARSET=latin1 +drop table t1; +create table t1 (a int not null, b varchar(2048), key (a), key(b)) key_block_size=8192; +Warnings: +Warning 1071 Specified key was too long; max key length is 1000 bytes +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` int(11) NOT NULL, + `b` varchar(2048) DEFAULT NULL, + KEY `a` (`a`), + KEY `b` (`b`(1000)) +) ENGINE=MyISAM DEFAULT CHARSET=latin1 KEY_BLOCK_SIZE=8192 +drop table t1; +create table t1 (a int not null, b varchar(2048), key (a) key_block_size=1024, key(b)) key_block_size=8192; +Warnings: +Warning 1071 Specified key was too long; max key length is 1000 bytes +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` int(11) NOT NULL, + `b` varchar(2048) DEFAULT NULL, + KEY `a` (`a`) KEY_BLOCK_SIZE=1024, + KEY `b` (`b`(1000)) +) ENGINE=MyISAM DEFAULT CHARSET=latin1 KEY_BLOCK_SIZE=8192 +drop table t1; +create table t1 (a int not null, b int, key (a) key_block_size=1024, key(b) key_block_size=8192) key_block_size=16384; +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` int(11) NOT NULL, + `b` int(11) DEFAULT NULL, + KEY `a` (`a`) KEY_BLOCK_SIZE=1024, + KEY `b` (`b`) KEY_BLOCK_SIZE=8192 +) ENGINE=MyISAM DEFAULT CHARSET=latin1 KEY_BLOCK_SIZE=16384 +drop table t1; +create table t1 (a int not null, key `a` (a) key_block_size=512); +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` int(11) NOT NULL, + KEY `a` (`a`) KEY_BLOCK_SIZE=1024 +) ENGINE=MyISAM DEFAULT CHARSET=latin1 +drop table t1; +create table t1 (a varchar(2048), key `a` (a) key_block_size=1000000000000000000); +Warnings: +Warning 1071 Specified key was too long; max key length is 1000 bytes +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` varchar(2048) DEFAULT NULL, + KEY `a` (`a`(1000)) KEY_BLOCK_SIZE=4096 +) ENGINE=MyISAM DEFAULT CHARSET=latin1 +drop table t1; +create table t1 (a int not null, key `a` (a) key_block_size=1025); +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` int(11) NOT NULL, + KEY `a` (`a`) KEY_BLOCK_SIZE=2048 +) ENGINE=MyISAM DEFAULT CHARSET=latin1 +drop table t1; +create table t1 (a int not null, key key_block_size=1024 (a)); +ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '=1024 (a))' at line 1 +set @@new=0; diff --git a/mysql-test/r/mysqldump.result b/mysql-test/r/mysqldump.result index c35e1c09c5c..5da2be8da37 100644 --- a/mysql-test/r/mysqldump.result +++ b/mysql-test/r/mysqldump.result @@ -3,13 +3,14 @@ drop database if exists mysqldump_test_db; drop database if exists db1; drop database if exists db2; drop view if exists v1, v2, v3; -CREATE TABLE t1(a int); +CREATE TABLE t1(a int, key (a)) key_block_size=1024; INSERT INTO t1 VALUES (1), (2); <?xml version="1.0"?> <mysqldump xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> <database name="test"> <table_structure name="t1"> - <field Field="a" Type="int(11)" Null="YES" Key="" Extra="" /> + <field Field="a" Type="int(11)" Null="YES" Key="MUL" Extra="" /> + <key Table="t1" Non_unique="1" Key_name="a" Seq_in_index="1" Column_name="a" Collation="A" Null="YES" Index_type="BTREE" Comment="" /> </table_structure> <table_data name="t1"> <row> diff --git a/mysql-test/r/ndb_basic.result b/mysql-test/r/ndb_basic.result index 4a1f5f587df..9477caf97ab 100644 --- a/mysql-test/r/ndb_basic.result +++ b/mysql-test/r/ndb_basic.result @@ -6,6 +6,13 @@ attr1 INT NOT NULL, attr2 INT, attr3 VARCHAR(10) ) ENGINE=ndbcluster; +drop table t1; +CREATE TABLE t1 ( +pk1 INT NOT NULL PRIMARY KEY, +attr1 INT NOT NULL, +attr2 INT, +attr3 VARCHAR(10) +) ENGINE=ndbcluster; SHOW INDEX FROM t1; Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Null Index_type Comment t1 0 PRIMARY 1 pk1 A 0 NULL NULL BTREE diff --git a/mysql-test/r/ndb_blob.result b/mysql-test/r/ndb_blob.result index 9c76d46f4f0..7a781ae3bde 100644 --- a/mysql-test/r/ndb_blob.result +++ b/mysql-test/r/ndb_blob.result @@ -481,14 +481,22 @@ msg text NOT NULL insert into t1 (msg) values( 'Tries to validate (8 byte length + inline bytes) as UTF8 :( Fast fix: removed validation for Text. It is not yet indexable -so bad data will not crash kernel. -Proper fix: Set inline bytes to multiple of mbmaxlen and -validate it (after the 8 byte length).'); +so bad data will not crash kernel.'); select * from t1; id msg 1 Tries to validate (8 byte length + inline bytes) as UTF8 :( Fast fix: removed validation for Text. It is not yet indexable so bad data will not crash kernel. -Proper fix: Set inline bytes to multiple of mbmaxlen and -validate it (after the 8 byte length). +drop table t1; +create table t1 ( +a int primary key not null auto_increment, +b text +) engine=ndbcluster; +select count(*) from t1; +count(*) +500 +truncate t1; +select count(*) from t1; +count(*) +0 drop table t1; diff --git a/mysql-test/r/ndb_config.result b/mysql-test/r/ndb_config.result index d2a8a91828c..c364b8f1b5d 100644 --- a/mysql-test/r/ndb_config.result +++ b/mysql-test/r/ndb_config.result @@ -8,4 +8,3 @@ 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 diff --git a/mysql-test/r/ndb_config2.result b/mysql-test/r/ndb_config2.result new file mode 100644 index 00000000000..cfd012933c4 --- /dev/null +++ b/mysql-test/r/ndb_config2.result @@ -0,0 +1 @@ +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 diff --git a/mysql-test/r/ndb_dd_basic.result b/mysql-test/r/ndb_dd_basic.result index d5ac5071a8e..ee1b717e6f1 100644 --- a/mysql-test/r/ndb_dd_basic.result +++ b/mysql-test/r/ndb_dd_basic.result @@ -5,20 +5,20 @@ INITIAL_SIZE 16M UNDO_BUFFER_SIZE = 1M ENGINE=MYISAM; Warnings: -Error 1539 Table storage engine 'MyISAM' does not support the create option 'TABLESPACE or LOGFILE GROUP' +Error 1465 Table storage engine 'MyISAM' does not support the create option 'TABLESPACE or LOGFILE GROUP' ALTER LOGFILE GROUP lg1 ADD UNDOFILE 'undofile02.dat' INITIAL_SIZE = 4M ENGINE=XYZ; Warnings: Error 1266 Using storage engine MyISAM for table 'lg1' -Error 1539 Table storage engine 'MyISAM' does not support the create option 'TABLESPACE or LOGFILE GROUP' +Error 1465 Table storage engine 'MyISAM' does not support the create option 'TABLESPACE or LOGFILE GROUP' CREATE TABLESPACE ts1 ADD DATAFILE 'datafile.dat' USE LOGFILE GROUP lg1 INITIAL_SIZE 12M; Warnings: -Error 1539 Table storage engine 'MyISAM' does not support the create option 'TABLESPACE or LOGFILE GROUP' +Error 1465 Table storage engine 'MyISAM' does not support the create option 'TABLESPACE or LOGFILE GROUP' set storage_engine=ndb; CREATE LOGFILE GROUP lg1 ADD UNDOFILE 'undofile.dat' diff --git a/mysql-test/r/ndb_dd_ddl.result b/mysql-test/r/ndb_dd_ddl.result index 39dceef1573..47b95214024 100644 --- a/mysql-test/r/ndb_dd_ddl.result +++ b/mysql-test/r/ndb_dd_ddl.result @@ -16,7 +16,7 @@ ERROR HY000: Failed to create LOGFILE GROUP SHOW WARNINGS; Level Code Message Error 1296 Got error 1514 'Currently there is a limit of one logfile group' from NDB -Error 1507 Failed to create LOGFILE GROUP +Error 1515 Failed to create LOGFILE GROUP CREATE LOGFILE GROUP lg1 ADD UNDOFILE 'undofile.dat' INITIAL_SIZE 16M diff --git a/mysql-test/r/rpl_failed_optimize.result b/mysql-test/r/rpl_failed_optimize.result index fd711f89222..ec0b3856ae7 100644 --- a/mysql-test/r/rpl_failed_optimize.result +++ b/mysql-test/r/rpl_failed_optimize.result @@ -18,3 +18,8 @@ Table Op Msg_type Msg_text test.non_existing optimize error Table 'test.non_existing' doesn't exist Warnings: Error 1146 Table 'test.non_existing' doesn't exist +select * from t1; +a +1 +commit; +drop table t1; diff --git a/mysql-test/r/rpl_loaddatalocal.result b/mysql-test/r/rpl_loaddatalocal.result index 20e56a62133..bb1b0610aa8 100644 --- a/mysql-test/r/rpl_loaddatalocal.result +++ b/mysql-test/r/rpl_loaddatalocal.result @@ -18,12 +18,12 @@ select * into outfile 'MYSQLTEST_VARDIR/master-data/rpl_loaddatalocal.select_out drop table t1; create table t1(a int primary key); load data local infile 'MYSQLTEST_VARDIR/master-data/rpl_loaddatalocal.select_outfile' into table t1; -select * from t1; +SELECT * FROM t1 ORDER BY a; a 1 2 3 -select * from t1; +SELECT * FROM t1 ORDER BY a; a 1 2 diff --git a/mysql-test/r/rpl_sp_effects.result b/mysql-test/r/rpl_sp_effects.result index bf8128d9385..26455b65beb 100644 --- a/mysql-test/r/rpl_sp_effects.result +++ b/mysql-test/r/rpl_sp_effects.result @@ -19,24 +19,30 @@ set spv=spv+1; end while; end// call p1(); -select * from t1; +SELECT * FROM t1 ORDER BY a; +a +1 +2 +3 +4 +5 +SELECT * FROM t1 ORDER BY a; a 1 2 3 4 5 -delete from t1; create procedure p2() begin declare a int default 4; create table t2 as select a; end// call p2(); -select * from t2; +SELECT * FROM t2 ORDER BY a; a 4 -select * from t2; +SELECT * FROM t2 ORDER BY a; a 4 drop procedure p1; @@ -61,43 +67,58 @@ end// call p1(f1(1), f1(2)); yes yes -select * from t1; +SELECT * FROM t1 ORDER BY a; a 1 +1 +2 2 +3 +4 +5 5 6 7 8 create table t2(a int); insert into t2 values (10),(11); -select a,f1(a) from t2; +SELECT a,f1(a) FROM t2 ORDER BY a; a f1(a) 10 11 11 12 insert into t2 select f1(3); -select 'master:',a from t1; +SELECT 'master:',a FROM t1 ORDER BY a; master: a master: 1 +master: 1 +master: 2 master: 2 +master: 3 +master: 3 +master: 4 +master: 5 master: 5 master: 6 master: 7 master: 8 master: 10 master: 11 -master: 3 -select 'slave:',a from t1; +SELECT 'slave:',a FROM t1 ORDER BY a; slave: a slave: 1 +slave: 1 +slave: 2 slave: 2 +slave: 3 +slave: 3 +slave: 4 +slave: 5 slave: 5 slave: 6 slave: 7 slave: 8 slave: 10 slave: 11 -slave: 3 drop procedure p1; delete from t1; delete from t2; @@ -108,11 +129,11 @@ select * from v1; f1(a) 2 3 -select 'master:',a from t1; +SELECT 'master:',a FROM t1 ORDER BY a; master: a master: 1 master: 2 -select 'slave:',a from t1; +SELECT 'slave:',a FROM t1 ORDER BY a; slave: a slave: 1 slave: 2 @@ -123,10 +144,10 @@ set @xx=123; execute s1 using @xx; f1(?) 124 -select 'master:',a from t1; +SELECT 'master:',a FROM t1 ORDER BY a; master: a master: 123 -select 'slave:',a from t1; +SELECT 'slave:',a FROM t1 ORDER BY a; slave: a slave: 123 delete from t1; @@ -141,18 +162,18 @@ set spv= spv - 10; end while; end// call p1(15); -select 'master:',a from t1; +SELECT 'master:',a FROM t1 ORDER BY a; master: a -master: 15 -master: 15 master: 6 master: 6 -select 'slave:',a from t1; +master: 15 +master: 15 +SELECT 'slave:',a FROM t1 ORDER BY a; slave: a -slave: 15 -slave: 15 slave: 6 slave: 6 +slave: 15 +slave: 15 drop procedure p1; drop function f1; drop table t1,t2; @@ -187,26 +208,26 @@ f1() 0 set @x=30; call p1(); -select 'master', a from t1; +SELECT 'master', a FROM t1 ORDER BY a; master a -master 20 master 10 master 11 -master 100 -master 101 +master 20 master 30 master 31 +master 100 +master 101 master 101 master 102 -select 'slave', a from t1; +SELECT 'slave', a FROM t1 ORDER BY a; slave a -slave 20 slave 10 slave 11 -slave 100 -slave 101 +slave 20 slave 30 slave 31 +slave 100 +slave 101 slave 101 slave 102 drop table t1; diff --git a/mysql-test/r/select.result b/mysql-test/r/select.result index 9b9f67efeb5..e9092fc8a69 100644 --- a/mysql-test/r/select.result +++ b/mysql-test/r/select.result @@ -3390,3 +3390,24 @@ id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE t2 const PRIMARY PRIMARY 4 const 1 1 SIMPLE t1 range PRIMARY PRIMARY 4 NULL 2 Using where DROP TABLE t1,t2; +CREATE TABLE t1 (i TINYINT UNSIGNED NOT NULL); +INSERT t1 SET i = 0; +UPDATE t1 SET i = -1; +Warnings: +Warning 1264 Out of range value for column 'i' at row 1 +SELECT * FROM t1; +i +0 +UPDATE t1 SET i = CAST(i - 1 AS SIGNED); +Warnings: +Warning 1264 Out of range value for column 'i' at row 1 +SELECT * FROM t1; +i +0 +UPDATE t1 SET i = i - 1; +Warnings: +Warning 1264 Out of range value for column 'i' at row 1 +SELECT * FROM t1; +i +255 +DROP TABLE t1; diff --git a/mysql-test/r/sp_notembedded.result b/mysql-test/r/sp_notembedded.result index e39ddd1d79d..c8cafe5ace1 100644 --- a/mysql-test/r/sp_notembedded.result +++ b/mysql-test/r/sp_notembedded.result @@ -1,3 +1,4 @@ +drop table if exists t1,t3; drop procedure if exists bug4902| create procedure bug4902() begin diff --git a/mysql-test/r/subselect.result b/mysql-test/r/subselect.result index e4850a19b4c..0a464d055c2 100644 --- a/mysql-test/r/subselect.result +++ b/mysql-test/r/subselect.result @@ -1354,10 +1354,10 @@ a explain extended select * from t2 where t2.a in (select t1.a from t1,t3 where t1.b=t3.a); id select_type table type possible_keys key key_len ref rows Extra 1 PRIMARY t2 index NULL a 5 NULL 4 Using where; Using index -2 DEPENDENT SUBQUERY t3 index a a 5 NULL 3 Using index -2 DEPENDENT SUBQUERY t1 ref a a 10 func,test.t3.a 1167 Using where; Using index +2 DEPENDENT SUBQUERY t1 ref a a 5 func 1001 Using where; Using index +2 DEPENDENT SUBQUERY t3 index a a 5 NULL 3 Using where; Using index Warnings: -Note 1003 select `test`.`t2`.`a` AS `a` from `test`.`t2` where <in_optimizer>(`test`.`t2`.`a`,<exists>(select 1 AS `Not_used` from `test`.`t1` join `test`.`t3` where ((`test`.`t1`.`b` = `test`.`t3`.`a`) and (<cache>(`test`.`t2`.`a`) = `test`.`t1`.`a`)))) +Note 1003 select `test`.`t2`.`a` AS `a` from `test`.`t2` where <in_optimizer>(`test`.`t2`.`a`,<exists>(select 1 AS `Not_used` from `test`.`t1` join `test`.`t3` where ((`test`.`t3`.`a` = `test`.`t1`.`b`) and (<cache>(`test`.`t2`.`a`) = `test`.`t1`.`a`)))) insert into t1 values (3,31); select * from t2 where t2.a in (select a from t1 where t1.b <> 30); a diff --git a/mysql-test/t/analyze.test b/mysql-test/t/analyze.test index a8fd0a4283e..1801a4a440f 100644 --- a/mysql-test/t/analyze.test +++ b/mysql-test/t/analyze.test @@ -61,6 +61,14 @@ prepare stmt1 from "SELECT * FROM t1 PROCEDURE ANALYSE()"; execute stmt1; execute stmt1; deallocate prepare stmt1; + +# +# bug#15225 (ANALYZE temporary has no effect) +# +create temporary table t1(a int, index(a)); +insert into t1 values('1'),('2'),('3'),('4'),('5'); +analyze table t1; +show index from t1; drop table t1; # End of 4.1 tests diff --git a/mysql-test/t/disabled.def b/mysql-test/t/disabled.def index 4068e409e32..288d060b2b5 100644 --- a/mysql-test/t/disabled.def +++ b/mysql-test/t/disabled.def @@ -32,7 +32,7 @@ rpl_ndb_log : BUG#18947 2006-03-21 tomas CRBR: order in binlog of c rpl_ndb_myisam2ndb : BUG#17400 2006-04-19 tomas Cluster Replication: delete & update of rows in table without pk fails on slave. rpl_switch_stm_row_mixed : BUG#18590 2006-03-28 brian rpl_row_blob_innodb : BUG#18980 2006-04-10 kent Test fails randomly -rpl_row_func003 : BUG#19074 2006-13-04 andrei test failed +rpl_row_func003 : BUG#19074 2006-13-04 andrei test failed rpl_row_inexist_tbl : BUG#18948 2006-03-09 mats Disabled since patch makes this test wait forever rpl_sp : BUG#16456 2006-02-16 jmiller udf : BUG#18564 2006-03-27 ian (Permission by Brian) diff --git a/mysql-test/t/exampledb.test b/mysql-test/t/exampledb.test index 946d25325dc..fbb2a18f344 100644 --- a/mysql-test/t/exampledb.test +++ b/mysql-test/t/exampledb.test @@ -5,6 +5,10 @@ -- source include/have_exampledb.inc --disable_warnings +# Clean up if event's test fails +drop database if exists events_test; +drop database if exists events_test2; + drop table if exists t1; --enable_warnings diff --git a/mysql-test/t/heap_btree.test b/mysql-test/t/heap_btree.test index 5e493c2643b..f1b9d290885 100644 --- a/mysql-test/t/heap_btree.test +++ b/mysql-test/t/heap_btree.test @@ -164,4 +164,16 @@ DELETE from t1 where a < 100; SELECT * from t1; DROP TABLE t1; +# +# BUG#18160 - Memory-/HEAP Table endless growing indexes +# +CREATE TABLE t1(val INT, KEY USING BTREE(val)) ENGINE=memory; +INSERT INTO t1 VALUES(0); +--replace_result 37 21 +SELECT INDEX_LENGTH FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_SCHEMA=DATABASE() AND TABLE_NAME='t1'; +UPDATE t1 SET val=1; +--replace_result 37 21 +SELECT INDEX_LENGTH FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_SCHEMA=DATABASE() AND TABLE_NAME='t1'; +DROP TABLE t1; + # End of 4.1 tests diff --git a/mysql-test/t/innodb.test b/mysql-test/t/innodb.test index cadb611714c..92e060eed92 100644 --- a/mysql-test/t/innodb.test +++ b/mysql-test/t/innodb.test @@ -2494,3 +2494,19 @@ SELECT DISTINCT p0.a FROM t2 p0 WHERE BINARY p0.b = 'customer_over'; SELECT p0.a FROM t2 p0 WHERE BINARY p0.b = 'customer_over'; drop table t2, t1; + +# +# Bug #15680 (SPATIAL key in innodb) +# +--error ER_TABLE_CANT_HANDLE_SPKEYS +create table t1 (g geometry not null, spatial gk(g)) engine=innodb; + +# +# Test optimize on table with open transaction +# + +CREATE TABLE t1 ( a int ) ENGINE=innodb; +BEGIN; +INSERT INTO t1 VALUES (1); +OPTIMIZE TABLE t1; +DROP TABLE t1; diff --git a/mysql-test/t/log_tables.test b/mysql-test/t/log_tables.test index 3b412d9e793..048da802d02 100644 --- a/mysql-test/t/log_tables.test +++ b/mysql-test/t/log_tables.test @@ -63,10 +63,10 @@ flush logs; # check locking of the log tables # ---error 1533 +--error ER_CANT_WRITE_LOCK_LOG_TABLE lock tables mysql.general_log WRITE; ---error 1533 +--error ER_CANT_WRITE_LOCK_LOG_TABLE lock tables mysql.slow_log WRITE; # @@ -75,10 +75,10 @@ lock tables mysql.slow_log WRITE; # tables are always opened and locked by the logger. # ---error 1534 +--error ER_CANT_READ_LOCK_LOG_TABLE lock tables mysql.general_log READ; ---error 1534 +--error ER_CANT_READ_LOCK_LOG_TABLE lock tables mysql.slow_log READ; # diff --git a/mysql-test/t/myisam-system.test b/mysql-test/t/myisam-system.test new file mode 100644 index 00000000000..43fbaabf698 --- /dev/null +++ b/mysql-test/t/myisam-system.test @@ -0,0 +1,21 @@ +# +# Test how DROP TABLE works if the index or data file doesn't exists + +# Initialise +--disable_warnings +drop table if exists t1,t2; +--enable_warnings + +create table t1 (a int) engine=myisam; +system rm $MYSQLTEST_VARDIR/master-data/test/t1.MYI ; +drop table if exists t1; +create table t1 (a int) engine=myisam; +system rm $MYSQLTEST_VARDIR/master-data/test/t1.MYI ; +--error 1051,6 +drop table t1; +create table t1 (a int) engine=myisam; +system rm $MYSQLTEST_VARDIR/master-data/test/t1.MYD ; +--error 1105,6,29 +drop table t1; +--error 1051 +drop table t1; diff --git a/mysql-test/t/myisam.test b/mysql-test/t/myisam.test index 15533ca00e6..87a00399c23 100644 --- a/mysql-test/t/myisam.test +++ b/mysql-test/t/myisam.test @@ -727,23 +727,6 @@ create table t1 (v varchar(65535)); eval set storage_engine=$default; # -# Test how DROP TABLE works if the index or data file doesn't exists - -create table t1 (a int) engine=myisam; -system rm $MYSQLTEST_VARDIR/master-data/test/t1.MYI ; -drop table if exists t1; -create table t1 (a int) engine=myisam; -system rm $MYSQLTEST_VARDIR/master-data/test/t1.MYI ; ---error 1051,6 -drop table t1; -create table t1 (a int) engine=myisam; -system rm $MYSQLTEST_VARDIR/master-data/test/t1.MYD ; ---error 1105,6,29 -drop table t1; ---error 1051 -drop table t1; - -# # Test concurrent insert # First with static record length # @@ -824,3 +807,72 @@ create table t3 (c1 int) engine=myisam pack_keys=default; create table t4 (c1 int) engine=myisam pack_keys=2; drop table t1, t2, t3; +# +# Test of key_block_size +# + +# Old format, to be obsolete in 5.3 +create table t1 (a int not null, key `a` key_block_size=1024 (a)); +show create table t1; +drop table t1; + +set @@new=1; + +create table t1 (a int not null, key `a` (a) key_block_size=1024); +show create table t1; +drop table t1; + +create table t1 (a int not null, key `a` (a) key_block_size=2048); +show create table t1; +drop table t1; + +create table t1 (a varchar(2048), key `a` (a)); +show create table t1; +drop table t1; + +create table t1 (a varchar(2048), key `a` (a) key_block_size=1024); +show create table t1; +drop table t1; + +create table t1 (a int not null, b varchar(2048), key (a), key(b)) key_block_size=1024; +show create table t1; +alter table t1 key_block_size=2048; +show create table t1; +alter table t1 add c int, add key (c); +show create table t1; +alter table t1 key_block_size=0; +alter table t1 add d int, add key (d); +show create table t1; +drop table t1; + +create table t1 (a int not null, b varchar(2048), key (a), key(b)) key_block_size=8192; +show create table t1; +drop table t1; + +create table t1 (a int not null, b varchar(2048), key (a) key_block_size=1024, key(b)) key_block_size=8192; +show create table t1; +drop table t1; + +create table t1 (a int not null, b int, key (a) key_block_size=1024, key(b) key_block_size=8192) key_block_size=16384; +show create table t1; +drop table t1; + + +# Test limits and errors of key_block_size + +create table t1 (a int not null, key `a` (a) key_block_size=512); +show create table t1; +drop table t1; + +create table t1 (a varchar(2048), key `a` (a) key_block_size=1000000000000000000); +show create table t1; +drop table t1; + +create table t1 (a int not null, key `a` (a) key_block_size=1025); +show create table t1; +drop table t1; + +--error 1064 +create table t1 (a int not null, key key_block_size=1024 (a)); + +set @@new=0; diff --git a/mysql-test/t/mysqldump.test b/mysql-test/t/mysqldump.test index 59e09a6407a..c5c3f88d8c8 100644 --- a/mysql-test/t/mysqldump.test +++ b/mysql-test/t/mysqldump.test @@ -11,7 +11,7 @@ drop view if exists v1, v2, v3; # XML output -CREATE TABLE t1(a int); +CREATE TABLE t1(a int, key (a)) key_block_size=1024; INSERT INTO t1 VALUES (1), (2); --exec $MYSQL_DUMP --skip-create --skip-comments -X test t1 DROP TABLE t1; diff --git a/mysql-test/t/ndb_basic.test b/mysql-test/t/ndb_basic.test index ab62e3dd13a..edf74ab1df9 100644 --- a/mysql-test/t/ndb_basic.test +++ b/mysql-test/t/ndb_basic.test @@ -6,6 +6,18 @@ DROP TABLE IF EXISTS t1,t2,t3,t4,t5,t6,t7; drop database if exists mysqltest; --enable_warnings +# workaround for bug#16445 +# remove to reproduce bug and run tests from ndb start +# and with ndb_autodiscover disabled. Fails on Linux 50 % of the times + +CREATE TABLE t1 ( + pk1 INT NOT NULL PRIMARY KEY, + attr1 INT NOT NULL, + attr2 INT, + attr3 VARCHAR(10) +) ENGINE=ndbcluster; +drop table t1; + # # Basic test to show that the NDB # table handler is working diff --git a/mysql-test/t/ndb_blob.test b/mysql-test/t/ndb_blob.test index f80b7f71281..bf82a793049 100644 --- a/mysql-test/t/ndb_blob.test +++ b/mysql-test/t/ndb_blob.test @@ -403,10 +403,29 @@ create table t1 ( insert into t1 (msg) values( 'Tries to validate (8 byte length + inline bytes) as UTF8 :( Fast fix: removed validation for Text. It is not yet indexable -so bad data will not crash kernel. -Proper fix: Set inline bytes to multiple of mbmaxlen and -validate it (after the 8 byte length).'); +so bad data will not crash kernel.'); select * from t1; drop table t1; +# -- bug #19201 +create table t1 ( + a int primary key not null auto_increment, + b text +) engine=ndbcluster; +--disable_query_log +set autocommit=1; +# more rows than batch size (64) +# for this bug no blob parts would be necessary +let $1 = 500; +while ($1) +{ + insert into t1 (b) values (repeat('x',4000)); + dec $1; +} +--enable_query_log +select count(*) from t1; +truncate t1; +select count(*) from t1; +drop table t1; + # End of 4.1 tests diff --git a/mysql-test/t/ndb_config.test b/mysql-test/t/ndb_config.test index 4787abe86e2..2fe54cac048 100644 --- a/mysql-test/t/ndb_config.test +++ b/mysql-test/t/ndb_config.test @@ -15,4 +15,3 @@ --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 diff --git a/mysql-test/t/ndb_config2.test b/mysql-test/t/ndb_config2.test new file mode 100644 index 00000000000..170f1b2e5e7 --- /dev/null +++ b/mysql-test/t/ndb_config2.test @@ -0,0 +1,7 @@ +-- source include/have_ndb.inc +-- source include/ndb_default_cluster.inc +-- source include/not_embedded.inc + +# Following doesn't work in all configurations (if shm is not defined) + +--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 diff --git a/mysql-test/t/ndb_partition_error.test b/mysql-test/t/ndb_partition_error.test index 286c2216f70..06581f1270f 100644 --- a/mysql-test/t/ndb_partition_error.test +++ b/mysql-test/t/ndb_partition_error.test @@ -66,6 +66,6 @@ partition by list(a) partitions 2 (partition x123 values in (11, 12), partition x234 values in (5, 1)); ---error 1505 +--error ER_NO_PARTITION_FOR_GIVEN_VALUE insert into t1 values (NULL,1,1); drop table t1; diff --git a/mysql-test/t/rpl_loaddatalocal.test b/mysql-test/t/rpl_loaddatalocal.test index af4fd0106bd..758ac94af24 100644 --- a/mysql-test/t/rpl_loaddatalocal.test +++ b/mysql-test/t/rpl_loaddatalocal.test @@ -53,11 +53,11 @@ create table t1(a int primary key); --replace_result $MYSQLTEST_VARDIR MYSQLTEST_VARDIR eval load data local infile '$MYSQLTEST_VARDIR/master-data/rpl_loaddatalocal.select_outfile' into table t1; system rm $MYSQLTEST_VARDIR/master-data/rpl_loaddatalocal.select_outfile ; -select * from t1; +SELECT * FROM t1 ORDER BY a; save_master_pos; connection slave; sync_with_master; -select * from t1; +SELECT * FROM t1 ORDER BY a; connection master; drop table t1; save_master_pos; diff --git a/mysql-test/t/rpl_sp_effects.test b/mysql-test/t/rpl_sp_effects.test index c081f8e00c6..40c9a5d0b74 100644 --- a/mysql-test/t/rpl_sp_effects.test +++ b/mysql-test/t/rpl_sp_effects.test @@ -1,3 +1,9 @@ +########################################## +# Change Author: JBM +# Change Date: 2006-05-02 +# Change: Added Order By for NDB testing +########################################## + # Test of replication of stored procedures (WL#2146 for MySQL 5.0) -- source include/master-slave.inc @@ -30,9 +36,9 @@ call p1(); sync_slave_with_master; connection slave; -select * from t1; +SELECT * FROM t1 ORDER BY a; connection master; -delete from t1; +SELECT * FROM t1 ORDER BY a; # 2. Test SP variable name delimiter //; @@ -44,10 +50,10 @@ end// delimiter ;// call p2(); -select * from t2; +SELECT * FROM t2 ORDER BY a; sync_slave_with_master; connection slave; -select * from t2; +SELECT * FROM t2 ORDER BY a; connection master; drop procedure p1; @@ -78,19 +84,19 @@ end// delimiter ;// call p1(f1(1), f1(2)); -select * from t1; +SELECT * FROM t1 ORDER BY a; create table t2(a int); insert into t2 values (10),(11); -select a,f1(a) from t2; +SELECT a,f1(a) FROM t2 ORDER BY a; # This shouldn't put separate 'call f1(3)' into binlog: insert into t2 select f1(3); -select 'master:',a from t1; +SELECT 'master:',a FROM t1 ORDER BY a; sync_slave_with_master; connection slave; -select 'slave:',a from t1; +SELECT 'slave:',a FROM t1 ORDER BY a; connection master; drop procedure p1; @@ -102,11 +108,11 @@ delete from t1; insert into t2 values(1),(2); create view v1 as select f1(a) from t2; select * from v1; -select 'master:',a from t1; +SELECT 'master:',a FROM t1 ORDER BY a; sync_slave_with_master; connection slave; -select 'slave:',a from t1; +SELECT 'slave:',a FROM t1 ORDER BY a; connection master; drop view v1; @@ -116,11 +122,11 @@ delete from t1; prepare s1 from 'select f1(?)'; set @xx=123; execute s1 using @xx; -select 'master:',a from t1; +SELECT 'master:',a FROM t1 ORDER BY a; sync_slave_with_master; connection slave; -select 'slave:',a from t1; +SELECT 'slave:',a FROM t1 ORDER BY a; connection master; delete from t1; @@ -140,10 +146,10 @@ begin end// delimiter ;// call p1(15); -select 'master:',a from t1; +SELECT 'master:',a FROM t1 ORDER BY a; sync_slave_with_master; connection slave; -select 'slave:',a from t1; +SELECT 'slave:',a FROM t1 ORDER BY a; connection master; drop procedure p1; @@ -188,10 +194,10 @@ select f1(); set @x=30; call p1(); -select 'master', a from t1; +SELECT 'master', a FROM t1 ORDER BY a; sync_slave_with_master; connection slave; -select 'slave', a from t1; +SELECT 'slave', a FROM t1 ORDER BY a; connection master; drop table t1; diff --git a/mysql-test/t/select.test b/mysql-test/t/select.test index c4fe1906cbc..8e3c5847846 100644 --- a/mysql-test/t/select.test +++ b/mysql-test/t/select.test @@ -2871,3 +2871,18 @@ SELECT t2.sku, t2.sppr, t2.name, t1.sku, t1.pr DROP TABLE t1,t2; + +# +# Bug#18712: Truncation problem (needs just documenting and test +# cases to prevent fixing this accidently. It is intended behaviour) +# + +CREATE TABLE t1 (i TINYINT UNSIGNED NOT NULL); +INSERT t1 SET i = 0; +UPDATE t1 SET i = -1; +SELECT * FROM t1; +UPDATE t1 SET i = CAST(i - 1 AS SIGNED); +SELECT * FROM t1; +UPDATE t1 SET i = i - 1; +SELECT * FROM t1; +DROP TABLE t1; diff --git a/mysql-test/t/sp_notembedded.test b/mysql-test/t/sp_notembedded.test index 4eb429156b2..0adbeb2d98b 100644 --- a/mysql-test/t/sp_notembedded.test +++ b/mysql-test/t/sp_notembedded.test @@ -1,6 +1,10 @@ # Can't test with embedded server -- source include/not_embedded.inc +--sleep 2 +--disable_warnings +drop table if exists t1,t3; +--enable_warnings delimiter |; # diff --git a/mysys/errors.c b/mysys/errors.c index 4472b7173fa..5fe9eadb522 100644 --- a/mysys/errors.c +++ b/mysys/errors.c @@ -39,7 +39,7 @@ const char * NEAR globerrs[GLOBERRS]= "Can't get working dirctory (Errcode: %d)", "Can't change dir to '%s' (Errcode: %d)", "Warning: '%s' had %d links", - "%d files and %d streams is left open\n", + "Warning: %d files and %d streams is left open\n", "Disk is full writing '%s' (Errcode: %d). Waiting for someone to free space... Retry in %d secs", "Can't create directory '%s' (Errcode: %d)", "Character set '%s' is not a compiled character set and is not specified in the '%s' file", @@ -50,6 +50,7 @@ const char * NEAR globerrs[GLOBERRS]= "Can't sync file '%s' to disk (Errcode: %d)", "Collation '%s' is not a compiled collation and is not specified in the '%s' file", "File '%s' not found (Errcode: %d)", + "File '%s' (fileno: %d) was not closed" }; void init_glob_errs(void) @@ -78,7 +79,7 @@ void init_glob_errs() EE(EE_GETWD) = "Can't get working dirctory (Errcode: %d)"; EE(EE_SETWD) = "Can't change dir to '%s' (Errcode: %d)"; EE(EE_LINK_WARNING) = "Warning: '%s' had %d links"; - EE(EE_OPEN_WARNING) = "%d files and %d streams is left open\n"; + EE(EE_OPEN_WARNING) = "Warning: %d files and %d streams is left open\n"; EE(EE_DISK_FULL) = "Disk is full writing '%s'. Waiting for someone to free space..."; EE(EE_CANT_MKDIR) ="Can't create directory '%s' (Errcode: %d)"; EE(EE_UNKNOWN_CHARSET)= "Character set '%s' is not a compiled character set and is not specified in the %s file"; @@ -89,5 +90,6 @@ void init_glob_errs() EE(EE_SYNC)= "Can't sync file '%s' to disk (Errcode: %d)"; EE(EE_UNKNOWN_COLLATION)= "Collation '%s' is not a compiled collation and is not specified in the %s file"; EE(EE_FILENOTFOUND) = "File '%s' not found (Errcode: %d)"; + EE(EE_FILE_NOT_CLOSED) = "File '%s' (fileno: %d) was not closed"; } #endif diff --git a/mysys/mf_keycache.c b/mysys/mf_keycache.c index bf8986fe05b..1dab9a47ed8 100644 --- a/mysys/mf_keycache.c +++ b/mysys/mf_keycache.c @@ -262,15 +262,9 @@ static int keycache_pthread_cond_signal(pthread_cond_t *cond); #define keycache_pthread_cond_signal pthread_cond_signal #endif /* defined(KEYCACHE_DEBUG) */ -static uint next_power(uint value) +static inline uint next_power(uint value) { - uint old_value= 1; - while (value) - { - old_value= value; - value&= value-1; - } - return (old_value << 1); + return (uint) my_round_up_to_next_power((uint32) value) << 1; } diff --git a/mysys/my_bit.c b/mysys/my_bit.c index 01c9b5ea68d..6ef0e171695 100644 --- a/mysys/my_bit.c +++ b/mysys/my_bit.c @@ -76,3 +76,33 @@ uint my_count_bits_ushort(ushort v) return nbits[v]; } + +/* + Next highest power of two + + SYNOPSIS + my_round_up_to_next_power() + v Value to check + + RETURN + Next or equal power of 2 + Note: 0 will return 0 + + NOTES + Algorithm by Sean Anderson, according to: + http://graphics.stanford.edu/~seander/bithacks.html + (Orignal code public domain) + + Comments shows how this works with 01100000000000000000000000001011 +*/ + +uint32 my_round_up_to_next_power(uint32 v) +{ + v--; /* 01100000000000000000000000001010 */ + v|= v >> 1; /* 01110000000000000000000000001111 */ + v|= v >> 2; /* 01111100000000000000000000001111 */ + v|= v >> 4; /* 01111111110000000000000000001111 */ + v|= v >> 8; /* 01111111111111111100000000001111 */ + v|= v >> 16; /* 01111111111111111111111111111111 */ + return v+1; /* 10000000000000000000000000000000 */ +} diff --git a/mysys/my_file.c b/mysys/my_file.c index 4c333c7d7db..0abc031a195 100644 --- a/mysys/my_file.c +++ b/mysys/my_file.c @@ -107,7 +107,10 @@ uint my_set_max_open_files(uint files) DBUG_RETURN(MY_NFILE); /* Copy any initialized files */ - memcpy((char*) tmp, (char*) my_file_info, sizeof(*tmp) * my_file_limit); + memcpy((char*) tmp, (char*) my_file_info, + sizeof(*tmp) * min(my_file_limit, files)); + bzero((char*) (tmp + my_file_limit), + max((int) (files- my_file_limit), 0)*sizeof(*tmp)); my_free_open_file_info(); /* Free if already allocated */ my_file_info= tmp; my_file_limit= files; @@ -121,8 +124,12 @@ void my_free_open_file_info() DBUG_ENTER("my_free_file_info"); if (my_file_info != my_file_info_default) { + /* Copy data back for my_print_open_files */ + memcpy((char*) my_file_info_default, my_file_info, + sizeof(*my_file_info_default)* MY_NFILE); my_free((char*) my_file_info, MYF(0)); my_file_info= my_file_info_default; + my_file_limit= MY_NFILE; } DBUG_VOID_RETURN; } diff --git a/mysys/my_init.c b/mysys/my_init.c index 88b8e457bd6..4d7299c7cb1 100644 --- a/mysys/my_init.c +++ b/mysys/my_init.c @@ -150,6 +150,7 @@ void my_end(int infoflag) sprintf(errbuff[0],EE(EE_OPEN_WARNING),my_file_opened,my_stream_opened); (void) my_message_no_curses(EE_OPEN_WARNING,errbuff[0],ME_BELL); DBUG_PRINT("error",("%s",errbuff[0])); + my_print_open_files(); } } free_charsets(); diff --git a/mysys/my_open.c b/mysys/my_open.c index 098d410d8ce..ed323b3b1ad 100644 --- a/mysys/my_open.c +++ b/mysys/my_open.c @@ -351,3 +351,24 @@ File my_sopen(const char *path, int oflag, int shflag, int pmode) return fh; /* return handle */ } #endif /* __WIN__ */ + + +#ifdef EXTRA_DEBUG + +void my_print_open_files(void) +{ + if (my_file_opened | my_stream_opened) + { + uint i; + for (i= 0 ; i < my_file_limit ; i++) + { + if (my_file_info[i].type != UNOPEN) + { + fprintf(stderr, EE(EE_FILE_NOT_CLOSED), my_file_info[i].name, i); + fputc('\n', stderr); + } + } + } +} + +#endif diff --git a/mysys/tree.c b/mysys/tree.c index 1780913961e..0c9c04919b0 100644 --- a/mysys/tree.c +++ b/mysys/tree.c @@ -271,7 +271,7 @@ TREE_ELEMENT *tree_insert(TREE *tree, void *key, uint key_size, return element; } -int tree_delete(TREE *tree, void *key, void *custom_arg) +int tree_delete(TREE *tree, void *key, uint key_size, void *custom_arg) { int cmp,remove_colour; TREE_ELEMENT *element,***parent, ***org_parent, *nod; @@ -326,8 +326,7 @@ int tree_delete(TREE *tree, void *key, void *custom_arg) rb_delete_fixup(tree,parent); if (tree->free) (*tree->free)(ELEMENT_KEY(tree,element), free_free, tree->custom_arg); - /* This doesn't include key_size, but better than nothing */ - tree->allocated-= sizeof(TREE_ELEMENT)+tree->size_of_element; + tree->allocated-= sizeof(TREE_ELEMENT) + tree->size_of_element + key_size; my_free((gptr) element,MYF(0)); tree->elements_in_tree--; return 0; diff --git a/sql/event_timed.cc b/sql/event_timed.cc index ed012ecd399..879f4d6a3c9 100644 --- a/sql/event_timed.cc +++ b/sql/event_timed.cc @@ -19,10 +19,6 @@ #include "event.h" #include "sp.h" - - -extern int MYSQLparse(void *thd); - /* Init all member variables diff --git a/sql/ha_berkeley.cc b/sql/ha_berkeley.cc index ef1876c0e2e..473fb149871 100644 --- a/sql/ha_berkeley.cc +++ b/sql/ha_berkeley.cc @@ -2742,7 +2742,8 @@ mysql_declare_plugin(berkeley) berkeley_hton_comment, NULL, /* Plugin Init */ NULL, /* Plugin Deinit */ - 0x0100 /* 1.0 */, + 0x0100, /* 1.0 */ + 0 } mysql_declare_plugin_end; diff --git a/sql/ha_heap.cc b/sql/ha_heap.cc index ca33a31de4b..1a7efb42748 100644 --- a/sql/ha_heap.cc +++ b/sql/ha_heap.cc @@ -720,6 +720,7 @@ mysql_declare_plugin(heap) heap_hton_comment, NULL, NULL, + 0x0100, /* 1.0 */ 0 } mysql_declare_plugin_end; diff --git a/sql/ha_innodb.cc b/sql/ha_innodb.cc index 3f606cd0b15..0b2f561e8c9 100644 --- a/sql/ha_innodb.cc +++ b/sql/ha_innodb.cc @@ -7470,6 +7470,7 @@ mysql_declare_plugin(innobase) NULL, /* Plugin Init */ NULL, /* Plugin Deinit */ 0x0100 /* 1.0 */, + 0 } mysql_declare_plugin_end; diff --git a/sql/ha_myisam.cc b/sql/ha_myisam.cc index 74aa157cbc1..786d45a4966 100644 --- a/sql/ha_myisam.cc +++ b/sql/ha_myisam.cc @@ -194,7 +194,7 @@ ha_myisam::ha_myisam(TABLE_SHARE *table_arg) int_table_flags(HA_NULL_IN_KEY | HA_CAN_FULLTEXT | HA_CAN_SQL_HANDLER | HA_DUPP_POS | HA_CAN_INDEX_BLOBS | HA_AUTO_PART_KEY | HA_FILE_BASED | HA_CAN_GEOMETRY | HA_READ_RND_SAME | - HA_CAN_INSERT_DELAYED | HA_CAN_BIT_FIELD), + HA_CAN_INSERT_DELAYED | HA_CAN_BIT_FIELD | HA_CAN_RTREEKEYS), can_enable_indexes(1) {} @@ -356,6 +356,7 @@ int ha_myisam::open(const char *name, int mode, uint test_if_locked) if (table->key_info[i].flags & HA_USES_PARSER) file->s->keyinfo[i].parser= (struct st_mysql_ftparser *)parser->plugin->info; + table->key_info[i].block_size= file->s->keyinfo[i].block_length; } return (0); } @@ -1374,7 +1375,7 @@ void ha_myisam::info(uint flag) sortkey= info.sortkey; ref_length= info.reflength; share->db_options_in_use= info.options; - block_size= myisam_block_size; + block_size= myisam_block_size; /* record block size */ /* Update share */ if (share->tmp_table == NO_TMP_TABLE) @@ -1507,6 +1508,8 @@ int ha_myisam::create(const char *name, register TABLE *table_arg, keydef[i].key_alg= pos->algorithm == HA_KEY_ALG_UNDEF ? (pos->flags & HA_SPATIAL ? HA_KEY_ALG_RTREE : HA_KEY_ALG_BTREE) : pos->algorithm; + keydef[i].block_length= pos->block_size; + keydef[i].seg=keyseg; keydef[i].keysegs=pos->key_parts; for (j=0 ; j < pos->key_parts ; j++) @@ -1804,6 +1807,7 @@ mysql_declare_plugin(myisam) myisam_hton_comment, NULL, /* Plugin Init */ NULL, /* Plugin Deinit */ - 0x0100 /* 1.0 */, + 0x0100, /* 1.0 */ + 0 } mysql_declare_plugin_end; diff --git a/sql/ha_myisammrg.cc b/sql/ha_myisammrg.cc index 89f0f9e3647..1cde37644bc 100644 --- a/sql/ha_myisammrg.cc +++ b/sql/ha_myisammrg.cc @@ -589,6 +589,7 @@ mysql_declare_plugin(myisammrg) myisammrg_hton_comment, NULL, /* Plugin Init */ NULL, /* Plugin Deinit */ - 0x0100 /* 1.0 */, + 0x0100, /* 1.0 */ + 0 } mysql_declare_plugin_end; diff --git a/sql/ha_ndbcluster.cc b/sql/ha_ndbcluster.cc index 10d90dc1e04..b84350fd3b8 100644 --- a/sql/ha_ndbcluster.cc +++ b/sql/ha_ndbcluster.cc @@ -6217,10 +6217,10 @@ static int ndbcluster_end(ha_panic_function type) #ifdef HAVE_NDB_BINLOG { pthread_mutex_lock(&ndbcluster_mutex); - for (uint i= 0; i < ndbcluster_open_tables.records; i++) + while (ndbcluster_open_tables.records) { NDB_SHARE *share= - (NDB_SHARE*) hash_element(&ndbcluster_open_tables, i); + (NDB_SHARE*) hash_element(&ndbcluster_open_tables, 0); #ifndef DBUG_OFF fprintf(stderr, "NDB: table share %s with use_count %d not freed\n", share->key, share->use_count); @@ -10186,6 +10186,7 @@ mysql_declare_plugin(ndbcluster) NULL, /* Plugin Init */ NULL, /* Plugin Deinit */ 0x0100 /* 1.0 */, + 0 } mysql_declare_plugin_end; diff --git a/sql/ha_partition.cc b/sql/ha_partition.cc index bff21d6681d..b1a5a447b6f 100644 --- a/sql/ha_partition.cc +++ b/sql/ha_partition.cc @@ -5455,7 +5455,8 @@ mysql_declare_plugin(partition) partition_hton_comment, NULL, /* Plugin Init */ NULL, /* Plugin Deinit */ - 0x0100 /* 1.0 */, + 0x0100, /* 1.0 */ + 0 } mysql_declare_plugin_end; diff --git a/sql/handler.cc b/sql/handler.cc index bf84ec16ea8..b9ef05a33c2 100644 --- a/sql/handler.cc +++ b/sql/handler.cc @@ -51,6 +51,8 @@ static handlerton *installed_htons[128]; #define BITMAP_STACKBUF_SIZE (128/8) +KEY_CREATE_INFO default_key_create_info= { HA_KEY_ALG_UNDEF, 0, {NullS,0} }; + /* static functions defined in this file */ static handler *create_default(TABLE_SHARE *table); @@ -3262,10 +3264,11 @@ int handler::ha_external_lock(THD *thd, int lock_type) locking combined with row-based replication needs to be looked over. Ideally, no such special handling should be needed. */ - switch (thd->lex->sql_command) - { + switch (thd->lex->sql_command) { case SQLCOM_TRUNCATE: case SQLCOM_ALTER_TABLE: + case SQLCOM_OPTIMIZE: + case SQLCOM_REPAIR: DBUG_RETURN(0); default: break; diff --git a/sql/handler.h b/sql/handler.h index 92b177807b7..d988e46b236 100644 --- a/sql/handler.h +++ b/sql/handler.h @@ -84,6 +84,7 @@ access on the table based on a given record. */ #define HA_PRIMARY_KEY_ALLOW_RANDOM_ACCESS (1 << 16) +#define HA_CAN_RTREEKEYS (1 << 17) #define HA_NOT_DELETE_WITH_CACHE (1 << 18) #define HA_NO_PREFIX_CHAR_KEYS (1 << 20) #define HA_CAN_FULLTEXT (1 << 21) @@ -281,6 +282,7 @@ enum enum_binlog_command { #define HA_CREATE_USED_COMMENT (1L << 16) #define HA_CREATE_USED_PASSWORD (1L << 17) #define HA_CREATE_USED_CONNECTION (1L << 18) +#define HA_CREATE_USED_KEY_BLOCK_SIZE (1L << 19) typedef ulonglong my_xid; // this line is the same as in log_event.h #define MYSQL_XID_PREFIX "MySQLXid" @@ -654,6 +656,7 @@ typedef struct st_ha_create_information ulong table_options; ulong avg_row_length; ulong used_fields; + ulong key_block_size; SQL_LIST merge_list; handlerton *db_type; enum row_type row_type; @@ -667,6 +670,15 @@ typedef struct st_ha_create_information bool store_on_disk; /* 1 if table stored on disk */ } HA_CREATE_INFO; + +typedef struct st_key_create_information +{ + enum ha_key_alg algorithm; + ulong block_size; + LEX_STRING parser_name; +} KEY_CREATE_INFO; + + /* Class for maintaining hooks used inside operations on tables such as: create table functions, delete table functions, and alter table @@ -701,6 +713,7 @@ private: typedef struct st_savepoint SAVEPOINT; extern ulong savepoint_alloc_size; +extern KEY_CREATE_INFO default_key_create_info; /* Forward declaration for condition pushdown to storage engine */ typedef class Item COND; diff --git a/sql/item_func.h b/sql/item_func.h index ed5924e8fe1..a91d93be8c6 100644 --- a/sql/item_func.h +++ b/sql/item_func.h @@ -284,6 +284,7 @@ class Item_func_connection_id :public Item_int_func longlong value; public: + Item_func_connection_id() {} const char *func_name() const { return "connection_id"; } void fix_length_and_dec(); bool fix_fields(THD *thd, Item **ref); diff --git a/sql/lex.h b/sql/lex.h index 171f7a48980..555a68dc388 100644 --- a/sql/lex.h +++ b/sql/lex.h @@ -275,6 +275,7 @@ static SYMBOL symbols[] = { { "JOIN", SYM(JOIN_SYM)}, { "KEY", SYM(KEY_SYM)}, { "KEYS", SYM(KEYS)}, + { "KEY_BLOCK_SIZE", SYM(KEY_BLOCK_SIZE)}, { "KILL", SYM(KILL_SYM)}, { "LANGUAGE", SYM(LANGUAGE_SYM)}, { "LAST", SYM(LAST_SYM)}, diff --git a/sql/log.cc b/sql/log.cc index e9a5011db4d..7c8f314bc08 100644 --- a/sql/log.cc +++ b/sql/log.cc @@ -1090,7 +1090,7 @@ binlog_end_trans(THD *thd, binlog_trx_data *trx_data, Log_event *end_ev) were, we would have to ensure that we're not ending a statement inside a stored function. */ - thd->binlog_flush_pending_rows_event(true); + thd->binlog_flush_pending_rows_event(TRUE); error= mysql_bin_log.write(thd, trans_log, end_ev); } else @@ -1486,6 +1486,7 @@ const char *MYSQL_LOG::generate_name(const char *log_name, return log_name; } + bool MYSQL_LOG::open_index_file(const char *index_file_name_arg, const char *log_name) { @@ -2878,23 +2879,27 @@ bool MYSQL_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() && !my_b_tell(trans_log)) + if (event_info->get_cache_stmt() && !trans_log_in_use) trans_register_ha(thd, - thd->options & (OPTION_NOT_AUTOCOMMIT | OPTION_BEGIN), + (thd->options & + (OPTION_NOT_AUTOCOMMIT | OPTION_BEGIN)), &binlog_hton); - - if (event_info->get_cache_stmt() || my_b_tell(trans_log)) + if (event_info->get_cache_stmt() || trans_log_in_use) + { + DBUG_PRINT("info", ("Using trans_log")); file= trans_log; + } /* - Note: as Mats suggested, for all the cases above where we write to + TODO as Mats suggested, for all the cases above where we write to trans_log, it sounds unnecessary to lock LOCK_log. We should rather test first if we want to write to trans_log, and if not, lock - LOCK_log. TODO. + LOCK_log. */ } #endif - DBUG_PRINT("info",("event type=%d",event_info->get_type_code())); + DBUG_PRINT("info",("event type: %d",event_info->get_type_code())); /* No check for auto events flag here - this write method should diff --git a/sql/mysql_priv.h b/sql/mysql_priv.h index 749a968a5af..93db68d1b50 100644 --- a/sql/mysql_priv.h +++ b/sql/mysql_priv.h @@ -92,7 +92,7 @@ char* query_table_status(THD *thd,const char *db,const char *table_name); do { \ DBUG_ASSERT(strncmp(Ver, MYSQL_SERVER_VERSION, sizeof(Ver)-1) >= 0); \ push_warning_printf(((THD *)Thd), MYSQL_ERROR::WARN_LEVEL_WARN, \ - ER_WARN_DEPRECATED, ER(ER_WARN_DEPRECATED), \ + ER_WARN_DEPRECATED_SYNTAX, ER(ER_WARN_DEPRECATED_SYNTAX), \ (Old), (Ver), (New)); \ } while(0) @@ -558,6 +558,7 @@ enum enum_mysql_completiontype { }; bool begin_trans(THD *thd); +bool end_active_trans(THD *thd); int end_trans(THD *thd, enum enum_mysql_completiontype completion); Item *negate_expression(THD *thd, Item *expr); @@ -1365,8 +1366,8 @@ bool mysql_manager_submit(void (*action)()); void print_where(COND *cond,const char *info); void print_cached_tables(void); void TEST_filesort(SORT_FIELD *sortorder,uint s_length); -void print_plan(JOIN* join, double read_time, double record_count, - uint idx, const char *info); +void print_plan(JOIN* join,uint idx, double record_count, double read_time, + double current_read_time, const char *info); #endif void mysql_print_status(); /* key.cc */ diff --git a/sql/mysqld.cc b/sql/mysqld.cc index 00299607e7d..0bae436cf78 100644 --- a/sql/mysqld.cc +++ b/sql/mysqld.cc @@ -742,6 +742,7 @@ static void clean_up_mutexes(void); static void wait_for_signal_thread_to_end(void); static int test_if_case_insensitive(const char *dir_name); static void create_pid_file(); +static void end_ssl(); #ifndef EMBEDDED_LIBRARY /**************************************************************************** @@ -1184,8 +1185,8 @@ void clean_up(bool print_message) #ifdef HAVE_DLOPEN udf_free(); #endif - plugin_free(); } + plugin_free(); if (tc_log) tc_log->close(); xid_cache_free(); @@ -1217,10 +1218,7 @@ void clean_up(bool print_message) #endif delete binlog_filter; delete rpl_filter; -#ifdef HAVE_OPENSSL - if (ssl_acceptor_fd) - my_free((gptr) ssl_acceptor_fd, MYF(MY_ALLOW_ZERO_PTR)); -#endif /* HAVE_OPENSSL */ + end_ssl(); #ifdef USE_REGEX my_regex_end(); #endif @@ -2962,6 +2960,18 @@ static void init_ssl() } +static void end_ssl() +{ +#ifdef HAVE_OPENSSL + if (ssl_acceptor_fd) + { + free_vio_ssl_acceptor_fd(ssl_acceptor_fd); + ssl_acceptor_fd= 0; + } +#endif /* HAVE_OPENSSL */ +} + + static int init_server_components() { DBUG_ENTER("init_server_components"); diff --git a/sql/share/errmsg.txt b/sql/share/errmsg.txt index 01e66b35c0f..a2bc77714bb 100644 --- a/sql/share/errmsg.txt +++ b/sql/share/errmsg.txt @@ -2978,52 +2978,52 @@ ER_UDF_EXISTS swe "Funktionen '%-.64s' finns redan" ukr "æÕÎËÃ¦Ñ '%-.64s' ×ÖÅ ¦ÓÎÕ¤" ER_CANT_OPEN_LIBRARY - cze "Nemohu otev-Bøít sdílenou knihovnu '%-.64s' (errno: %d %s)" - dan "Kan ikke åbne delt bibliotek '%-.64s' (errno: %d %s)" - nla "Kan shared library '%-.64s' niet openen (Errcode: %d %s)" - eng "Can't open shared library '%-.64s' (errno: %d %s)" - jps "shared library '%-.64s' ‚ðŠJ‚Ž–‚ª‚Å‚«‚Ü‚¹‚ñ (errno: %d %s)", - est "Ei suuda avada jagatud teeki '%-.64s' (veakood: %d %s)" - fre "Impossible d'ouvrir la bibliothèque partagée '%-.64s' (errno: %d %s)" - ger "Kann Shared Library '%-.64s' nicht öffnen (Fehler: %d %s)" - greek "Äåí åßíáé äõíáôÞ ç áíÜãíùóç ôçò shared library '%-.64s' (êùäéêüò ëÜèïõò: %d %s)" - hun "A(z) '%-.64s' megosztott konyvtar nem hasznalhato (hibakod: %d %s)" - ita "Impossibile aprire la libreria condivisa '%-.64s' (errno: %d %s)" - jpn "shared library '%-.64s' ¤ò³«¤¯»ö¤¬¤Ç¤¤Þ¤»¤ó (errno: %d %s)" - kor "'%-.64s' °øÀ¯ ¶óÀ̹ö·¯¸®¸¦ ¿¼ö ¾ø½À´Ï´Ù.(¿¡·¯¹øÈ£: %d %s)" - nor "Can't open shared library '%-.64s' (errno: %d %s)" - norwegian-ny "Can't open shared library '%-.64s' (errno: %d %s)" - pol "Can't open shared library '%-.64s' (errno: %d %s)" - por "Não pode abrir biblioteca compartilhada '%-.64s' (erro no. '%d' - '%-.64s')" - rum "Nu pot deschide libraria shared '%-.64s' (Eroare: %d %s)" - rus "îÅ×ÏÚÍÏÖÎÏ ÏÔËÒÙÔØ ÄÉÎÁÍÉÞÅÓËÕÀ ÂÉÂÌÉÏÔÅËÕ '%-.64s' (ÏÛÉÂËÁ: %d %s)" - serbian "Ne mogu da otvorim share-ovanu biblioteku '%-.64s' (errno: %d %s)" - slo "Nemô¾em otvori» zdieµanú kni¾nicu '%-.64s' (chybový kód: %d %s)" - spa "No puedo abrir libraria conjugada '%-.64s' (errno: %d %s)" - swe "Kan inte öppna det dynamiska biblioteket '%-.64s' (Felkod: %d %s)" - ukr "îÅ ÍÏÖÕ ×¦ÄËÒÉÔÉ ÒÏÚĦÌÀ×ÁÎÕ Â¦Â̦ÏÔÅËÕ '%-.64s' (ÐÏÍÉÌËÁ: %d %s)" -ER_CANT_FIND_DL_ENTRY - cze "Nemohu naj-Bít funkci '%-.64s' v knihovnì" - dan "Kan ikke finde funktionen '%-.64s' i bibliotek" - nla "Kan functie '%-.64s' niet in library vinden" - eng "Can't find symbol '%-.64s' in library" - jps "function '%-.64s' ‚ðƒ‰ƒCƒuƒ‰ƒŠ[’†‚ÉŒ©•t‚¯‚鎖‚ª‚Å‚«‚Ü‚¹‚ñ", - est "Ei leia funktsiooni '%-.64s' antud teegis" - fre "Impossible de trouver la fonction '%-.64s' dans la bibliothèque" - ger "Kann Funktion '%-.64s' in der Library nicht finden" - greek "Äåí åßíáé äõíáôÞ ç áíåýñåóç ôçò óõíÜñôçóçò '%-.64s' óôçí âéâëéïèÞêç" - hun "A(z) '%-.64s' fuggveny nem talalhato a konyvtarban" - ita "Impossibile trovare la funzione '%-.64s' nella libreria" - jpn "function '%-.64s' ¤ò¥é¥¤¥Ö¥é¥ê¡¼Ãæ¤Ë¸«ÉÕ¤±¤ë»ö¤¬¤Ç¤¤Þ¤»¤ó" - kor "¶óÀ̹ö·¯¸®¿¡¼ '%-.64s' ÇÔ¼ö¸¦ ãÀ» ¼ö ¾ø½À´Ï´Ù." - por "Não pode encontrar a função '%-.64s' na biblioteca" - rum "Nu pot gasi functia '%-.64s' in libraria" - rus "îÅ×ÏÚÍÏÖÎÏ ÏÔÙÓËÁÔØ ÓÉÍ×ÏÌ '%-.64s' × ÂÉÂÌÉÏÔÅËÅ" - serbian "Ne mogu da pronadjem funkciju '%-.64s' u biblioteci" - slo "Nemô¾em nájs» funkciu '%-.64s' v kni¾nici" - spa "No puedo encontrar función '%-.64s' en libraria" - swe "Hittar inte funktionen '%-.64s' in det dynamiska biblioteket" - ukr "îÅ ÍÏÖÕ ÚÎÁÊÔÉ ÆÕÎËæÀ '%-.64s' Õ Â¦Â̦ÏÔÅæ" + cze "Nemohu otev-Bøít sdílenou knihovnu '%-.64s' (errno: %d %-.128s)" + dan "Kan ikke åbne delt bibliotek '%-.64s' (errno: %d %-.128s)" + nla "Kan shared library '%-.64s' niet openen (Errcode: %d %-.128s)" + eng "Can't open shared library '%-.64s' (errno: %d %-.128s)" + jps "shared library '%-.64s' ‚ðŠJ‚Ž–‚ª‚Å‚«‚Ü‚¹‚ñ (errno: %d %-.128s)", + est "Ei suuda avada jagatud teeki '%-.64s' (veakood: %d %-.128s)" + fre "Impossible d'ouvrir la bibliothèque partagée '%-.64s' (errno: %d %-.128s)" + ger "Kann Shared Library '%-.64s' nicht öffnen (Fehler: %d %-.128s)" + greek "Äåí åßíáé äõíáôÞ ç áíÜãíùóç ôçò shared library '%-.64s' (êùäéêüò ëÜèïõò: %d %-.128s)" + hun "A(z) '%-.64s' megosztott konyvtar nem hasznalhato (hibakod: %d %-.128s)" + ita "Impossibile aprire la libreria condivisa '%-.64s' (errno: %d %-.128s)" + jpn "shared library '%-.64s' ¤ò³«¤¯»ö¤¬¤Ç¤¤Þ¤»¤ó (errno: %d %-.128s)" + kor "'%-.64s' °øÀ¯ ¶óÀ̹ö·¯¸®¸¦ ¿¼ö ¾ø½À´Ï´Ù.(¿¡·¯¹øÈ£: %d %-.128s)" + nor "Can't open shared library '%-.64s' (errno: %d %-.128s)" + norwegian-ny "Can't open shared library '%-.64s' (errno: %d %-.128s)" + pol "Can't open shared library '%-.64s' (errno: %d %-.128s)" + por "Não pode abrir biblioteca compartilhada '%-.64s' (erro no. %d '%-.128s')" + rum "Nu pot deschide libraria shared '%-.64s' (Eroare: %d %-.128s)" + rus "îÅ×ÏÚÍÏÖÎÏ ÏÔËÒÙÔØ ÄÉÎÁÍÉÞÅÓËÕÀ ÂÉÂÌÉÏÔÅËÕ '%-.64s' (ÏÛÉÂËÁ: %d %-.128s)" + serbian "Ne mogu da otvorim share-ovanu biblioteku '%-.64s' (errno: %d %-.128s)" + slo "Nemô¾em otvori» zdieµanú kni¾nicu '%-.64s' (chybový kód: %d %-.128s)" + spa "No puedo abrir libraria conjugada '%-.64s' (errno: %d %-.128s)" + swe "Kan inte öppna det dynamiska biblioteket '%-.64s' (Felkod: %d %-.128s)" + ukr "îÅ ÍÏÖÕ ×¦ÄËÒÉÔÉ ÒÏÚĦÌÀ×ÁÎÕ Â¦Â̦ÏÔÅËÕ '%-.64s' (ÐÏÍÉÌËÁ: %d %-.128s)" +ER_CANT_FIND_DL_ENTRY + cze "Nemohu naj-Bít funkci '%-.128s' v knihovnì" + dan "Kan ikke finde funktionen '%-.128s' i bibliotek" + nla "Kan functie '%-.128s' niet in library vinden" + eng "Can't find symbol '%-.128s' in library" + jps "function '%-.128s' ‚ðƒ‰ƒCƒuƒ‰ƒŠ[’†‚ÉŒ©•t‚¯‚鎖‚ª‚Å‚«‚Ü‚¹‚ñ", + est "Ei leia funktsiooni '%-.128s' antud teegis" + fre "Impossible de trouver la fonction '%-.128s' dans la bibliothèque" + ger "Kann Funktion '%-.128s' in der Library nicht finden" + greek "Äåí åßíáé äõíáôÞ ç áíåýñåóç ôçò óõíÜñôçóçò '%-.128s' óôçí âéâëéïèÞêç" + hun "A(z) '%-.128s' fuggveny nem talalhato a konyvtarban" + ita "Impossibile trovare la funzione '%-.128s' nella libreria" + jpn "function '%-.128s' ¤ò¥é¥¤¥Ö¥é¥ê¡¼Ãæ¤Ë¸«ÉÕ¤±¤ë»ö¤¬¤Ç¤¤Þ¤»¤ó" + kor "¶óÀ̹ö·¯¸®¿¡¼ '%-.128s' ÇÔ¼ö¸¦ ãÀ» ¼ö ¾ø½À´Ï´Ù." + por "Não pode encontrar a função '%-.128s' na biblioteca" + rum "Nu pot gasi functia '%-.128s' in libraria" + rus "îÅ×ÏÚÍÏÖÎÏ ÏÔÙÓËÁÔØ ÓÉÍ×ÏÌ '%-.128s' × ÂÉÂÌÉÏÔÅËÅ" + serbian "Ne mogu da pronadjem funkciju '%-.128s' u biblioteci" + slo "Nemô¾em nájs» funkciu '%-.128s' v kni¾nici" + spa "No puedo encontrar función '%-.128s' en libraria" + swe "Hittar inte funktionen '%-.128s' in det dynamiska biblioteket" + ukr "îÅ ÍÏÖÕ ÚÎÁÊÔÉ ÆÕÎËæÀ '%-.128s' Õ Â¦Â̦ÏÔÅæ" ER_FUNCTION_NOT_DEFINED cze "Funkce '%-.64s' nen-Bí definována" dan "Funktionen '%-.64s' er ikke defineret" @@ -5602,6 +5602,22 @@ ER_SP_RECURSION_LIMIT ger "Rekursionsgrenze %d (durch Variable max_sp_recursion_depth gegeben) wurde für Routine %.64s überschritten" ER_SP_PROC_TABLE_CORRUPT eng "Failed to load routine %-.64s. The table mysql.proc is missing, corrupt, or contains bad data (internal code %d)" +ER_SP_WRONG_NAME 42000 + eng "Incorrect routine name '%-.64s'" +ER_TABLE_NEEDS_UPGRADE + eng "Table upgrade required. Please do \"REPAIR TABLE `%-.32s`\" to fix it!" +ER_SP_NO_AGGREGATE 42000 + eng "AGGREGATE is not supported for stored functions" +ER_MAX_PREPARED_STMT_COUNT_REACHED 42000 + eng "Can't create more than max_prepared_stmt_count statements (current value: %lu)" +ER_VIEW_RECURSIVE + eng "`%-.64s`.`%-.64s` contains view recursion" +ER_NON_GROUPING_FIELD_USED 42000 + eng "non-grouping field '%-.64s' is used in %-.64s clause" +ER_TABLE_CANT_HANDLE_SPKEYS + eng "The used table type doesn't support SPATIAL indexes" +ER_ILLEGAL_HA_CREATE_OPTION + eng "Table storage engine '%-.64s' does not support the create option '%.64s'" ER_PARTITION_REQUIRES_VALUES_ERROR eng "%-.64s PARTITIONING requires definition of VALUES %-.64s for each partition" swe "%-.64s PARTITIONering kräver definition av VALUES %-.64s för varje partition" @@ -5798,32 +5814,16 @@ ER_EVENT_DATA_TOO_LONG ER_DROP_INDEX_FK eng "Cannot drop index '%-.64s': needed in a foreign key constraint" ger "Kann Index '%-.64s' nicht löschen: wird für einen Fremdschlüssel benötigt" +ER_WARN_DEPRECATED_SYNTAX + eng "The syntax '%s' is deprecated and will be removed in MySQL %s. Please use %s instead." ER_CANT_WRITE_LOCK_LOG_TABLE eng "You can't write-lock a log table. Only read access is possible." ER_CANT_READ_LOCK_LOG_TABLE eng "You can't use usual read lock with log tables. Try READ LOCAL instead." -ER_SP_WRONG_NAME 42000 - eng "Incorrect routine name '%-.64s'" ER_FOREIGN_DUPLICATE_KEY 23000 S1009 eng "Upholding foreign key constraints for table '%.64s', entry '%-.64s', key %d would lead to a duplicate entry" ER_COL_COUNT_DOESNT_MATCH_PLEASE_UPDATE eng "Column count of mysql.%s is wrong. Expected %d, found %d. Created with MySQL %d, now running %d. Please use scripts/mysql_fix_privilege_tables" -ER_TABLE_NEEDS_UPGRADE - eng "Table upgrade required. Please do \"REPAIR TABLE `%-.32s`\" to fix it!" -ER_ILLEGAL_HA_CREATE_OPTION - eng "Table storage engine '%-.64s' does not support the create option '%.64s'" -ER_CANT_CHANGE_TX_ISOLATION 25001 - eng "Transaction isolation level can't be changed while a transaction is in progress" -ER_WARN_DEPRECATED - eng "The syntax '%s' is deprecated and will be removed in MySQL %s. Please use %s instead." -ER_SP_NO_AGGREGATE 42000 - eng "AGGREGATE is not supported for stored functions" -ER_MAX_PREPARED_STMT_COUNT_REACHED 42000 - eng "Can't create more than max_prepared_stmt_count statements (current value: %lu)" -ER_VIEW_RECURSIVE - eng "`%-.64s`.`%-.64s` contains view recursion" -ER_NON_GROUPING_FIELD_USED 42000 - eng "non-grouping field '%-.64s' is used in %-.64s clause" ER_TEMP_TABLE_PREVENTS_SWITCH_OUT_OF_RBR eng "Cannot switch out of the row-based binary log format when the session has open temporary tables" ER_STORED_FUNCTION_PREVENTS_SWITCH_BINLOG_FORMAT @@ -5840,3 +5840,5 @@ ER_NULL_IN_VALUES_LESS_THAN ER_WRONG_PARTITION_NAME eng "Incorrect partition name" swe "Felaktigt partitionsnamn" +ER_CANT_CHANGE_TX_ISOLATION 25001 + eng "Transaction isolation level can't be changed while a transaction is in progress" diff --git a/sql/sp.cc b/sql/sp.cc index f7a6772146d..6f074fd7dce 100644 --- a/sql/sp.cc +++ b/sql/sp.cc @@ -268,7 +268,6 @@ db_find_routine_aux(THD *thd, int type, sp_name *name, TABLE *table) static int db_find_routine(THD *thd, int type, sp_name *name, sp_head **sphp) { - extern int MYSQLparse(void *thd); TABLE *table; const char *params, *returns, *body; int ret; @@ -477,6 +476,7 @@ db_load_routine(THD *thd, int type, sp_name *name, sp_head **sphp, (*sphp)->optimize(); } end: + lex_end(thd->lex); thd->spcont= old_spcont; thd->variables.sql_mode= old_sql_mode; thd->variables.select_limit= old_select_limit; diff --git a/sql/sp_head.cc b/sql/sp_head.cc index fbdb9a72640..8a64799e5f9 100644 --- a/sql/sp_head.cc +++ b/sql/sp_head.cc @@ -680,6 +680,7 @@ sp_head::destroy() DBUG_ASSERT(m_lex.is_empty() || m_thd); while ((lex= (LEX *)m_lex.pop())) { + lex_end(m_thd->lex); delete m_thd->lex; m_thd->lex= lex; } @@ -1682,7 +1683,10 @@ sp_head::restore_lex(THD *thd) */ merge_table_list(thd, sublex->query_tables, sublex); if (! sublex->sp_lex_in_use) + { + lex_end(sublex); delete sublex; + } thd->lex= oldlex; DBUG_VOID_RETURN; } diff --git a/sql/sp_head.h b/sql/sp_head.h index 6b32ea13e5d..fbc277b4de8 100644 --- a/sql/sp_head.h +++ b/sql/sp_head.h @@ -521,7 +521,10 @@ public: virtual ~sp_lex_keeper() { if (m_lex_resp) + { + lex_end(m_lex); delete m_lex; + } } /* diff --git a/sql/sql_base.cc b/sql/sql_base.cc index 010245cc077..77d2b165881 100644 --- a/sql/sql_base.cc +++ b/sql/sql_base.cc @@ -288,13 +288,13 @@ TABLE_SHARE *get_table_share(THD *thd, TABLE_LIST *table_list, char *key, if (!(share= alloc_table_share(table_list, key, key_length))) { -#ifdef NOT_YET +#ifdef WAITING_FOR_TABLE_DEF_CACHE_STAGE_3 pthread_mutex_unlock(&LOCK_open); #endif DBUG_RETURN(0); } -#ifdef NOT_YET +#ifdef WAITING_FOR_TABLE_DEF_CACHE_STAGE_3 // We need a write lock to be able to add a new entry pthread_mutex_unlock(&LOCK_open); pthread_mutex_lock(&LOCK_open); @@ -331,19 +331,19 @@ TABLE_SHARE *get_table_share(THD *thd, TABLE_LIST *table_list, char *key, if (my_hash_insert(&table_def_cache, (byte*) share)) { -#ifdef NOT_YET +#ifdef WAITING_FOR_TABLE_DEF_CACHE_STAGE_3 pthread_mutex_unlock(&LOCK_open); (void) pthread_mutex_unlock(&share->mutex); #endif free_table_share(share); DBUG_RETURN(0); // return error } -#ifdef NOT_YET +#ifdef WAITING_FOR_TABLE_DEF_CACHE_STAGE_3 pthread_mutex_unlock(&LOCK_open); #endif if (open_table_def(thd, share, db_flags)) { -#ifdef NOT_YET +#ifdef WAITING_FOR_TABLE_DEF_CACHE_STAGE_3 /* No such table or wrong table definition file Lock first the table cache and then the mutex. @@ -372,7 +372,7 @@ found: /* We must do a lock to ensure that the structure is initialized */ (void) pthread_mutex_lock(&share->mutex); -#ifdef NOT_YET +#ifdef WAITING_FOR_TABLE_DEF_CACHE_STAGE_3 pthread_mutex_unlock(&LOCK_open); #endif if (share->error) @@ -540,7 +540,7 @@ void release_table_share(TABLE_SHARE *share, enum release_type type) DBUG_VOID_RETURN; -#ifdef NOT_YET +#ifdef WAITING_FOR_TABLE_DEF_CACHE_STAGE_3 if (to_be_deleted) { /* @@ -1069,7 +1069,7 @@ void close_thread_tables(THD *thd, bool lock_in_use, bool skip_derived) handled either before writing a query log event (inside binlog_query()) or when preparing a pending event. */ - thd->binlog_flush_pending_rows_event(true); + thd->binlog_flush_pending_rows_event(TRUE); mysql_unlock_tables(thd, thd->lock); thd->lock=0; } diff --git a/sql/sql_class.cc b/sql/sql_class.cc index 0173b15ea68..6166771e5d1 100644 --- a/sql/sql_class.cc +++ b/sql/sql_class.cc @@ -2688,8 +2688,7 @@ int THD::binlog_query(THD::enum_binlog_query_type qtype, DBUG_ENTER("THD::binlog_query"); DBUG_ASSERT(query && mysql_bin_log.is_open()); - switch (qtype) - { + switch (qtype) { case THD::MYSQL_QUERY_TYPE: /* Using this query type is a conveniece hack, since we have been diff --git a/sql/sql_class.h b/sql/sql_class.h index fdb70b6c991..54f256997d0 100644 --- a/sql/sql_class.h +++ b/sql/sql_class.h @@ -112,17 +112,16 @@ class Key :public Sql_alloc { public: enum Keytype { PRIMARY, UNIQUE, MULTIPLE, FULLTEXT, SPATIAL, FOREIGN_KEY}; enum Keytype type; - enum ha_key_alg algorithm; + KEY_CREATE_INFO key_create_info; List<key_part_spec> columns; const char *name; bool generated; - LEX_STRING *parser_name; - Key(enum Keytype type_par, const char *name_arg, enum ha_key_alg alg_par, - bool generated_arg, List<key_part_spec> &cols, - LEX_STRING *parser_arg= 0) - :type(type_par), algorithm(alg_par), columns(cols), name(name_arg), - generated(generated_arg), parser_name(parser_arg) + Key(enum Keytype type_par, const char *name_arg, + KEY_CREATE_INFO *key_info_arg, + bool generated_arg, List<key_part_spec> &cols) + :type(type_par), key_create_info(*key_info_arg), columns(cols), + name(name_arg), generated(generated_arg) {} ~Key() {} /* Equality comparison of keys (ignoring name) */ @@ -144,7 +143,7 @@ public: foreign_key(const char *name_arg, List<key_part_spec> &cols, Table_ident *table, List<key_part_spec> &ref_cols, uint delete_opt_arg, uint update_opt_arg, uint match_opt_arg) - :Key(FOREIGN_KEY, name_arg, HA_KEY_ALG_UNDEF, 0, cols), + :Key(FOREIGN_KEY, name_arg, &default_key_create_info, 0, cols), ref_table(table), ref_columns(cols), delete_opt(delete_opt_arg), update_opt(update_opt_arg), match_opt(match_opt_arg) diff --git a/sql/sql_lex.cc b/sql/sql_lex.cc index 5a76066af8c..562224201e7 100644 --- a/sql/sql_lex.cc +++ b/sql/sql_lex.cc @@ -168,8 +168,6 @@ void lex_start(THD *thd, const uchar *buf, uint length) lex->select_lex.ftfunc_list= &lex->select_lex.ftfunc_list_alloc; lex->select_lex.group_list.empty(); lex->select_lex.order_list.empty(); - lex->current_select= &lex->select_lex; - lex->yacc_yyss=lex->yacc_yyvs=0; lex->ignore_space=test(thd->variables.sql_mode & MODE_IGNORE_SPACE); lex->sql_command= lex->orig_sql_command= SQLCOM_END; lex->duplicates= DUP_ERROR; @@ -197,8 +195,16 @@ void lex_start(THD *thd, const uchar *buf, uint length) void lex_end(LEX *lex) { - x_free(lex->yacc_yyss); - x_free(lex->yacc_yyvs); + DBUG_ENTER("lex_end"); + DBUG_PRINT("enter", ("lex: 0x%lx", (long) lex)); + if (lex->yacc_yyss) + { + my_free(lex->yacc_yyss, MYF(0)); + my_free(lex->yacc_yyvs, MYF(0)); + lex->yacc_yyss= 0; + lex->yacc_yyvs= 0; + } + DBUG_VOID_RETURN; } @@ -1633,7 +1639,8 @@ void st_select_lex::print_limit(THD *thd, String *str) */ st_lex::st_lex() - :result(0), sql_command(SQLCOM_END), query_tables_own_last(0) + :result(0), yacc_yyss(0), yacc_yyvs(0), + sql_command(SQLCOM_END), query_tables_own_last(0) { hash_init(&sroutines, system_charset_info, 0, 0, 0, sp_sroutine_key, 0, 0); sroutines_list.empty(); diff --git a/sql/sql_lex.h b/sql/sql_lex.h index 47fbc685bab..f0bd85367d0 100644 --- a/sql/sql_lex.h +++ b/sql/sql_lex.h @@ -840,6 +840,7 @@ typedef struct st_lex udf_func udf; HA_CHECK_OPT check_opt; // check/repair options HA_CREATE_INFO create_info; + KEY_CREATE_INFO key_create_info; LEX_MASTER_INFO mi; // used by CHANGE MASTER USER_RESOURCES mqh; ulong type; diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc index b1b498b356d..8ee78578631 100644 --- a/sql/sql_parse.cc +++ b/sql/sql_parse.cc @@ -137,7 +137,7 @@ static void unlock_locked_tables(THD *thd) } -static bool end_active_trans(THD *thd) +bool end_active_trans(THD *thd) { int error=0; DBUG_ENTER("end_active_trans"); @@ -2961,8 +2961,7 @@ end_with_restore_list: thd->enable_slow_log= opt_log_slow_admin_statements; if (end_active_trans(thd)) goto error; - else - res = mysql_create_index(thd, first_table, lex->key_list); + res= mysql_create_index(thd, first_table, lex->key_list); break; #ifdef HAVE_REPLICATION @@ -3069,18 +3068,16 @@ end_with_restore_list: /* ALTER TABLE ends previous transaction */ if (end_active_trans(thd)) goto error; - else - { - thd->enable_slow_log= opt_log_slow_admin_statements; - res= mysql_alter_table(thd, select_lex->db, lex->name, - &lex->create_info, - first_table, lex->create_list, - lex->key_list, - select_lex->order_list.elements, - (ORDER *) select_lex->order_list.first, - lex->duplicates, lex->ignore, &lex->alter_info, - 1); - } + + thd->enable_slow_log= opt_log_slow_admin_statements; + res= mysql_alter_table(thd, select_lex->db, lex->name, + &lex->create_info, + first_table, lex->create_list, + lex->key_list, + select_lex->order_list.elements, + (ORDER *) select_lex->order_list.first, + lex->duplicates, lex->ignore, &lex->alter_info, + 1); break; } #endif /*DONT_ALLOW_SHOW_COMMANDS*/ @@ -3207,7 +3204,7 @@ end_with_restore_list: check_table_access(thd, SELECT_ACL | INSERT_ACL, all_tables, 0)) goto error; /* purecov: inspected */ thd->enable_slow_log= opt_log_slow_admin_statements; - res = mysql_analyze_table(thd, first_table, &lex->check_opt); + res= mysql_analyze_table(thd, first_table, &lex->check_opt); /* ! we write after unlocking the table */ if (!res && !lex->no_write_to_binlog) { @@ -3512,8 +3509,7 @@ end_with_restore_list: goto error; /* purecov: inspected */ if (end_active_trans(thd)) goto error; - else - res = mysql_drop_index(thd, first_table, &lex->alter_info); + res= mysql_drop_index(thd, first_table, &lex->alter_info); break; case SQLCOM_SHOW_PROCESSLIST: if (!thd->security_ctx->priv_user[0] && @@ -5973,14 +5969,16 @@ bool add_field_to_list(THD *thd, char *field_name, enum_field_types type, if (type_modifier & PRI_KEY_FLAG) { lex->col_list.push_back(new key_part_spec(field_name,0)); - lex->key_list.push_back(new Key(Key::PRIMARY, NullS, HA_KEY_ALG_UNDEF, + lex->key_list.push_back(new Key(Key::PRIMARY, NullS, + &default_key_create_info, 0, lex->col_list)); lex->col_list.empty(); } if (type_modifier & (UNIQUE_FLAG | UNIQUE_KEY_FLAG)) { lex->col_list.push_back(new key_part_spec(field_name,0)); - lex->key_list.push_back(new Key(Key::UNIQUE, NullS, HA_KEY_ALG_UNDEF, 0, + lex->key_list.push_back(new Key(Key::UNIQUE, NullS, + &default_key_create_info, 0, lex->col_list)); lex->col_list.empty(); } diff --git a/sql/sql_partition.cc b/sql/sql_partition.cc index 0442ad724d2..71b8e9b1d95 100644 --- a/sql/sql_partition.cc +++ b/sql/sql_partition.cc @@ -3430,6 +3430,7 @@ bool mysql_unpack_partition(THD *thd, const uchar *part_buf, result= FALSE; end: + lex_end(thd->lex); thd->free_list= thd_free_list; thd->lex= old_lex; thd->variables.character_set_client= old_character_set_client; diff --git a/sql/sql_select.cc b/sql/sql_select.cc index 79b1c3836dc..5f8c4dd2e1a 100644 --- a/sql/sql_select.cc +++ b/sql/sql_select.cc @@ -3360,33 +3360,46 @@ best_access_path(JOIN *join, for (keyuse=s->keyuse ; keyuse->table == table ;) { key_part_map found_part= 0; - table_map found_ref= 0; - uint found_ref_or_null= 0; - uint key= keyuse->key; + table_map found_ref= 0; + uint key= keyuse->key; KEY *keyinfo= table->key_info+key; bool ft_key= (keyuse->keypart == FT_KEYPART); + uint found_ref_or_null= 0; /* Calculate how many key segments of the current key we can use */ start_key= keyuse; do { /* for each keypart */ uint keypart= keyuse->keypart; - uint found_part_ref_or_null= KEY_OPTIMIZE_REF_OR_NULL; + table_map best_part_found_ref= 0; + double best_prev_record_reads= DBL_MAX; do { if (!(remaining_tables & keyuse->used_tables) && !(found_ref_or_null & keyuse->optimize)) { found_part|= keyuse->keypart_map; - found_ref|= keyuse->used_tables; + double tmp= prev_record_reads(join, + (found_ref | + keyuse->used_tables)); + if (tmp < best_prev_record_reads) + { + best_part_found_ref= keyuse->used_tables; + best_prev_record_reads= tmp; + } if (rec > keyuse->ref_table_rows) rec= keyuse->ref_table_rows; - found_part_ref_or_null&= keyuse->optimize; + /* + If there is one 'key_column IS NULL' expression, we can + use this ref_or_null optimisation of this field + */ + found_ref_or_null|= (keyuse->optimize & + KEY_OPTIMIZE_REF_OR_NULL); } keyuse++; - found_ref_or_null|= found_part_ref_or_null; } while (keyuse->table == table && keyuse->key == key && keyuse->keypart == keypart); + found_ref|= best_part_found_ref; } while (keyuse->table == table && keyuse->key == key); /* @@ -3451,17 +3464,17 @@ best_access_path(JOIN *join, } } /* Limit the number of matched rows */ - tmp = records; + tmp= records; set_if_smaller(tmp, (double) thd->variables.max_seeks_for_key); if (table->used_keys.is_set(key)) { /* we can use only index tree */ uint keys_per_block= table->file->block_size/2/ (keyinfo->key_length+table->file->ref_length)+1; - tmp = record_count*(tmp+keys_per_block-1)/keys_per_block; + tmp= record_count*(tmp+keys_per_block-1)/keys_per_block; } else - tmp = record_count*min(tmp,s->worst_seeks); + tmp= record_count*min(tmp,s->worst_seeks); } } else @@ -3475,7 +3488,7 @@ best_access_path(JOIN *join, (!(table->file->index_flags(key, 0, 0) & HA_ONLY_WHOLE_INDEX) || found_part == PREV_BITS(uint,keyinfo->key_parts))) { - max_key_part=max_part_bit(found_part); + max_key_part= max_part_bit(found_part); /* Check if quick_range could determinate how many rows we will match @@ -3486,8 +3499,8 @@ best_access_path(JOIN *join, else { /* Check if we have statistic about the distribution */ - if ((records = keyinfo->rec_per_key[max_key_part-1])) - tmp = records; + if ((records= keyinfo->rec_per_key[max_key_part-1])) + tmp= records; else { /* @@ -3548,13 +3561,13 @@ best_access_path(JOIN *join, /* we can use only index tree */ uint keys_per_block= table->file->block_size/2/ (keyinfo->key_length+table->file->ref_length)+1; - tmp = record_count*(tmp+keys_per_block-1)/keys_per_block; + tmp= record_count*(tmp+keys_per_block-1)/keys_per_block; } else - tmp = record_count*min(tmp,s->worst_seeks); + tmp= record_count*min(tmp,s->worst_seeks); } else - tmp = best_time; // Do nothing + tmp= best_time; // Do nothing } } /* not ft_key */ if (tmp < best_time - records/(double) TIME_FOR_COMPARE) @@ -3906,7 +3919,8 @@ optimize_straight_join(JOIN *join, table_map join_tables) for (JOIN_TAB **pos= join->best_ref + idx ; (s= *pos) ; pos++) { /* Find the best access method from 's' to the current partial plan */ - best_access_path(join, s, join->thd, join_tables, idx, record_count, read_time); + best_access_path(join, s, join->thd, join_tables, idx, + record_count, read_time); /* compute the cost of the new plan extended with 's' */ record_count*= join->positions[idx].records_read; read_time+= join->positions[idx].read_time; @@ -4029,8 +4043,9 @@ greedy_search(JOIN *join, 'join->best_positions' contains a complete optimal extension of the current partial QEP. */ - DBUG_EXECUTE("opt", print_plan(join, read_time, record_count, - join->tables, "optimal");); + DBUG_EXECUTE("opt", print_plan(join, join->tables, + record_count, read_time, read_time, + "optimal");); DBUG_VOID_RETURN; } @@ -4061,8 +4076,9 @@ greedy_search(JOIN *join, --rem_size; ++idx; - DBUG_EXECUTE("opt", - print_plan(join, read_time, record_count, idx, "extended");); + DBUG_EXECUTE("opt", print_plan(join, join->tables, + record_count, read_time, read_time, + "extended");); } while (TRUE); } @@ -4085,13 +4101,14 @@ greedy_search(JOIN *join, read_time the cost of the best partial plan search_depth maximum depth of the recursion and thus size of the found optimal plan (0 < search_depth <= join->tables+1). - prune_level pruning heuristics that should be applied during optimization + prune_level pruning heuristics that should be applied during + optimization (values: 0 = EXHAUSTIVE, 1 = PRUNE_BY_TIME_OR_ROWS) DESCRIPTION The procedure searches for the optimal ordering of the query tables in set - 'remaining_tables' of size N, and the corresponding optimal access paths to each - table. The choice of a table order and an access path for each table + 'remaining_tables' of size N, and the corresponding optimal access paths to + each table. The choice of a table order and an access path for each table constitutes a query execution plan (QEP) that fully specifies how to execute the query. @@ -4201,8 +4218,8 @@ best_extension_by_limited_search(JOIN *join, double best_record_count= DBL_MAX; double best_read_time= DBL_MAX; - DBUG_EXECUTE("opt", - print_plan(join, read_time, record_count, idx, "part_plan");); + DBUG_EXECUTE("opt", print_plan(join, idx, record_count, read_time, read_time, + "part_plan");); for (JOIN_TAB **pos= join->best_ref + idx ; (s= *pos) ; pos++) { @@ -4214,7 +4231,8 @@ best_extension_by_limited_search(JOIN *join, double current_record_count, current_read_time; /* Find the best access method from 's' to the current partial plan */ - best_access_path(join, s, thd, remaining_tables, idx, record_count, read_time); + best_access_path(join, s, thd, remaining_tables, idx, + record_count, read_time); /* Compute the cost of extending the plan with 's' */ current_record_count= record_count * join->positions[idx].records_read; current_read_time= read_time + join->positions[idx].read_time; @@ -4223,7 +4241,12 @@ best_extension_by_limited_search(JOIN *join, if ((current_read_time + current_record_count / (double) TIME_FOR_COMPARE) >= join->best_read) { - DBUG_EXECUTE("opt", print_plan(join, read_time, record_count, idx, + DBUG_EXECUTE("opt", print_plan(join, idx+1, + current_record_count, + read_time, + (current_read_time + + current_record_count / + (double) TIME_FOR_COMPARE), "prune_by_cost");); restore_prev_nj_state(s); continue; @@ -4252,7 +4275,10 @@ best_extension_by_limited_search(JOIN *join, } else { - DBUG_EXECUTE("opt", print_plan(join, read_time, record_count, idx, + DBUG_EXECUTE("opt", print_plan(join, idx+1, + current_record_count, + read_time, + current_read_time, "pruned_by_heuristic");); restore_prev_nj_state(s); continue; @@ -4280,7 +4306,8 @@ best_extension_by_limited_search(JOIN *join, */ current_read_time+= current_record_count / (double) TIME_FOR_COMPARE; if (join->sort_by_table && - join->sort_by_table != join->positions[join->const_tables].table->table) + join->sort_by_table != + join->positions[join->const_tables].table->table) /* We have to make a temp table */ current_read_time+= current_record_count; if ((search_depth == 1) || (current_read_time < join->best_read)) @@ -4289,8 +4316,10 @@ best_extension_by_limited_search(JOIN *join, sizeof(POSITION) * (idx + 1)); join->best_read= current_read_time - 0.001; } - DBUG_EXECUTE("opt", print_plan(join, current_read_time, - current_record_count, idx, + DBUG_EXECUTE("opt", print_plan(join, idx+1, + current_record_count, + read_time, + current_read_time, "full_plan");); } restore_prev_nj_state(s); @@ -4311,7 +4340,6 @@ find_best(JOIN *join,table_map rest_tables,uint idx,double record_count, ha_rows rec; double tmp; THD *thd= join->thd; - if (!rest_tables) { DBUG_PRINT("best",("read_time: %g record_count: %g",read_time, diff --git a/sql/sql_show.cc b/sql/sql_show.cc index 1c55a7dd26c..4071f86989f 100644 --- a/sql/sql_show.cc +++ b/sql/sql_show.cc @@ -42,6 +42,9 @@ static TYPELIB grant_types = { sizeof(grant_names)/sizeof(char **), grant_names, NULL}; #endif +static void store_key_options(THD *thd, String *packet, TABLE *table, + KEY *key_info); + /*************************************************************************** ** List all table types supported ***************************************************************************/ @@ -929,15 +932,12 @@ store_create_info(THD *thd, TABLE_LIST *table_list, String *packet, handler *file= table->file; TABLE_SHARE *share= table->s; HA_CREATE_INFO create_info; - my_bool foreign_db_mode= (thd->variables.sql_mode & (MODE_POSTGRESQL | - MODE_ORACLE | - MODE_MSSQL | - MODE_DB2 | - MODE_MAXDB | - MODE_ANSI)) != 0; - my_bool limited_mysql_mode= (thd->variables.sql_mode & - (MODE_NO_FIELD_OPTIONS | MODE_MYSQL323 | - MODE_MYSQL40)) != 0; + bool foreign_db_mode= (thd->variables.sql_mode & (MODE_POSTGRESQL | + MODE_ORACLE | + MODE_MSSQL | + MODE_DB2 | + MODE_MAXDB | + MODE_ANSI)) != 0; DBUG_ENTER("store_create_info"); DBUG_PRINT("enter",("table: %s", table->s->table_name.str)); @@ -1100,22 +1100,12 @@ store_create_info(THD *thd, TABLE_LIST *table_list, String *packet, if (!found_primary) append_identifier(thd, packet, key_info->name, strlen(key_info->name)); - if (!(thd->variables.sql_mode & MODE_NO_KEY_OPTIONS) && - !limited_mysql_mode && !foreign_db_mode) - { - if (key_info->algorithm == HA_KEY_ALG_BTREE) - packet->append(STRING_WITH_LEN(" USING BTREE")); - - if (key_info->algorithm == HA_KEY_ALG_HASH) - packet->append(STRING_WITH_LEN(" USING HASH")); - - // +BAR: send USING only in non-default case: non-spatial rtree - if ((key_info->algorithm == HA_KEY_ALG_RTREE) && - !(key_info->flags & HA_SPATIAL)) - packet->append(STRING_WITH_LEN(" USING RTREE")); +#if MYSQL_VERSION_ID < 50300 + /* Key options moved to after key parts in 5.3.0 */ + if (!thd->variables.new_mode) + store_key_options(thd, packet, table, key_info); +#endif - // No need to send USING FULLTEXT, it is sent as FULLTEXT KEY - } packet->append(STRING_WITH_LEN(" (")); for (uint j=0 ; j < key_info->key_parts ; j++,key_part++) @@ -1140,6 +1130,10 @@ store_create_info(THD *thd, TABLE_LIST *table_list, String *packet, } } packet->append(')'); +#if MYSQL_VERSION_ID < 50300 + if (thd->variables.new_mode) +#endif + store_key_options(thd, packet, table, key_info); if (key_info->parser) { packet->append(" WITH PARSER ", 13); @@ -1252,6 +1246,12 @@ store_create_info(THD *thd, TABLE_LIST *table_list, String *packet, packet->append(STRING_WITH_LEN(" ROW_FORMAT=")); packet->append(ha_row_type[(uint) share->row_type]); } + if (table->s->key_block_size) + { + packet->append(STRING_WITH_LEN(" KEY_BLOCK_SIZE=")); + end= longlong10_to_str(table->s->key_block_size, buff, 10); + packet->append(buff, (uint) (end - buff)); + } table->file->append_create_info(packet); if (share->comment && share->comment[0]) { @@ -1286,6 +1286,47 @@ store_create_info(THD *thd, TABLE_LIST *table_list, String *packet, DBUG_RETURN(0); } + +static void store_key_options(THD *thd, String *packet, TABLE *table, + KEY *key_info) +{ + bool limited_mysql_mode= (thd->variables.sql_mode & + (MODE_NO_FIELD_OPTIONS | MODE_MYSQL323 | + MODE_MYSQL40)) != 0; + bool foreign_db_mode= (thd->variables.sql_mode & (MODE_POSTGRESQL | + MODE_ORACLE | + MODE_MSSQL | + MODE_DB2 | + MODE_MAXDB | + MODE_ANSI)) != 0; + char *end, buff[32]; + + if (!(thd->variables.sql_mode & MODE_NO_KEY_OPTIONS) && + !limited_mysql_mode && !foreign_db_mode) + { + + if (key_info->algorithm == HA_KEY_ALG_BTREE) + packet->append(STRING_WITH_LEN(" USING BTREE")); + + if (key_info->algorithm == HA_KEY_ALG_HASH) + packet->append(STRING_WITH_LEN(" USING HASH")); + + /* send USING only in non-default case: non-spatial rtree */ + if ((key_info->algorithm == HA_KEY_ALG_RTREE) && + !(key_info->flags & HA_SPATIAL)) + packet->append(STRING_WITH_LEN(" USING RTREE")); + + if ((key_info->flags & HA_USES_BLOCK_SIZE) && + table->s->key_block_size != key_info->block_size) + { + packet->append(STRING_WITH_LEN(" KEY_BLOCK_SIZE=")); + end= longlong10_to_str(key_info->block_size, buff, 10); + packet->append(buff, (uint) (end - buff)); + } + } +} + + void view_store_options(THD *thd, TABLE_LIST *table, String *buff) { diff --git a/sql/sql_table.cc b/sql/sql_table.cc index 77e6d6dfd21..f890f504952 100644 --- a/sql/sql_table.cc +++ b/sql/sql_table.cc @@ -231,10 +231,9 @@ static int mysql_copy_key_list(List<Key> *orig_key, } } if (!(temp_key= new Key(prep_key->type, prep_key->name, - prep_key->algorithm, + &prep_key->key_create_info, prep_key->generated, - prep_columns, - prep_key->parser_name))) + prep_columns))) { mem_alloc_error(sizeof(Key)); DBUG_RETURN(TRUE); @@ -504,12 +503,14 @@ bool read_ddl_log_entry(uint read_entry, DDL_LOG_ENTRY *ddl_log_entry) Initialise ddl log SYNOPSIS init_ddl_log() - RETURN VALUES - TRUE Error - FALSE Success + DESCRIPTION Write the header of the ddl log file and length of names. Also set number of entries to zero. + + RETURN VALUES + TRUE Error + FALSE Success */ static bool init_ddl_log() @@ -519,9 +520,8 @@ static bool init_ddl_log() DBUG_ENTER("init_ddl_log"); if (global_ddl_log.inited) - { - DBUG_RETURN(FALSE); - } + goto end; + global_ddl_log.io_size= IO_SIZE; create_ddl_log_file_name(file_name); if ((global_ddl_log.file_id= my_create(file_name, @@ -536,9 +536,12 @@ static bool init_ddl_log() global_ddl_log.inited= TRUE; if (write_ddl_log_header()) { + VOID(my_close(global_ddl_log.file_id, MYF(MY_WME))); global_ddl_log.inited= FALSE; DBUG_RETURN(TRUE); } + +end: DBUG_RETURN(FALSE); } @@ -1070,7 +1073,7 @@ void execute_ddl_log_recovery() global_ddl_log.inited= FALSE; global_ddl_log.recovery_phase= TRUE; global_ddl_log.io_size= IO_SIZE; - global_ddl_log.file_id=(File)-1; + global_ddl_log.file_id= (File) -1; /* To be able to run this from boot, we allocate a temporary THD @@ -1135,8 +1138,12 @@ void release_ddl_log() my_free((char*)free_list, MYF(0)); free_list= tmp; } - if (global_ddl_log.file_id != (File)-1) - VOID(my_close(global_ddl_log.file_id, MYF(0))); + if (global_ddl_log.file_id >= 0) + { + VOID(my_close(global_ddl_log.file_id, MYF(MY_WME))); + global_ddl_log.file_id= (File) -1; + } + global_ddl_log.inited= 0; pthread_mutex_unlock(&LOCK_gdl); VOID(pthread_mutex_destroy(&LOCK_gdl)); DBUG_VOID_RETURN; @@ -2501,14 +2508,16 @@ static int mysql_prepare_table(THD *thd, HA_CREATE_INFO *create_info, break; } - switch(key->type){ + switch (key->type) { case Key::MULTIPLE: key_info->flags= 0; break; case Key::FULLTEXT: key_info->flags= HA_FULLTEXT; - if ((key_info->parser_name= key->parser_name)) + if ((key_info->parser_name= &key->key_create_info.parser_name)->str) key_info->flags|= HA_USES_PARSER; + else + key_info->parser_name= 0; break; case Key::SPATIAL: #ifdef HAVE_SPATIAL @@ -2532,7 +2541,7 @@ static int mysql_prepare_table(THD *thd, HA_CREATE_INFO *create_info, key_info->key_parts=(uint8) key->columns.elements; key_info->key_part=key_part_info; key_info->usable_key_parts= key_number; - key_info->algorithm=key->algorithm; + key_info->algorithm= key->key_create_info.algorithm; if (key->type == Key::FULLTEXT) { @@ -2554,6 +2563,12 @@ static int mysql_prepare_table(THD *thd, HA_CREATE_INFO *create_info, /* TODO: Add proper checks if handler supports key_type and algorithm */ if (key_info->flags & HA_SPATIAL) { + if (!(file->table_flags() & HA_CAN_RTREEKEYS)) + { + my_message(ER_TABLE_CANT_HANDLE_SPKEYS, ER(ER_TABLE_CANT_HANDLE_SPKEYS), + MYF(0)); + DBUG_RETURN(-1); + } if (key_info->key_parts != 1) { my_error(ER_WRONG_ARGUMENTS, MYF(0), "SPATIAL INDEX"); @@ -2578,6 +2593,18 @@ static int mysql_prepare_table(THD *thd, HA_CREATE_INFO *create_info, #endif } + /* Take block size from key part or table part */ + /* + TODO: Add warning if block size changes. We can't do it here, as + this may depend on the size of the key + */ + key_info->block_size= (key->key_create_info.block_size ? + key->key_create_info.block_size : + create_info->key_block_size); + + if (key_info->block_size) + key_info->flags|= HA_USES_BLOCK_SIZE; + List_iterator<key_part_spec> cols(key->columns), cols2(key->columns); CHARSET_INFO *ft_key_charset=0; // for FULLTEXT for (uint column_nr=0 ; (column=cols++) ; column_nr++) @@ -3551,7 +3578,9 @@ mysql_rename_table(handlerton *base, } } delete file; - if (error) + if (error == HA_ERR_WRONG_COMMAND) + my_error(ER_NOT_SUPPORTED_YET, MYF(0), "ALTER TABLE"); + else if (error) my_error(ER_ERROR_ON_RENAME, MYF(0), from, to, error); DBUG_RETURN(error != 0); } @@ -3869,6 +3898,8 @@ static bool mysql_admin_table(THD* thd, TABLE_LIST* tables, int result_code; DBUG_ENTER("mysql_admin_table"); + if (end_active_trans(thd)) + DBUG_RETURN(1); field_list.push_back(item = new Item_empty_string("Table", NAME_LEN*2)); item->maybe_null = 1; field_list.push_back(item = new Item_empty_string("Op", 10)); @@ -3919,6 +3950,7 @@ static bool mysql_admin_table(THD* thd, TABLE_LIST* tables, { switch ((*prepare_func)(thd, table, check_opt)) { case 1: // error, message written to net + ha_autocommit_or_rollback(thd, 1); close_thread_tables(thd); continue; case -1: // error, message could be written to net @@ -3960,6 +3992,7 @@ static bool mysql_admin_table(THD* thd, TABLE_LIST* tables, View opening can be interrupted in the middle of process so some tables can be left opening */ + ha_autocommit_or_rollback(thd, 1); close_thread_tables(thd); if (protocol->write()) goto err; @@ -3984,6 +4017,7 @@ static bool mysql_admin_table(THD* thd, TABLE_LIST* tables, length= my_snprintf(buff, sizeof(buff), ER(ER_OPEN_AS_READONLY), table_name); protocol->store(buff, length, system_charset_info); + ha_autocommit_or_rollback(thd, 0); close_thread_tables(thd); table->table=0; // For query cache if (protocol->write()) @@ -4029,6 +4063,7 @@ static bool mysql_admin_table(THD* thd, TABLE_LIST* tables, (table->table->file->ha_check_for_upgrade(check_opt) == HA_ADMIN_NEEDS_ALTER)) { + ha_autocommit_or_rollback(thd, 1); close_thread_tables(thd); tmp_disable_binlog(thd); // binlogging is done by caller if wanted result_code= mysql_recreate_table(thd, table, 0); @@ -4115,6 +4150,7 @@ send_result_message: "try with alter", so here we close the table, do an ALTER TABLE, reopen the table and do ha_innobase::analyze() on it. */ + ha_autocommit_or_rollback(thd, 0); close_thread_tables(thd); TABLE_LIST *save_next_local= table->next_local, *save_next_global= table->next_global; @@ -4122,6 +4158,7 @@ send_result_message: tmp_disable_binlog(thd); // binlogging is done by caller if wanted result_code= mysql_recreate_table(thd, table, 0); reenable_binlog(thd); + ha_autocommit_or_rollback(thd, 0); close_thread_tables(thd); if (!result_code) // recreation went ok { @@ -4196,14 +4233,20 @@ send_result_message: table->table->s->version=0; // Force close of table else if (open_for_modify && !table->table->s->log_table) { - pthread_mutex_lock(&LOCK_open); - remove_table_from_cache(thd, table->table->s->db.str, - table->table->s->table_name.str, RTFC_NO_FLAG); - pthread_mutex_unlock(&LOCK_open); - /* Something may be modified, that's why we have to invalidate cache */ + if (table->table->s->tmp_table) + table->table->file->info(HA_STATUS_CONST); + else + { + pthread_mutex_lock(&LOCK_open); + remove_table_from_cache(thd, table->table->s->db.str, + table->table->s->table_name.str, RTFC_NO_FLAG); + pthread_mutex_unlock(&LOCK_open); + } + /* May be something modified consequently we have to invalidate cache */ query_cache_invalidate3(thd, table->table, 0); } } + ha_autocommit_or_rollback(thd, 0); close_thread_tables(thd); table->table=0; // For query cache if (protocol->write()) @@ -4212,7 +4255,9 @@ send_result_message: send_eof(thd); DBUG_RETURN(FALSE); + err: + ha_autocommit_or_rollback(thd, 1); close_thread_tables(thd); // Shouldn't be needed if (table) table->table=0; @@ -4667,7 +4712,9 @@ mysql_discard_or_import_tablespace(THD *thd, if (error) goto err; write_bin_log(thd, FALSE, thd->query, thd->query_length); + err: + ha_autocommit_or_rollback(thd, error); close_thread_tables(thd); thd->tablespace_op=FALSE; @@ -5148,6 +5195,8 @@ bool mysql_alter_table(THD *thd,char *new_db, char *new_name, create_info->avg_row_length= table->s->avg_row_length; if (!(used_fields & HA_CREATE_USED_DEFAULT_CHARSET)) create_info->default_table_charset= table->s->table_charset; + if (!(used_fields & HA_CREATE_USED_KEY_BLOCK_SIZE)) + create_info->key_block_size= table->s->key_block_size; restore_record(table, s->default_values); // Empty record for DEFAULT List_iterator<Alter_drop> drop_it(alter_info->drop_list); @@ -5350,6 +5399,16 @@ bool mysql_alter_table(THD *thd,char *new_db, char *new_name, key_part_length)); } if (key_parts.elements) + { + KEY_CREATE_INFO key_create_info; + bzero((char*) &key_create_info, sizeof(key_create_info)); + + key_create_info.algorithm= key_info->algorithm; + if (key_info->flags & HA_USES_BLOCK_SIZE) + key_create_info.block_size= key_info->block_size; + if (key_info->flags & HA_USES_PARSER) + key_create_info.parser_name= *key_info->parser_name; + key_list.push_back(new Key(key_info->flags & HA_SPATIAL ? Key::SPATIAL : (key_info->flags & HA_NOSAME ? (!my_strcasecmp(system_charset_info, @@ -5358,11 +5417,10 @@ bool mysql_alter_table(THD *thd,char *new_db, char *new_name, (key_info->flags & HA_FULLTEXT ? Key::FULLTEXT : Key::MULTIPLE)), key_name, - key_info->algorithm, + &key_create_info, test(key_info->flags & HA_GENERATED_KEY), - key_parts, - key_info->flags & HA_USES_PARSER ? - &key_info->parser->name : 0)); + key_parts)); + } } { Key *key; @@ -5458,9 +5516,8 @@ bool mysql_alter_table(THD *thd,char *new_db, char *new_name, while ((prep_col= prep_col_it++)) prep_columns.push_back(new key_part_spec(*prep_col)); prepared_key_list.push_back(new Key(prep_key->type, prep_key->name, - prep_key->algorithm, - prep_key->generated, prep_columns, - prep_key->parser_name)); + &prep_key->key_create_info, + prep_key->generated, prep_columns)); } /* Create the prepared information. */ @@ -6344,7 +6401,8 @@ bool mysql_recreate_table(THD *thd, TABLE_LIST *table_list, } -bool mysql_checksum_table(THD *thd, TABLE_LIST *tables, HA_CHECK_OPT *check_opt) +bool mysql_checksum_table(THD *thd, TABLE_LIST *tables, + HA_CHECK_OPT *check_opt) { TABLE_LIST *table; List<Item> field_list; diff --git a/sql/sql_test.cc b/sql/sql_test.cc index bf86630d28c..b28aa4a1ce5 100644 --- a/sql/sql_test.cc +++ b/sql/sql_test.cc @@ -230,8 +230,8 @@ TEST_join(JOIN *join) */ void -print_plan(JOIN* join, double read_time, double record_count, - uint idx, const char *info) +print_plan(JOIN* join, uint idx, double record_count, double read_time, + double current_read_time, const char *info) { uint i; POSITION pos; @@ -245,13 +245,15 @@ print_plan(JOIN* join, double read_time, double record_count, DBUG_LOCK_FILE; if (join->best_read == DBL_MAX) { - fprintf(DBUG_FILE,"%s; idx:%u, best: DBL_MAX, current:%g\n", - info, idx, read_time); + fprintf(DBUG_FILE, + "%s; idx:%u, best: DBL_MAX, atime: %g, itime: %g, count: %g\n", + info, idx, current_read_time, read_time, record_count); } else { - fprintf(DBUG_FILE,"%s; idx: %u, best: %g, current: %g\n", - info, idx, join->best_read, read_time); + fprintf(DBUG_FILE, + "%s; idx:%u, best: %g, accumulated: %g, increment: %g, count: %g\n", + info, idx, join->best_read, current_read_time, read_time, record_count); } /* Print the tables in JOIN->positions */ @@ -270,9 +272,9 @@ print_plan(JOIN* join, double read_time, double record_count, Print the tables in JOIN->best_positions only if at least one complete plan has been found. An indicator for this is the value of 'join->best_read'. */ - fputs("BEST_POSITIONS: ", DBUG_FILE); if (join->best_read < DBL_MAX) { + fputs("BEST_POSITIONS: ", DBUG_FILE); for (i= 0; i < idx ; i++) { pos= join->best_positions[i]; diff --git a/sql/sql_view.cc b/sql/sql_view.cc index 3ef6a234f4e..8e5a776950d 100644 --- a/sql/sql_view.cc +++ b/sql/sql_view.cc @@ -943,7 +943,6 @@ bool mysql_make_view(THD *thd, File_parser *parser, TABLE_LIST *table) goto err; } - if (!(table->view_tables= (List<TABLE_LIST>*) new(thd->mem_root) List<TABLE_LIST>)) goto err; @@ -1194,6 +1193,7 @@ ok2: old_lex->time_zone_tables_used= thd->lex->time_zone_tables_used; result= !table->prelocking_placeholder && table->prepare_security(thd); + lex_end(thd->lex); end: if (arena) thd->restore_active_arena(arena, &backup); @@ -1201,6 +1201,8 @@ end: DBUG_RETURN(result); err: + DBUG_ASSERT(thd->lex == table->view); + lex_end(thd->lex); delete table->view; table->view= 0; // now it is not VIEW placeholder result= 1; diff --git a/sql/sql_yacc.yy b/sql/sql_yacc.yy index 0fbba495b00..32b5bc8adb9 100644 --- a/sql/sql_yacc.yy +++ b/sql/sql_yacc.yy @@ -364,6 +364,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b, ulong *yystacksize); %token JOIN_SYM %token KEYS %token KEY_SYM +%token KEY_BLOCK_SIZE %token KILL_SYM %token LANGUAGE_SYM %token LAST_INSERT_ID @@ -730,7 +731,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b, ulong *yystacksize); sp_opt_label BIN_NUM label_ident TEXT_STRING_filesystem %type <lex_str_ptr> - opt_table_alias opt_fulltext_parser + opt_table_alias %type <table> table_ident table_ident_nodb references xid @@ -795,7 +796,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b, ulong *yystacksize); key_type opt_unique_or_fulltext constraint_key_type %type <key_alg> - key_alg opt_btree_or_rtree + opt_btree_or_rtree %type <string_list> key_usage_list using_list @@ -886,6 +887,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b, ulong *yystacksize); view_suid view_tail view_list_opt view_list view_select view_check_option trigger_tail sp_tail install uninstall partition_entry binlog_base64_event + init_key_options key_options key_opts key_opt END_OF_INPUT %type <NONE> call sp_proc_stmts sp_proc_stmts1 sp_proc_stmt @@ -1220,11 +1222,13 @@ create: } create2 { Lex->current_select= &Lex->select_lex; } - | CREATE opt_unique_or_fulltext INDEX_SYM ident key_alg ON table_ident + | CREATE opt_unique_or_fulltext INDEX_SYM ident key_alg ON + table_ident { LEX *lex=Lex; lex->sql_command= SQLCOM_CREATE_INDEX; - if (!lex->current_select->add_table_to_list(lex->thd, $7, NULL, + if (!lex->current_select->add_table_to_list(lex->thd, $7, + NULL, TL_OPTION_UPDATING)) YYABORT; lex->create_list.empty(); @@ -1232,15 +1236,16 @@ create: lex->col_list.empty(); lex->change=NullS; } - '(' key_list ')' opt_fulltext_parser + '(' key_list ')' key_options { LEX *lex=Lex; - if ($2 != Key::FULLTEXT && $12) + if ($2 != Key::FULLTEXT && lex->key_create_info.parser_name.str) { yyerror(ER(ER_SYNTAX_ERROR)); YYABORT; } - lex->key_list.push_back(new Key($2,$4.str,$5,0,lex->col_list,$12)); + lex->key_list.push_back(new Key($2, $4.str, &lex->key_create_info, 0, + lex->col_list)); lex->col_list.empty(); } | CREATE DATABASE opt_if_not_exists ident @@ -3890,6 +3895,11 @@ create_table_option: | STORAGE_SYM DISK_SYM {Lex->create_info.store_on_disk= TRUE;} | STORAGE_SYM MEMORY_SYM {Lex->create_info.store_on_disk= FALSE;} | CONNECTION_SYM opt_equal TEXT_STRING_sys { Lex->create_info.connect_string.str= $3.str; Lex->create_info.connect_string.length= $3.length; Lex->create_info.used_fields|= HA_CREATE_USED_CONNECTION; } + | KEY_BLOCK_SIZE opt_equal ulong_num + { + Lex->create_info.used_fields|= HA_CREATE_USED_KEY_BLOCK_SIZE; + Lex->create_info.key_block_size= $3; + } ; default_charset: @@ -3983,23 +3993,25 @@ column_def: ; key_def: - key_type opt_ident key_alg '(' key_list ')' opt_fulltext_parser + key_type opt_ident key_alg '(' key_list ')' key_options { LEX *lex=Lex; - if ($1 != Key::FULLTEXT && $7) + if ($1 != Key::FULLTEXT && lex->key_create_info.parser_name.str) { yyerror(ER(ER_SYNTAX_ERROR)); YYABORT; } - lex->key_list.push_back(new Key($1,$2, $3, 0, lex->col_list, $7)); + lex->key_list.push_back(new Key($1,$2, &lex->key_create_info, 0, + lex->col_list)); lex->col_list.empty(); /* Alloced by sql_alloc */ } - | opt_constraint constraint_key_type opt_ident key_alg '(' key_list ')' + | opt_constraint constraint_key_type opt_ident key_alg + '(' key_list ')' key_options { LEX *lex=Lex; - const char *key_name= $3 ? $3:$1; - lex->key_list.push_back(new Key($2, key_name, $4, 0, - lex->col_list)); + const char *key_name= $3 ? $3 : $1; + lex->key_list.push_back(new Key($2, key_name, &lex->key_create_info, 0, + lex->col_list)); lex->col_list.empty(); /* Alloced by sql_alloc */ } | opt_constraint FOREIGN KEY_SYM opt_ident '(' key_list ')' references @@ -4012,7 +4024,7 @@ key_def: lex->fk_update_opt, lex->fk_match_option)); lex->key_list.push_back(new Key(Key::MULTIPLE, $4 ? $4 : $1, - HA_KEY_ALG_UNDEF, 1, + &default_key_create_info, 1, lex->col_list)); lex->col_list.empty(); /* Alloced by sql_alloc */ @@ -4029,20 +4041,6 @@ key_def: } ; -opt_fulltext_parser: - /* empty */ { $$= (LEX_STRING *)0; } - | WITH PARSER_SYM IDENT_sys - { - if (plugin_is_ready(&$3, MYSQL_FTPARSER_PLUGIN)) - $$= (LEX_STRING *)sql_memdup(&$3, sizeof(LEX_STRING)); - else - { - my_error(ER_FUNCTION_NOT_DEFINED, MYF(0), $3.str); - YYABORT; - } - } - ; - opt_check_constraint: /* empty */ | check_constraint @@ -4516,10 +4514,50 @@ opt_unique_or_fulltext: } ; +init_key_options: + { + Lex->key_create_info= default_key_create_info; + } + ; + +/* + For now, key_alg initializies lex->key_create_info. + In the future, when all key options are after key definition, + we can remove key_alg and move init_key_options to key_options +*/ + key_alg: - /* empty */ { $$= HA_KEY_ALG_UNDEF; } - | USING opt_btree_or_rtree { $$= $2; } - | TYPE_SYM opt_btree_or_rtree { $$= $2; }; + /* empty */ init_key_options + | init_key_options key_opts + ; + +key_options: + /* empty */ {} + | key_opts + ; + +key_opts: + key_opt + | key_opts key_opt + ; + +key_opt: + USING opt_btree_or_rtree { Lex->key_create_info.algorithm= $2; } + | TYPE_SYM opt_btree_or_rtree { Lex->key_create_info.algorithm= $2; } + | KEY_BLOCK_SIZE opt_equal ulong_num + { Lex->key_create_info.block_size= $3; } + | WITH PARSER_SYM IDENT_sys + { + if (plugin_is_ready(&$3, MYSQL_FTPARSER_PLUGIN)) + Lex->key_create_info.parser_name= $3; + else + { + my_error(ER_FUNCTION_NOT_DEFINED, MYF(0), $3.str); + YYABORT; + } + } + ; + opt_btree_or_rtree: BTREE_SYM { $$= HA_KEY_ALG_BTREE; } @@ -9348,7 +9386,7 @@ keyword_sp: | ISSUER_SYM {} | INNOBASE_SYM {} | INSERT_METHOD {} - | RELAY_THREAD {} + | KEY_BLOCK_SIZE {} | LAST_SYM {} | LEAVES {} | LESS_SYM {} @@ -9435,6 +9473,7 @@ keyword_sp: | REDUNDANT_SYM {} | RELAY_LOG_FILE_SYM {} | RELAY_LOG_POS_SYM {} + | RELAY_THREAD {} | RELOAD {} | REORGANIZE_SYM {} | REPEATABLE_SYM {} diff --git a/sql/structs.h b/sql/structs.h index e369d8ed7e8..72237887514 100644 --- a/sql/structs.h +++ b/sql/structs.h @@ -86,6 +86,7 @@ typedef struct st_key { uint key_parts; /* How many key_parts */ uint extra_length; uint usable_key_parts; /* Should normally be = key_parts */ + uint block_size; enum ha_key_alg algorithm; /* Note that parser is used when the table is opened for use, and diff --git a/sql/table.cc b/sql/table.cc index 6ba66569f5c..bacb703a28c 100644 --- a/sql/table.cc +++ b/sql/table.cc @@ -535,6 +535,7 @@ static int open_binary_frm(THD *thd, TABLE_SHARE *share, uchar *head, keyinfo->key_length= (uint) uint2korr(strpos+2); keyinfo->key_parts= (uint) strpos[4]; keyinfo->algorithm= (enum ha_key_alg) strpos[5]; + keyinfo->block_size= uint2korr(strpos+6); strpos+=8; } else @@ -706,6 +707,7 @@ static int open_binary_frm(THD *thd, TABLE_SHARE *share, uchar *head, } my_free(buff, MYF(0)); } + share->key_block_size= uint2korr(head+62); error=4; extra_rec_buf_length= uint2korr(head+59); @@ -2065,6 +2067,11 @@ File create_frm(THD *thd, const char *name, const char *db, tmp= MYSQL_VERSION_ID; // Store to avoid warning from int4store int4store(fileinfo+51, tmp); int4store(fileinfo+55, create_info->extra_size); + /* + 59-60 is reserved for extra_rec_buf_length, + 61 for default_part_db_type + */ + int2store(fileinfo+62, create_info->key_block_size); bzero(fill,IO_SIZE); for (; length > IO_SIZE ; length-= IO_SIZE) { diff --git a/sql/table.h b/sql/table.h index 85d49444b29..5fd9cd28585 100644 --- a/sql/table.h +++ b/sql/table.h @@ -160,6 +160,7 @@ typedef struct st_table_share uint ref_count; /* How many TABLE objects uses this */ uint open_count; /* Number of tables in open list */ uint blob_ptr_size; /* 4 or 8 */ + uint key_block_size; /* create key_block_size, if used */ uint null_bytes, last_null_bit_pos; uint fields; /* Number of fields */ uint rec_buff_length; /* Size of table->record[] buffer */ diff --git a/sql/unireg.cc b/sql/unireg.cc index bbb4d970d37..eb38e6c0592 100644 --- a/sql/unireg.cc +++ b/sql/unireg.cc @@ -338,9 +338,9 @@ err_handler: /* Pack screens to a screen for save in a form-file */ -static uchar * pack_screens(List<create_field> &create_fields, - uint *info_length, uint *screens, - bool small_file) +static uchar *pack_screens(List<create_field> &create_fields, + uint *info_length, uint *screens, + bool small_file) { reg1 uint i; uint row,start_row,end_row,fields_on_screen; @@ -431,7 +431,7 @@ static uint pack_keys(uchar *keybuff, uint key_count, KEY *keyinfo, int2store(pos+2,key->key_length); pos[4]= (uchar) key->key_parts; pos[5]= (uchar) key->algorithm; - pos[6]=pos[7]=0; // For the future + int2store(pos+6, key->block_size); pos+=8; key_parts+=key->key_parts; DBUG_PRINT("loop",("flags: %d key_parts: %d at 0x%lx", diff --git a/storage/heap/hp_delete.c b/storage/heap/hp_delete.c index 2d94418a1bf..f37db2588f3 100644 --- a/storage/heap/hp_delete.c +++ b/storage/heap/hp_delete.c @@ -79,7 +79,8 @@ int hp_rb_delete_key(HP_INFO *info, register HP_KEYDEF *keyinfo, custom_arg.key_length= hp_rb_make_key(keyinfo, info->recbuf, record, recpos); custom_arg.search_flag= SEARCH_SAME; old_allocated= keyinfo->rb_tree.allocated; - res= tree_delete(&keyinfo->rb_tree, info->recbuf, &custom_arg); + res= tree_delete(&keyinfo->rb_tree, info->recbuf, custom_arg.key_length, + &custom_arg); info->s->index_length-= (old_allocated - keyinfo->rb_tree.allocated); return res; } diff --git a/storage/myisam/ft_eval.c b/storage/myisam/ft_eval.c index eab9d37af0b..459742d2aff 100644 --- a/storage/myisam/ft_eval.c +++ b/storage/myisam/ft_eval.c @@ -54,6 +54,7 @@ int main(int argc, char *argv[]) /* Define a key over the first column */ keyinfo[0].seg=keyseg; keyinfo[0].keysegs=1; + keyinfo[0].block_length= 0; /* Default block length */ keyinfo[0].seg[0].type= HA_KEYTYPE_TEXT; keyinfo[0].seg[0].flag= HA_BLOB_PART; keyinfo[0].seg[0].start=recinfo[0].length; diff --git a/storage/myisam/ft_test1.c b/storage/myisam/ft_test1.c index d54b344e2cd..28dcfb2b758 100644 --- a/storage/myisam/ft_test1.c +++ b/storage/myisam/ft_test1.c @@ -89,6 +89,7 @@ static int run_test(const char *filename) /* Define a key over the first column */ keyinfo[0].seg=keyseg; keyinfo[0].keysegs=1; + keyinfo[0].block_length= 0; /* Default block length */ keyinfo[0].seg[0].type= key_type; keyinfo[0].seg[0].flag= (key_field == FIELD_BLOB) ? HA_BLOB_PART: (key_field == FIELD_VARCHAR) ? HA_VAR_LENGTH_PART:0; diff --git a/storage/myisam/mi_check.c b/storage/myisam/mi_check.c index eb2f42697ce..0fa095a21db 100644 --- a/storage/myisam/mi_check.c +++ b/storage/myisam/mi_check.c @@ -358,7 +358,7 @@ int chk_key(MI_CHECK *param, register MI_INFO *info) puts("- check key delete-chain"); param->key_file_blocks=info->s->base.keystart; - for (key=0 ; key < info->s->state.header.max_block_size ; key++) + for (key=0 ; key < info->s->state.header.max_block_size_index ; key++) if (check_k_link(param,info,key)) { if (param->testflag & T_VERBOSE) puts(""); @@ -1411,7 +1411,7 @@ int mi_repair(MI_CHECK *param, register MI_INFO *info, share->state.key_root[i]= HA_OFFSET_ERROR; /* Drop the delete chain. */ - for (i=0 ; i < share->state.header.max_block_size ; i++) + for (i=0 ; i < share->state.header.max_block_size_index ; i++) share->state.key_del[i]= HA_OFFSET_ERROR; /* @@ -1795,7 +1795,7 @@ int mi_sort_index(MI_CHECK *param, register MI_INFO *info, my_string name) info->update= (short) (HA_STATE_CHANGED | HA_STATE_ROW_CHANGED); for (key=0 ; key < info->s->base.keys ; key++) info->s->state.key_root[key]=index_pos[key]; - for (key=0 ; key < info->s->state.header.max_block_size ; key++) + for (key=0 ; key < info->s->state.header.max_block_size_index ; key++) info->s->state.key_del[key]= HA_OFFSET_ERROR; info->s->state.changed&= ~STATE_NOT_SORTED_PAGES; @@ -2095,7 +2095,7 @@ int mi_repair_by_sort(MI_CHECK *param, register MI_INFO *info, /* Clear the pointers to the given rows */ for (i=0 ; i < share->base.keys ; i++) share->state.key_root[i]= HA_OFFSET_ERROR; - for (i=0 ; i < share->state.header.max_block_size ; i++) + for (i=0 ; i < share->state.header.max_block_size_index ; i++) share->state.key_del[i]= HA_OFFSET_ERROR; info->state->key_file_length=share->base.keystart; } @@ -2463,7 +2463,7 @@ int mi_repair_parallel(MI_CHECK *param, register MI_INFO *info, /* Clear the pointers to the given rows */ for (i=0 ; i < share->base.keys ; i++) share->state.key_root[i]= HA_OFFSET_ERROR; - for (i=0 ; i < share->state.header.max_block_size ; i++) + for (i=0 ; i < share->state.header.max_block_size_index ; i++) share->state.key_del[i]= HA_OFFSET_ERROR; info->state->key_file_length=share->base.keystart; } @@ -3800,6 +3800,7 @@ int recreate_table(MI_CHECK *param, MI_INFO **org_info, char *filename) ha_rows max_records; ulonglong file_length,tmp_length; MI_CREATE_INFO create_info; + DBUG_ENTER("recreate_table"); error=1; /* Default error */ info= **org_info; @@ -3809,7 +3810,7 @@ int recreate_table(MI_CHECK *param, MI_INFO **org_info, char *filename) unpack= (share.options & HA_OPTION_COMPRESS_RECORD) && (param->testflag & T_UNPACK); if (!(keyinfo=(MI_KEYDEF*) my_alloca(sizeof(MI_KEYDEF)*share.base.keys))) - return 0; + DBUG_RETURN(0); memcpy((byte*) keyinfo,(byte*) share.keyinfo, (size_t) (sizeof(MI_KEYDEF)*share.base.keys)); @@ -3818,14 +3819,14 @@ int recreate_table(MI_CHECK *param, MI_INFO **org_info, char *filename) (key_parts+share.base.keys)))) { my_afree((gptr) keyinfo); - return 1; + DBUG_RETURN(1); } if (!(recdef=(MI_COLUMNDEF*) my_alloca(sizeof(MI_COLUMNDEF)*(share.base.fields+1)))) { my_afree((gptr) keyinfo); my_afree((gptr) keysegs); - return 1; + DBUG_RETURN(1); } if (!(uniquedef=(MI_UNIQUEDEF*) my_alloca(sizeof(MI_UNIQUEDEF)*(share.state.header.uniques+1)))) @@ -3833,7 +3834,7 @@ int recreate_table(MI_CHECK *param, MI_INFO **org_info, char *filename) my_afree((gptr) recdef); my_afree((gptr) keyinfo); my_afree((gptr) keysegs); - return 1; + DBUG_RETURN(1); } /* Copy the column definitions */ @@ -3903,6 +3904,11 @@ int recreate_table(MI_CHECK *param, MI_INFO **org_info, char *filename) create_info.language = (param->language ? param->language : share.state.header.language); create_info.key_file_length= status_info.key_file_length; + /* + Allow for creating an auto_increment key. This has an effect only if + an auto_increment key exists in the original table. + */ + create_info.with_auto_increment= TRUE; /* We don't have to handle symlinks here because we are using HA_DONT_TOUCH_DATA */ if (mi_create(filename, @@ -3947,7 +3953,7 @@ end: my_afree((gptr) keyinfo); my_afree((gptr) recdef); my_afree((gptr) keysegs); - return error; + DBUG_RETURN(error); } @@ -4050,6 +4056,8 @@ void update_auto_increment_key(MI_CHECK *param, MI_INFO *info, my_bool repair_only) { byte *record; + DBUG_ENTER("update_auto_increment_key"); + if (!info->s->base.auto_key || ! mi_is_key_active(info->s->state.key_map, info->s->base.auto_key - 1)) { @@ -4057,7 +4065,7 @@ void update_auto_increment_key(MI_CHECK *param, MI_INFO *info, mi_check_print_info(param, "Table: %s doesn't have an auto increment key\n", param->isam_file_name); - return; + DBUG_VOID_RETURN; } if (!(param->testflag & T_SILENT) && !(param->testflag & T_REP)) @@ -4070,7 +4078,7 @@ void update_auto_increment_key(MI_CHECK *param, MI_INFO *info, MYF(0)))) { mi_check_print_error(param,"Not enough memory for extra record"); - return; + DBUG_VOID_RETURN; } mi_extra(info,HA_EXTRA_KEYREAD,0); @@ -4081,7 +4089,7 @@ void update_auto_increment_key(MI_CHECK *param, MI_INFO *info, mi_extra(info,HA_EXTRA_NO_KEYREAD,0); my_free((char*) record, MYF(0)); mi_check_print_error(param,"%d when reading last record",my_errno); - return; + DBUG_VOID_RETURN; } if (!repair_only) info->s->state.auto_increment=param->auto_increment_value; @@ -4097,7 +4105,7 @@ void update_auto_increment_key(MI_CHECK *param, MI_INFO *info, mi_extra(info,HA_EXTRA_NO_KEYREAD,0); my_free((char*) record, MYF(0)); update_state_info(param, info, UPDATE_AUTO_INC); - return; + DBUG_VOID_RETURN; } diff --git a/storage/myisam/mi_create.c b/storage/myisam/mi_create.c index 3be998b2c17..22cbde278be 100644 --- a/storage/myisam/mi_create.c +++ b/storage/myisam/mi_create.c @@ -28,9 +28,9 @@ #endif #include <m_ctype.h> - /* - ** Old options is used when recreating database, from isamchk - */ +/* + Old options is used when recreating database, from myisamchk +*/ int mi_create(const char *name,uint keys,MI_KEYDEF *keydefs, uint columns, MI_COLUMNDEF *recinfo, @@ -45,6 +45,7 @@ int mi_create(const char *name,uint keys,MI_KEYDEF *keydefs, key_length,info_length,key_segs,options,min_key_length_skip, base_pos,long_varchar_count,varchar_length, max_key_block_length,unique_key_parts,fulltext_keys,offset; + uint aligned_key_start, block_length; ulong reclength, real_reclength,min_pack_length; char filename[FN_REFLEN],linkname[FN_REFLEN], *linkname_ptr; ulong pack_reclength; @@ -428,8 +429,16 @@ int mi_create(const char *name,uint keys,MI_KEYDEF *keydefs, key_segs) share.state.rec_per_key_part[key_segs-1]=1L; length+=key_length; + /* Get block length for key, if defined by user */ + block_length= (keydef->block_length ? + my_round_up_to_next_power(keydef->block_length) : + myisam_block_size); + block_length= max(block_length, MI_MIN_KEY_BLOCK_LENGTH); + block_length= min(block_length, MI_MAX_KEY_BLOCK_LENGTH); + keydef->block_length= MI_BLOCK_SIZE(length-real_length_diff, - pointer,MI_MAX_KEYPTR_SIZE); + pointer,MI_MAX_KEYPTR_SIZE, + block_length); if (keydef->block_length > MI_MAX_KEY_BLOCK_LENGTH || length >= MI_MAX_KEY_BUFF) { @@ -485,7 +494,7 @@ int mi_create(const char *name,uint keys,MI_KEYDEF *keydefs, mi_int2store(share.state.header.base_pos,base_pos); share.state.header.language= (ci->language ? ci->language : default_charset_info->number); - share.state.header.max_block_size=max_key_block_length/MI_MIN_KEY_BLOCK_LENGTH; + share.state.header.max_block_size_index= max_key_block_length/MI_MIN_KEY_BLOCK_LENGTH; share.state.dellink = HA_OFFSET_ERROR; share.state.process= (ulong) getpid(); @@ -512,8 +521,12 @@ int mi_create(const char *name,uint keys,MI_KEYDEF *keydefs, mi_int2store(share.state.header.unique_key_parts,unique_key_parts); mi_set_all_keys_active(share.state.key_map, keys); - share.base.keystart = share.state.state.key_file_length= - MY_ALIGN(info_length, myisam_block_size); + aligned_key_start= my_round_up_to_next_power(max_key_block_length ? + max_key_block_length : + myisam_block_size); + + share.base.keystart= share.state.state.key_file_length= + MY_ALIGN(info_length, aligned_key_start); share.base.max_key_block_length=max_key_block_length; share.base.max_key_length=ALIGN_SIZE(max_key_length+4); share.base.records=ci->max_rows; diff --git a/storage/myisam/mi_key.c b/storage/myisam/mi_key.c index f8463a0b6b0..526a733e724 100644 --- a/storage/myisam/mi_key.c +++ b/storage/myisam/mi_key.c @@ -127,7 +127,7 @@ uint _mi_make_key(register MI_INFO *info, uint keynr, uchar *key, } if (keyseg->flag & HA_VAR_LENGTH_PART) { - uint pack_length= keyseg->bit_start; + uint pack_length= (keyseg->bit_start == 1 ? 1 : 2); uint tmp_length= (pack_length == 1 ? (uint) *(uchar*) pos : uint2korr(pos)); pos+= pack_length; /* Skip VARCHAR length */ diff --git a/storage/myisam/mi_open.c b/storage/myisam/mi_open.c index 91bf438035f..b61c1af24da 100644 --- a/storage/myisam/mi_open.c +++ b/storage/myisam/mi_open.c @@ -295,7 +295,7 @@ MI_INFO *mi_open(const char *name, int mode, uint open_flags) &share->data_file_name,strlen(data_name)+1, &share->state.key_root,keys*sizeof(my_off_t), &share->state.key_del, - (share->state.header.max_block_size*sizeof(my_off_t)), + (share->state.header.max_block_size_index*sizeof(my_off_t)), #ifdef THREAD &share->key_root_lock,sizeof(rw_lock_t)*keys, #endif @@ -310,7 +310,7 @@ MI_INFO *mi_open(const char *name, int mode, uint open_flags) (char*) key_root, sizeof(my_off_t)*keys); memcpy((char*) share->state.key_del, (char*) key_del, (sizeof(my_off_t) * - share->state.header.max_block_size)); + share->state.header.max_block_size_index)); strmov(share->unique_file_name, name_buff); share->unique_name_length= strlen(name_buff); strmov(share->index_file_name, index_name); @@ -820,7 +820,7 @@ uint mi_state_info_write(File file, MI_STATE_INFO *state, uint pWrite) uchar buff[MI_STATE_INFO_SIZE + MI_STATE_EXTRA_SIZE]; uchar *ptr=buff; uint i, keys= (uint) state->header.keys, - key_blocks=state->header.max_block_size; + key_blocks=state->header.max_block_size_index; DBUG_ENTER("mi_state_info_write"); memcpy_fixed(ptr,&state->header,sizeof(state->header)); @@ -886,7 +886,7 @@ uchar *mi_state_info_read(uchar *ptr, MI_STATE_INFO *state) ptr +=sizeof(state->header); keys=(uint) state->header.keys; key_parts=mi_uint2korr(state->header.key_parts); - key_blocks=state->header.max_block_size; + key_blocks=state->header.max_block_size_index; state->open_count = mi_uint2korr(ptr); ptr +=2; state->changed= (bool) *ptr++; @@ -1059,7 +1059,7 @@ char *mi_keydef_read(char *ptr, MI_KEYDEF *keydef) keydef->keylength = mi_uint2korr(ptr); ptr +=2; keydef->minlength = mi_uint2korr(ptr); ptr +=2; keydef->maxlength = mi_uint2korr(ptr); ptr +=2; - keydef->block_size = keydef->block_length/MI_MIN_KEY_BLOCK_LENGTH-1; + keydef->block_size_index= keydef->block_length/MI_MIN_KEY_BLOCK_LENGTH-1; keydef->underflow_block_length=keydef->block_length/3; keydef->version = 0; /* Not saved */ keydef->parser = &ft_default_parser; diff --git a/storage/myisam/mi_page.c b/storage/myisam/mi_page.c index 5240c063fba..a5e2b01ed0f 100644 --- a/storage/myisam/mi_page.c +++ b/storage/myisam/mi_page.c @@ -112,8 +112,8 @@ int _mi_dispose(register MI_INFO *info, MI_KEYDEF *keyinfo, my_off_t pos, DBUG_ENTER("_mi_dispose"); DBUG_PRINT("enter",("pos: %ld", (long) pos)); - old_link=info->s->state.key_del[keyinfo->block_size]; - info->s->state.key_del[keyinfo->block_size]=pos; + old_link= info->s->state.key_del[keyinfo->block_size_index]; + info->s->state.key_del[keyinfo->block_size_index]= pos; mi_sizestore(buff,old_link); info->s->state.changed|= STATE_NOT_SORTED_PAGES; DBUG_RETURN(key_cache_write(info->s->key_cache, @@ -132,7 +132,8 @@ my_off_t _mi_new(register MI_INFO *info, MI_KEYDEF *keyinfo, int level) char buff[8]; DBUG_ENTER("_mi_new"); - if ((pos=info->s->state.key_del[keyinfo->block_size]) == HA_OFFSET_ERROR) + if ((pos= info->s->state.key_del[keyinfo->block_size_index]) == + HA_OFFSET_ERROR) { if (info->state->key_file_length >= info->s->base.max_key_file_length - keyinfo->block_length) @@ -152,7 +153,7 @@ my_off_t _mi_new(register MI_INFO *info, MI_KEYDEF *keyinfo, int level) (uint) keyinfo->block_length,0)) pos= HA_OFFSET_ERROR; else - info->s->state.key_del[keyinfo->block_size]=mi_sizekorr(buff); + info->s->state.key_del[keyinfo->block_size_index]= mi_sizekorr(buff); } info->s->state.changed|= STATE_NOT_SORTED_PAGES; DBUG_PRINT("exit",("Pos: %ld",(long) pos)); diff --git a/storage/myisam/mi_test1.c b/storage/myisam/mi_test1.c index 0e62b074376..0b78ac8a7ff 100644 --- a/storage/myisam/mi_test1.c +++ b/storage/myisam/mi_test1.c @@ -95,6 +95,7 @@ static int run_test(const char *filename) /* Define a key over the first column */ keyinfo[0].seg=keyseg; keyinfo[0].keysegs=1; + keyinfo[0].block_length= 0; /* Default block length */ keyinfo[0].key_alg=HA_KEY_ALG_BTREE; keyinfo[0].seg[0].type= key_type; keyinfo[0].seg[0].flag= pack_seg; diff --git a/storage/myisam/mi_test2.c b/storage/myisam/mi_test2.c index e77a37d853f..357ebb1b9bc 100644 --- a/storage/myisam/mi_test2.c +++ b/storage/myisam/mi_test2.c @@ -95,6 +95,7 @@ int main(int argc, char *argv[]) keyinfo[0].key_alg=HA_KEY_ALG_BTREE; keyinfo[0].keysegs=1; keyinfo[0].flag = pack_type; + keyinfo[0].block_length= 0; /* Default block length */ keyinfo[1].seg= &glob_keyseg[1][0]; keyinfo[1].seg[0].start=7; keyinfo[1].seg[0].length=6; @@ -111,6 +112,7 @@ int main(int argc, char *argv[]) keyinfo[1].key_alg=HA_KEY_ALG_BTREE; keyinfo[1].keysegs=2; keyinfo[1].flag =0; + keyinfo[1].block_length= MI_MIN_KEY_BLOCK_LENGTH; /* Diff blocklength */ keyinfo[2].seg= &glob_keyseg[2][0]; keyinfo[2].seg[0].start=12; keyinfo[2].seg[0].length=8; @@ -121,6 +123,7 @@ int main(int argc, char *argv[]) keyinfo[2].key_alg=HA_KEY_ALG_BTREE; keyinfo[2].keysegs=1; keyinfo[2].flag =HA_NOSAME; + keyinfo[2].block_length= 0; /* Default block length */ keyinfo[3].seg= &glob_keyseg[3][0]; keyinfo[3].seg[0].start=0; keyinfo[3].seg[0].length=reclength-(use_blob ? 8 : 0); @@ -132,6 +135,7 @@ int main(int argc, char *argv[]) keyinfo[3].key_alg=HA_KEY_ALG_BTREE; keyinfo[3].keysegs=1; keyinfo[3].flag = pack_type; + keyinfo[3].block_length= 0; /* Default block length */ keyinfo[4].seg= &glob_keyseg[4][0]; keyinfo[4].seg[0].start=0; keyinfo[4].seg[0].length=5; @@ -143,6 +147,7 @@ int main(int argc, char *argv[]) keyinfo[4].key_alg=HA_KEY_ALG_BTREE; keyinfo[4].keysegs=1; keyinfo[4].flag = pack_type; + keyinfo[4].block_length= 0; /* Default block length */ keyinfo[5].seg= &glob_keyseg[5][0]; keyinfo[5].seg[0].start=0; keyinfo[5].seg[0].length=4; @@ -154,6 +159,7 @@ int main(int argc, char *argv[]) keyinfo[5].key_alg=HA_KEY_ALG_BTREE; keyinfo[5].keysegs=1; keyinfo[5].flag = pack_type; + keyinfo[5].block_length= 0; /* Default block length */ recinfo[0].type=pack_fields ? FIELD_SKIP_PRESPACE : 0; recinfo[0].length=7; @@ -813,7 +819,7 @@ end: printf("Write records: %d\nUpdate records: %d\nSame-key-read: %d\nDelete records: %d\n", write_count,update,dupp_keys,opt_delete); if (rec_pointer_size) printf("Record pointer size: %d\n",rec_pointer_size); - printf("myisam_block_size: %u\n", myisam_block_size); + printf("myisam_block_size: %lu\n", myisam_block_size); if (key_cacheing) { puts("Key cache used"); @@ -914,13 +920,13 @@ static void get_options(int argc, char **argv) } break; case 'e': /* myisam_block_length */ - if ((myisam_block_size=atoi(++pos)) < MI_MIN_KEY_BLOCK_LENGTH || + if ((myisam_block_size= atoi(++pos)) < MI_MIN_KEY_BLOCK_LENGTH || myisam_block_size > MI_MAX_KEY_BLOCK_LENGTH) { fprintf(stderr,"Wrong myisam_block_length\n"); exit(1); } - myisam_block_size=1 << my_bit_log2(myisam_block_size); + myisam_block_size= my_round_up_to_next_power(myisam_block_size); break; case 'E': /* myisam_block_length */ if ((key_cache_block_size=atoi(++pos)) < MI_MIN_KEY_BLOCK_LENGTH || @@ -929,7 +935,7 @@ static void get_options(int argc, char **argv) fprintf(stderr,"Wrong key_cache_block_size\n"); exit(1); } - key_cache_block_size=1 << my_bit_log2(key_cache_block_size); + key_cache_block_size= my_round_up_to_next_power(key_cache_block_size); break; case 'f': if ((first_key=atoi(++pos)) < 0 || first_key >= MYISAM_KEYS) diff --git a/storage/myisam/mi_test3.c b/storage/myisam/mi_test3.c index 4e764c6f971..173fbe64cf5 100644 --- a/storage/myisam/mi_test3.c +++ b/storage/myisam/mi_test3.c @@ -76,6 +76,7 @@ int main(int argc,char **argv) keyinfo[0].key_alg=HA_KEY_ALG_BTREE; keyinfo[0].keysegs=1; keyinfo[0].flag = (uint8) HA_PACK_KEY; + keyinfo[0].block_length= 0; /* Default block length */ keyinfo[1].seg= &keyseg[1][0]; keyinfo[1].seg[0].start=8; keyinfo[1].seg[0].length=4; /* Long is always 4 in myisam */ @@ -84,6 +85,7 @@ int main(int argc,char **argv) keyinfo[1].key_alg=HA_KEY_ALG_BTREE; keyinfo[1].keysegs=1; keyinfo[1].flag =HA_NOSAME; + keyinfo[1].block_length= 0; /* Default block length */ recinfo[0].type=0; recinfo[0].length=sizeof(record.id); diff --git a/storage/myisam/myisamdef.h b/storage/myisam/myisamdef.h index caf6254c321..0b450de9c03 100644 --- a/storage/myisam/myisamdef.h +++ b/storage/myisam/myisamdef.h @@ -55,7 +55,7 @@ typedef struct st_mi_state_info uchar keys; /* number of keys in file */ uchar uniques; /* number of UNIQUE definitions */ uchar language; /* Language for indexes */ - uchar max_block_size; /* max keyblock size */ + uchar max_block_size_index; /* max keyblock size */ uchar fulltext_keys; uchar not_used; /* To align to 8 */ } header; @@ -431,7 +431,7 @@ typedef struct st_mi_sort_param #define MI_FOUND_WRONG_KEY 32738 /* Impossible value from ha_key_cmp */ #define MI_MAX_KEY_BLOCK_SIZE (MI_MAX_KEY_BLOCK_LENGTH/MI_MIN_KEY_BLOCK_LENGTH) -#define MI_BLOCK_SIZE(key_length,data_pointer,key_pointer) (((((key_length)+(data_pointer)+(key_pointer))*4+(key_pointer)+2)/myisam_block_size+1)*myisam_block_size) +#define MI_BLOCK_SIZE(key_length,data_pointer,key_pointer,block_size) (((((key_length)+(data_pointer)+(key_pointer))*4+(key_pointer)+2)/(block_size)+1)*(block_size)) #define MI_MAX_KEYPTR_SIZE 5 /* For calculating block lengths */ #define MI_MIN_KEYBLOCK_LENGTH 50 /* When to split delete blocks */ @@ -742,6 +742,8 @@ my_bool check_table_is_closed(const char *name, const char *where); int mi_open_datafile(MI_INFO *info, MYISAM_SHARE *share, File file_to_dup); int mi_open_keyfile(MYISAM_SHARE *share); void mi_setup_functions(register MYISAM_SHARE *share); +my_bool mi_dynmap_file(MI_INFO *info, my_off_t size); +void mi_remap_file(MI_INFO *info, my_off_t size); /* Functions needed by mi_check */ volatile int *killed_ptr(MI_CHECK *param); diff --git a/storage/myisam/myisamlog.c b/storage/myisam/myisamlog.c index de55b86252c..17af4ab34a2 100644 --- a/storage/myisam/myisamlog.c +++ b/storage/myisam/myisamlog.c @@ -475,7 +475,7 @@ static int examine_log(my_string file_name, char **table_names) { if (!curr_file_info->closed) files_open--; - VOID(tree_delete(&tree, (gptr) curr_file_info, tree.custom_arg)); + VOID(tree_delete(&tree, (gptr) curr_file_info, 0, tree.custom_arg)); } break; case MI_LOG_EXTRA: diff --git a/storage/myisam/myisampack.c b/storage/myisam/myisampack.c index e80a3ffacd9..5b3067cb115 100644 --- a/storage/myisam/myisampack.c +++ b/storage/myisam/myisampack.c @@ -2726,6 +2726,7 @@ static int compress_isam_file(PACK_MRG_INFO *mrg, HUFF_COUNTS *huff_counts) break; } case FIELD_LAST: + case FIELD_enum_val_count: abort(); /* Impossible */ } start_pos+=count->max_zero_fill; @@ -2965,7 +2966,7 @@ static int save_state(MI_INFO *isam_file,PACK_MRG_INFO *mrg,my_off_t new_length, mi_clear_all_keys_active(share->state.key_map); for (key=0 ; key < share->base.keys ; key++) share->state.key_root[key]= HA_OFFSET_ERROR; - for (key=0 ; key < share->state.header.max_block_size ; key++) + for (key=0 ; key < share->state.header.max_block_size_index ; key++) share->state.key_del[key]= HA_OFFSET_ERROR; isam_file->state->checksum=crc; /* Save crc here */ share->changed=1; /* Force write of header */ diff --git a/storage/ndb/include/kernel/signaldata/TcKeyReq.hpp b/storage/ndb/include/kernel/signaldata/TcKeyReq.hpp index a37f3811b25..0dbc4094e67 100644 --- a/storage/ndb/include/kernel/signaldata/TcKeyReq.hpp +++ b/storage/ndb/include/kernel/signaldata/TcKeyReq.hpp @@ -39,6 +39,7 @@ class TcKeyReq { friend class NdbOperation; friend class NdbIndexOperation; friend class NdbScanOperation; + friend class NdbBlob; friend class DbUtil; /** diff --git a/storage/ndb/include/ndbapi/NdbBlob.hpp b/storage/ndb/include/ndbapi/NdbBlob.hpp index 13bbfa59e50..089b70339de 100644 --- a/storage/ndb/include/ndbapi/NdbBlob.hpp +++ b/storage/ndb/include/ndbapi/NdbBlob.hpp @@ -326,6 +326,7 @@ private: bool isWriteOp(); bool isDeleteOp(); bool isScanOp(); + bool isTakeOverOp(); // computations Uint32 getPartNumber(Uint64 pos); Uint32 getPartCount(); diff --git a/storage/ndb/src/ndbapi/NdbBlob.cpp b/storage/ndb/src/ndbapi/NdbBlob.cpp index 00f71a2f85b..4e3e13b59bf 100644 --- a/storage/ndb/src/ndbapi/NdbBlob.cpp +++ b/storage/ndb/src/ndbapi/NdbBlob.cpp @@ -23,6 +23,7 @@ #include <NdbBlob.hpp> #include "NdbBlobImpl.hpp" #include <NdbScanOperation.hpp> +#include <signaldata/TcKeyReq.hpp> #include <NdbEventOperationImpl.hpp> /* @@ -392,6 +393,13 @@ NdbBlob::isScanOp() theNdbOp->theOperationType == NdbOperation::OpenRangeScanRequest; } +inline bool +NdbBlob::isTakeOverOp() +{ + return + TcKeyReq::getTakeOverScanFlag(theNdbOp->theScanInfo); +} + // computations (inline) inline Uint32 @@ -1527,8 +1535,22 @@ NdbBlob::preExecute(NdbTransaction::ExecType anExecType, bool& batch) if (isUpdateOp() || isWriteOp() || isDeleteOp()) { // add operation before this one to read head+inline NdbOperation* tOp = theNdbCon->getNdbOperation(theTable, theNdbOp); + /* + * If main op is from take over scan lock, the added read is done + * as committed read: + * + * In normal transactional case, the row is locked by us and + * committed read returns same as normal read. + * + * In current TRUNCATE TABLE, the deleting trans is committed in + * batches and then restarted with new trans id. A normal read + * would hang on the scan delete lock and then fail. + */ + NdbOperation::LockMode lockMode = + ! isTakeOverOp() ? + NdbOperation::LM_Read : NdbOperation::LM_CommittedRead; if (tOp == NULL || - tOp->readTuple() == -1 || + tOp->readTuple(lockMode) == -1 || setTableKeyValue(tOp) == -1 || getHeadInlineValue(tOp) == -1) { setErrorCode(tOp); diff --git a/storage/ndb/test/ndbapi/testBlobs.cpp b/storage/ndb/test/ndbapi/testBlobs.cpp index a1b0c89652e..bf9a8b1bce9 100644 --- a/storage/ndb/test/ndbapi/testBlobs.cpp +++ b/storage/ndb/test/ndbapi/testBlobs.cpp @@ -44,6 +44,7 @@ struct Opt { bool m_dbg; bool m_dbgall; const char* m_dbug; + bool m_fac; bool m_full; unsigned m_loop; unsigned m_parts; @@ -72,6 +73,7 @@ struct Opt { m_dbg(false), m_dbgall(false), m_dbug(0), + m_fac(false), m_full(false), m_loop(1), m_parts(10), @@ -110,6 +112,7 @@ printusage() << " -dbg print debug" << endl << " -dbgall print also NDB API debug (if compiled in)" << endl << " -dbug opt dbug options" << endl + << " -fac fetch across commit in scan delete [" << d.m_fac << "]" << endl << " -full read/write only full blob values" << endl << " -loop N loop N times 0=forever [" << d.m_loop << "]" << endl << " -parts N max parts in blob value [" << d.m_parts << "]" << endl @@ -1255,23 +1258,11 @@ deleteScan(bool idx) CHK((ret = g_ops->nextResult(false)) == 0 || ret == 1 || ret == 2); if (++n == g_opt.m_batch || ret == 2) { DBG("execute batch: n=" << n << " ret=" << ret); - switch (0) { - case 0: // works normally + if (! g_opt.m_fac) { CHK(g_con->execute(NoCommit) == 0); - CHK(true || g_con->restart() == 0); - break; - case 1: // nonsense - g_con is invalid for 2nd batch - CHK(g_con->execute(Commit) == 0); - CHK(true || g_con->restart() == 0); - break; - case 2: // DBTC sendSignalErrorRefuseLab - CHK(g_con->execute(NoCommit) == 0); - CHK(g_con->restart() == 0); - break; - case 3: // 266 time-out + } else { CHK(g_con->execute(Commit) == 0); CHK(g_con->restart() == 0); - break; } n = 0; } @@ -1817,6 +1808,10 @@ NDB_COMMAND(testOdbcDriver, "testBlobs", "testBlobs", "testBlobs", 65535) continue; } } + if (strcmp(arg, "-fac") == 0) { + g_opt.m_fac = true; + continue; + } if (strcmp(arg, "-full") == 0) { g_opt.m_full = true; continue; diff --git a/storage/ndb/tools/delete_all.cpp b/storage/ndb/tools/delete_all.cpp index feedded06ad..fcf9b425bd0 100644 --- a/storage/ndb/tools/delete_all.cpp +++ b/storage/ndb/tools/delete_all.cpp @@ -23,17 +23,21 @@ #include <NDBT.hpp> static int clear_table(Ndb* pNdb, const NdbDictionary::Table* pTab, - bool commit_across_open_cursor, int parallelism=240); + bool fetch_across_commit, int parallelism=240); NDB_STD_OPTS_VARS; static const char* _dbname = "TEST_DB"; +static my_bool _transactional = false; static struct my_option my_long_options[] = { NDB_STD_OPTS("ndb_desc"), { "database", 'd', "Name of database table is in", (gptr*) &_dbname, (gptr*) &_dbname, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0 }, + { "transactional", 't', "Single transaction (may run out of operations)", + (gptr*) &_transactional, (gptr*) &_transactional, 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() @@ -84,18 +88,11 @@ int main(int argc, char** argv){ ndbout << " Table " << argv[i] << " does not exist!" << endl; return NDBT_ProgramExit(NDBT_WRONGARGS); } - // Check if we have any blobs - bool commit_across_open_cursor = true; - for (int j = 0; j < pTab->getNoOfColumns(); j++) { - NdbDictionary::Column::Type t = pTab->getColumn(j)->getType(); - if (t == NdbDictionary::Column::Blob || - t == NdbDictionary::Column::Text) { - commit_across_open_cursor = false; - break; - } - } - ndbout << "Deleting all from " << argv[i] << "..."; - if(clear_table(&MyNdb, pTab, commit_across_open_cursor) == NDBT_FAILED){ + ndbout << "Deleting all from " << argv[i]; + if (! _transactional) + ndbout << " (non-transactional)"; + ndbout << " ..."; + if(clear_table(&MyNdb, pTab, ! _transactional) == NDBT_FAILED){ res = NDBT_FAILED; ndbout << "FAILED" << endl; } @@ -105,7 +102,7 @@ int main(int argc, char** argv){ int clear_table(Ndb* pNdb, const NdbDictionary::Table* pTab, - bool commit_across_open_cursor, int parallelism) + bool fetch_across_commit, int parallelism) { // Scan all records exclusive and delete // them one by one @@ -136,7 +133,7 @@ int clear_table(Ndb* pNdb, const NdbDictionary::Table* pTab, } goto failed; } - + pOp = pTrans->getNdbScanOperation(pTab->getName()); if (pOp == NULL) { goto failed; @@ -167,7 +164,7 @@ int clear_table(Ndb* pNdb, const NdbDictionary::Table* pTab, } while((check = pOp->nextResult(false)) == 0); if(check != -1){ - if (commit_across_open_cursor) { + if (fetch_across_commit) { check = pTrans->execute(NdbTransaction::Commit); pTrans->restart(); // new tx id } else { @@ -198,7 +195,7 @@ int clear_table(Ndb* pNdb, const NdbDictionary::Table* pTab, } goto failed; } - if (! commit_across_open_cursor && + if (! fetch_across_commit && pTrans->execute(NdbTransaction::Commit) != 0) { err = pTrans->getNdbError(); goto failed; diff --git a/vio/viosslfactories.c b/vio/viosslfactories.c index 4ee27f1e491..002874caf58 100644 --- a/vio/viosslfactories.c +++ b/vio/viosslfactories.c @@ -296,7 +296,7 @@ ctor_failure: TODO: Add option --verify to mysqld to be able to change verification mode */ -struct st_VioSSLAcceptorFd* +struct st_VioSSLAcceptorFd * new_VioSSLAcceptorFd(const char *key_file, const char *cert_file, const char *ca_file, @@ -387,4 +387,12 @@ ctor_failure: my_free((gptr) ptr,MYF(0)); DBUG_RETURN(0); } + + +void free_vio_ssl_acceptor_fd(struct st_VioSSLAcceptorFd *fd) +{ + SSL_CTX_free(fd->ssl_context); + my_free((gptr) fd, MYF(0)); +} + #endif /* HAVE_OPENSSL */ |