diff options
-rwxr-xr-x | BUILD/compile-pentium-maintainer | 13 | ||||
-rw-r--r-- | acconfig.h | 9 | ||||
-rw-r--r-- | configure.in | 26 | ||||
-rw-r--r-- | include/my_global.h | 6 | ||||
-rw-r--r-- | innobase/dict/dict0load.c | 9 | ||||
-rw-r--r-- | innobase/fil/fil0fil.c | 242 | ||||
-rw-r--r-- | innobase/os/os0file.c | 47 | ||||
-rw-r--r-- | innobase/row/row0mysql.c | 169 | ||||
-rw-r--r-- | myisam/mi_open.c | 1 | ||||
-rw-r--r-- | mysql-test/include/have_geometry.inc | 4 | ||||
-rw-r--r-- | mysql-test/r/have_geometry.require | 2 | ||||
-rw-r--r-- | mysql-test/r/multi_update.result | 1 | ||||
-rw-r--r-- | mysql-test/r/subselect.result | 2 | ||||
-rw-r--r-- | mysql-test/t/gis-rtree.test | 2 | ||||
-rw-r--r-- | mysql-test/t/gis.test | 2 | ||||
-rw-r--r-- | mysql-test/t/multi_update.test | 1 | ||||
-rw-r--r-- | mysql-test/t/subselect.test | 2 | ||||
-rw-r--r-- | mysql-test/t/system_mysql_db_fix.test | 4 | ||||
-rw-r--r-- | sql/ha_myisam.cc | 4 | ||||
-rw-r--r-- | sql/item.cc | 13 | ||||
-rw-r--r-- | sql/item.h | 39 | ||||
-rw-r--r-- | sql/mysql_priv.h | 1 | ||||
-rw-r--r-- | sql/mysqld.cc | 13 | ||||
-rw-r--r-- | sql/set_var.cc | 2 | ||||
-rw-r--r-- | sql/slave.cc | 2 | ||||
-rw-r--r-- | sql/sql_class.cc | 2 | ||||
-rw-r--r-- | sql/sql_class.h | 2 | ||||
-rw-r--r-- | sql/sql_show.cc | 7 | ||||
-rw-r--r-- | tests/client_test.c | 90 |
29 files changed, 462 insertions, 255 deletions
diff --git a/BUILD/compile-pentium-maintainer b/BUILD/compile-pentium-maintainer deleted file mode 100755 index 1265154dc76..00000000000 --- a/BUILD/compile-pentium-maintainer +++ /dev/null @@ -1,13 +0,0 @@ -#! /bin/sh - -path=`dirname $0` -. "$path/SETUP.sh" - -extra_flags="$pentium_cflags $debug_cflags" -c_warnings="$c_warnings $debug_extra_warnings" -cxx_warnings="$cxx_warnings $debug_extra_warnings" -extra_configs="$pentium_configs $debug_configs " - -extra_configs="$extra_configs --enable-maintainer-mode" - -. "$path/FINISH.sh" diff --git a/acconfig.h b/acconfig.h index 67e9d1759c6..9b85f47ce35 100644 --- a/acconfig.h +++ b/acconfig.h @@ -197,6 +197,15 @@ /* If we want to have query cache */ #undef HAVE_QUERY_CACHE +/* Spatial extentions */ +#undef HAVE_SPATIAL + +/* RTree keys */ +#undef HAVE_RTREE_KEYS + +/* Access checks in embedded library */ +#undef HAVE_EMBEDDED_PRIVILEGE_CONTROL + /* Solaris define gethostbyaddr_r with 7 arguments. glibc2 defines this with 8 arguments */ #undef HAVE_SOLARIS_STYLE_GETHOST diff --git a/configure.in b/configure.in index 0dfa17b7da8..c7667748139 100644 --- a/configure.in +++ b/configure.in @@ -95,7 +95,6 @@ AC_SUBST(CXXLDFLAGS) AC_PREREQ(2.12)dnl Minimum Autoconf version required. -AM_MAINTAINER_MODE #AC_ARG_PROGRAM # Automaticly invoked by AM_INIT_AUTOMAKE AM_SANITY_CHECK # This is needed is SUBDIRS is set @@ -2133,6 +2132,31 @@ then AC_DEFINE(HAVE_QUERY_CACHE) fi +AC_ARG_WITH(geometry, + [ --without-geometry Do not build geometry-related parts.], + [with_geometry=$withval], + [with_geometry=yes] +) + +if test "$with_geometry" = "yes" +then + AC_DEFINE(HAVE_SPATIAL) + AC_DEFINE(HAVE_RTREE_KEYS) +fi + +AC_ARG_WITH(embedded_privilege_control, + [ --with-embedded-privilege-control + Build parts to check user's privileges. + Only affects embedded library.], + [with_embedded_privilege_control=$withval], + [with_embedded_privilege_control=no] +) + +if test "$with_embedded_privilege_control" = "yes" +then + AC_DEFINE(HAVE_EMBEDDED_PRIVILEGE_CONTROL) +fi + AC_ARG_WITH(extra-tools, [ --without-extra-tools Skip building utilites in the tools directory.], [with_tools=$withval], diff --git a/include/my_global.h b/include/my_global.h index 57c736d6f75..3d1a770d877 100644 --- a/include/my_global.h +++ b/include/my_global.h @@ -1194,6 +1194,8 @@ do { doubleget_union _tmp; \ #define MYSQL_UNIVERSAL_CLIENT_CHARSET MYSQL_DEFAULT_CHARSET_NAME #endif -#define HAVE_SPATIAL -#define HAVE_RTREE_KEYS +#if defined(EMBEDDED_LIBRARY) && !defined(HAVE_EMBEDDED_PRIVILEGE_CONTROL) +#define NO_EMBEDDED_ACCESS_CHECKS +#endif + #endif /* my_global_h */ diff --git a/innobase/dict/dict0load.c b/innobase/dict/dict0load.c index b55050ee83f..ee4ae9dd1a1 100644 --- a/innobase/dict/dict0load.c +++ b/innobase/dict/dict0load.c @@ -207,7 +207,6 @@ dict_check_tablespaces_or_store_max_id( ulint space_id; ulint max_space_id = 0; mtr_t mtr; - char name[OS_FILE_MAX_PATH]; mutex_enter(&(dict_sys->mutex)); @@ -247,9 +246,7 @@ loop: /* We found one */ - ut_a(len < OS_FILE_MAX_PATH - 10); - ut_memcpy(name, field, len); - name[len] = '\0'; + char* name = mem_strdupl(field, len); field = rec_get_nth_field(rec, 9, &len); ut_a(len == 4); @@ -267,7 +264,9 @@ loop: fil_space_for_table_exists_in_mem(space_id, name, TRUE, TRUE); } - + + mem_free(name); + if (space_id > max_space_id) { max_space_id = space_id; } diff --git a/innobase/fil/fil0fil.c b/innobase/fil/fil0fil.c index b076e3a3315..3b033655856 100644 --- a/innobase/fil/fil0fil.c +++ b/innobase/fil/fil0fil.c @@ -1749,7 +1749,7 @@ fil_delete_tablespace( fil_space_t* space; fil_node_t* node; ulint count = 0; - char path[OS_FILE_MAX_PATH]; + char* path; ut_a(id != 0); stop_ibuf_merges: @@ -1806,11 +1806,8 @@ try_again: } ut_a(space); - ut_a(strlen(space->name) < OS_FILE_MAX_PATH); ut_a(space->n_pending_ibuf_merges == 0); - strcpy(path, space->name); - space->is_being_deleted = TRUE; ut_a(UT_LIST_GET_LEN(space->chain) == 1); @@ -1834,6 +1831,8 @@ try_again: goto try_again; } + path = mem_strdup(space->name); + mutex_exit(&(system->mutex)); #ifndef UNIV_HOTBACKUP /* Invalidate in the buffer pool all pages belonging to the @@ -1851,27 +1850,26 @@ try_again: if (success) { success = os_file_delete(path); + } - if (success) { - /* Write a log record about the deletion of the .ibd - file, so that ibbackup can replay it in the - --apply-log phase. We use a dummy mtr and the familiar - log write mechanism. */ + mem_free(path); + + if (success) { #ifndef UNIV_HOTBACKUP - { - mtr_t mtr; + /* Write a log record about the deletion of the .ibd + file, so that ibbackup can replay it in the + --apply-log phase. We use a dummy mtr and the familiar + log write mechanism. */ + mtr_t mtr; - /* When replaying the operation in ibbackup, do not try - to write any log record */ - mtr_start(&mtr); + /* When replaying the operation in ibbackup, do not try + to write any log record */ + mtr_start(&mtr); - fil_op_write_log(MLOG_FILE_DELETE, id, path, - NULL, &mtr); - mtr_commit(&mtr); - } + fil_op_write_log(MLOG_FILE_DELETE, id, path, NULL, &mtr); + mtr_commit(&mtr); #endif - return(TRUE); - } + return(TRUE); } return(FALSE); @@ -1957,6 +1955,29 @@ fil_rename_tablespace_in_mem( } /*********************************************************************** +Allocates a file name for a single-table tablespace. +The string must be freed by caller with mem_free(). */ +static +char* +fil_make_ibd_name( +/*==============*/ + /* out, own: file name */ + const char* name) /* in: table name */ +{ + ulint namelen = strlen(name); + ulint dirlen = strlen(fil_path_to_mysql_datadir); + char* filename = mem_alloc(namelen + dirlen + sizeof "/.ibd"); + + memcpy(filename, fil_path_to_mysql_datadir, dirlen); + filename[dirlen] = '/'; + memcpy(filename + dirlen + 1, name, namelen); + memcpy(filename + dirlen + namelen + 1, ".ibd", sizeof ".ibd"); + + srv_normalize_path_for_win(filename); + return(filename); +} + +/*********************************************************************** Renames a single-table tablespace. The tablespace must be cached in the tablespace memory cache. */ @@ -1978,9 +1999,9 @@ fil_rename_tablespace( fil_space_t* space; fil_node_t* node; ulint count = 0; - char* path = NULL; + char* path; ibool old_name_was_specified = TRUE; - char old_path[OS_FILE_MAX_PATH]; + char* old_path; ut_a(id != 0); @@ -2059,48 +2080,33 @@ retry: /* Check that the old name in the space is right */ if (old_name_was_specified) { - ut_a(strlen(old_name) + strlen(fil_path_to_mysql_datadir) - < OS_FILE_MAX_PATH - 10); - sprintf(old_path, "%s/%s.ibd", fil_path_to_mysql_datadir, - old_name); - srv_normalize_path_for_win(old_path); + old_path = fil_make_ibd_name(old_name); ut_a(strcmp(space->name, old_path) == 0); ut_a(strcmp(node->name, old_path) == 0); } else { - sprintf(old_path, "%s", space->name); + old_path = mem_strdup(space->name); } /* Rename the tablespace and the node in the memory cache */ - - ut_a(strlen(new_name) + strlen(fil_path_to_mysql_datadir) - < OS_FILE_MAX_PATH - 10); - path = mem_alloc(OS_FILE_MAX_PATH); - - sprintf(path, "%s/%s.ibd", fil_path_to_mysql_datadir, new_name); - - srv_normalize_path_for_win(path); - + path = fil_make_ibd_name(new_name); success = fil_rename_tablespace_in_mem(space, node, path); - if (!success) { - - goto func_exit; - } - - success = os_file_rename(old_path, path); + if (success) { + success = os_file_rename(old_path, path); - if (!success) { - /* We have to revert the changes we made to the tablespace - memory cache */ + if (!success) { + /* We have to revert the changes we made + to the tablespace memory cache */ - ut_a(fil_rename_tablespace_in_mem(space, node, old_path)); + ut_a(fil_rename_tablespace_in_mem(space, node, + old_path)); + } } -func_exit: - if (path) { - mem_free(path); - } + mem_free(path); + mem_free(old_path); + space->stop_ios = FALSE; mutex_exit(&(system->mutex)); @@ -2144,15 +2150,11 @@ fil_create_new_single_table_tablespace( ulint err; byte* page; ibool success; - char path[OS_FILE_MAX_PATH]; + char* path; ut_a(size >= FIL_IBD_FILE_INITIAL_SIZE); - ut_a(strlen(tablename) + strlen(fil_path_to_mysql_datadir) - < OS_FILE_MAX_PATH - 10); - sprintf(path, "%s/%s.ibd", fil_path_to_mysql_datadir, tablename); - - srv_normalize_path_for_win(path); + path = fil_make_ibd_name(tablename); file = os_file_create(path, OS_FILE_CREATE, OS_FILE_NORMAL, OS_DATA_FILE, &ret); @@ -2175,14 +2177,17 @@ fil_create_new_single_table_tablespace( "InnoDB: resolve the problem by removing the file %s\n" "InnoDB: under the 'datadir' of MySQL.\n", path); + mem_free(path); return(DB_TABLESPACE_ALREADY_EXISTS); } if (err == OS_FILE_DISK_FULL) { + mem_free(path); return(DB_OUT_OF_FILE_SPACE); } + mem_free(path); return(DB_ERROR); } @@ -2195,6 +2200,7 @@ fil_create_new_single_table_tablespace( os_file_close(file); os_file_delete(path); + mem_free(path); return(DB_OUT_OF_FILE_SPACE); } @@ -2206,9 +2212,11 @@ fil_create_new_single_table_tablespace( if (*space_id == ULINT_UNDEFINED) { ut_free(page); + error_exit: os_file_close(file); os_file_delete(path); + mem_free(path); return(DB_ERROR); } @@ -2234,11 +2242,7 @@ fil_create_new_single_table_tablespace( if (!ret) { fprintf(stderr, "InnoDB: Error: could not write the first page to tablespace %s\n", path); - - os_file_close(file); - os_file_delete(path); - - return(DB_ERROR); + goto error_exit; } ret = os_file_flush(file); @@ -2246,27 +2250,22 @@ fil_create_new_single_table_tablespace( if (!ret) { fprintf(stderr, "InnoDB: Error: file flush of tablespace %s failed\n", path); - - os_file_close(file); - os_file_delete(path); - - return(DB_ERROR); + goto error_exit; } os_file_close(file); if (*space_id == ULINT_UNDEFINED) { os_file_delete(path); - + error_exit2: + mem_free(path); return(DB_ERROR); } success = fil_space_create(path, *space_id, FIL_TABLESPACE); if (!success) { - os_file_delete(path); - - return(DB_ERROR); + goto error_exit2; } fil_node_create(path, size, *space_id, FALSE); @@ -2282,6 +2281,7 @@ fil_create_new_single_table_tablespace( mtr_commit(&mtr); } #endif + mem_free(path); return(DB_SUCCESS); } @@ -2315,13 +2315,7 @@ fil_reset_too_high_lsns( ulint page_no; ibool success; - filepath = ut_malloc(OS_FILE_MAX_PATH); - - ut_a(strlen(name) < OS_FILE_MAX_PATH - 10); - - sprintf(filepath, "%s/%s.ibd", fil_path_to_mysql_datadir, name); - - srv_normalize_path_for_win(filepath); + filepath = fil_make_ibd_name(name); file = os_file_create_simple_no_error_handling(filepath, OS_FILE_OPEN, OS_FILE_READ_WRITE, &success); @@ -2450,13 +2444,7 @@ fil_open_single_table_tablespace( ulint space_id; ibool ret = TRUE; - filepath = ut_malloc(OS_FILE_MAX_PATH); - - ut_a(strlen(name) < OS_FILE_MAX_PATH - 10); - - sprintf(filepath, "%s/%s.ibd", fil_path_to_mysql_datadir, name); - - srv_normalize_path_for_win(filepath); + filepath = fil_make_ibd_name(name); file = os_file_create_simple_no_error_handling(filepath, OS_FILE_OPEN, OS_FILE_READ_ONLY, &success); @@ -2525,6 +2513,28 @@ func_exit: return(ret); } +#ifdef UNIV_HOTBACKUP +/*********************************************************************** +Allocates a file name for an old version of a single-table tablespace. +The string must be freed by caller with mem_free(). */ +static +char* +fil_make_ibbackup_old_name( +/*=======================*/ + /* out, own: file name */ + const char* name) /* in: original file name */ +{ + static const char suffix[] = "_ibbackup_old_vers_"; + ulint len = strlen(name); + char* path = ut_malloc(len + (15 + sizeof suffix)); + + memcpy(path, name, len); + memcpy(path + len, suffix, (sizeof suffix) - 1); + ut_sprintf_timestamp_without_extra_chars(path + len + sizeof suffix); + return(path); +} +#endif /* UNIV_HOTBACKUP */ + /************************************************************************ Opens an .ibd file and adds the associated single-table tablespace to the InnoDB fil0fil.c data structures. */ @@ -2547,10 +2557,8 @@ fil_load_single_table_tablespace( #ifdef UNIV_HOTBACKUP fil_space_t* space; #endif - filepath = ut_malloc(OS_FILE_MAX_PATH); - - ut_a(strlen(dbname) + strlen(filename) - + strlen(fil_path_to_mysql_datadir) < OS_FILE_MAX_PATH - 100); + filepath = ut_malloc(strlen(dbname) + strlen(filename) + + strlen(fil_path_to_mysql_datadir) + 3); sprintf(filepath, "%s/%s/%s", fil_path_to_mysql_datadir, dbname, filename); @@ -2564,7 +2572,7 @@ fil_load_single_table_tablespace( fprintf(stderr, "InnoDB: Error: could not open single-table tablespace file\n" -"InnoDB: %s!", filepath); +"InnoDB: %s!\n", filepath); ut_free(filepath); @@ -2579,7 +2587,7 @@ fil_load_single_table_tablespace( fprintf(stderr, "InnoDB: Error: could not measure the size of single-table tablespace file\n" -"InnoDB: %s!", filepath); +"InnoDB: %s!\n", filepath); os_file_close(file); ut_free(filepath); @@ -2639,11 +2647,7 @@ fil_load_single_table_tablespace( filepath, space_id, filepath, size); os_file_close(file); - new_path = ut_malloc(OS_FILE_MAX_PATH); - - sprintf(new_path, "%s_ibbackup_old_vers_", filepath); - ut_sprintf_timestamp_without_extra_chars( - new_path + ut_strlen(new_path)); + new_path = fil_make_ibbackup_old_name(filepath); ut_a(os_file_rename(filepath, new_path)); ut_free(page); @@ -2676,11 +2680,8 @@ fil_load_single_table_tablespace( space->name); os_file_close(file); - new_path = ut_malloc(OS_FILE_MAX_PATH); + new_path = fil_make_ibbackup_old_name(filepath); - sprintf(new_path, "%s_ibbackup_old_vers_", filepath); - ut_sprintf_timestamp_without_extra_chars( - new_path + ut_strlen(new_path)); mutex_exit(&(fil_system->mutex)); ut_a(os_file_rename(filepath, new_path)); @@ -2724,7 +2725,8 @@ fil_load_single_table_tablespaces(void) /* out: DB_SUCCESS or error number */ { int ret; - char* dbpath; + char* dbpath = NULL; + ulint dbpath_len = 0; os_file_dir_t dir; os_file_dir_t dbdir; os_file_stat_t dbinfo; @@ -2739,7 +2741,7 @@ fil_load_single_table_tablespaces(void) return(DB_ERROR); } - dbpath = ut_malloc(OS_FILE_MAX_PATH); + dbpath = ut_malloc(dbpath_len); /* Scan all directories under the datadir. They are the database directories of MySQL. */ @@ -2747,6 +2749,7 @@ fil_load_single_table_tablespaces(void) ret = os_file_readdir_next_file(fil_path_to_mysql_datadir, dir, &dbinfo); while (ret == 0) { + ulint len; /* printf("Looking at %s in datadir\n", dbinfo.name); */ if (dbinfo.type == OS_FILE_TYPE_FILE @@ -2757,9 +2760,19 @@ fil_load_single_table_tablespaces(void) /* We found a symlink or a directory; try opening it to see if a symlink is a directory */ - - ut_a(strlen(dbinfo.name) < OS_FILE_MAX_PATH - 10); + len = strlen(fil_path_to_mysql_datadir) + + strlen (dbinfo.name) + 2; + if (len > dbpath_len) { + dbpath_len = len; + if (!dbpath) { + dbpath = mem_alloc(dbpath_len); + } + else { + dbpath = mem_realloc(dbpath, dbpath_len, + __FILE__, __LINE__); + } + } sprintf(dbpath, "%s/%s", fil_path_to_mysql_datadir, dbinfo.name); srv_normalize_path_for_win(dbpath); @@ -2809,7 +2822,9 @@ next_datadir_item: dir, &dbinfo); } - ut_free(dbpath); + if (dbpath) { + ut_free(dbpath); + } /* At the end of directory we should get 1 as the return value, -1 if there was an error */ @@ -2962,14 +2977,13 @@ fil_space_for_table_exists_in_mem( fil_system_t* system = fil_system; fil_space_t* namespace; fil_space_t* space; - char path[OS_FILE_MAX_PATH]; + char* path; ut_ad(system); mutex_enter(&(system->mutex)); - sprintf(path, "%s/%s.ibd", fil_path_to_mysql_datadir, name); - srv_normalize_path_for_win(path); + path = fil_make_ibd_name(name); /* Look if there is a space with the same id */ @@ -2988,6 +3002,7 @@ fil_space_for_table_exists_in_mem( space->mark = TRUE; } + mem_free(path); mutex_exit(&(system->mutex)); return(TRUE); @@ -2995,6 +3010,7 @@ fil_space_for_table_exists_in_mem( if (!print_error_if_does_not_exist) { + mem_free(path); mutex_exit(&(system->mutex)); return(FALSE); @@ -3024,6 +3040,7 @@ fil_space_for_table_exists_in_mem( "InnoDB: You can look from section 15.1 of http://www.innodb.com/ibman.html\n" "InnoDB: how to resolve the issue.\n"); + mem_free(path); mutex_exit(&(system->mutex)); return(FALSE); @@ -3047,11 +3064,13 @@ fil_space_for_table_exists_in_mem( "InnoDB: You can look from section 15.1 of http://www.innodb.com/ibman.html\n" "InnoDB: how to resolve the issue.\n"); + mem_free(path); mutex_exit(&(system->mutex)); return(FALSE); } + mem_free(path); mutex_exit(&(system->mutex)); return(FALSE); @@ -3072,14 +3091,13 @@ fil_get_space_id_for_table( fil_system_t* system = fil_system; fil_space_t* namespace; ulint id = ULINT_UNDEFINED; - char path[OS_FILE_MAX_PATH]; + char* path; ut_ad(system); mutex_enter(&(system->mutex)); - sprintf(path, "%s/%s.ibd", fil_path_to_mysql_datadir, name); - srv_normalize_path_for_win(path); + path = fil_make_ibd_name(name); /* Look if there is a space with the same name; the name is the directory path to the file */ @@ -3091,6 +3109,8 @@ fil_get_space_id_for_table( id = namespace->id; } + mem_free(path); + mutex_exit(&(system->mutex)); return(id); diff --git a/innobase/os/os0file.c b/innobase/os/os0file.c index a27da6d870e..9d428c283a5 100644 --- a/innobase/os/os0file.c +++ b/innobase/os/os0file.c @@ -387,22 +387,19 @@ os_file_lock( /*=========*/ /* out: 0 on success */ int fd, /* in: file descriptor */ - const char* name, /* in: file name */ - uint lock_type) /* in: lock_type */ + const char* name) /* in: file name */ { struct flock lk; - lk.l_type = lock_type; + lk.l_type = F_WRLCK; lk.l_whence = SEEK_SET; lk.l_start = lk.l_len = 0; if (fcntl(fd, F_SETLK, &lk) == -1) { fprintf(stderr, - "InnoDB: Unable to lock %s with lock %d, error: %d", - name, lock_type, errno); - perror (": fcntl"); + "InnoDB: Unable to lock %s, error: %d", name, errno); close(fd); return(-1); } - return 0; + return(0); } #endif /* USE_FILE_LOCK */ @@ -869,7 +866,8 @@ try_again: goto try_again; } #ifdef USE_FILE_LOCK - } else if (os_file_lock(file, name, F_WRLCK)) { + } else if (access_type == OS_FILE_READ_WRITE + && os_file_lock(file, name)) { *success = FALSE; file = -1; #endif @@ -980,7 +978,8 @@ os_file_create_simple_no_error_handling( if (file == -1) { *success = FALSE; #ifdef USE_FILE_LOCK - } else if (os_file_lock(file, name, F_WRLCK)) { + } else if (access_type == OS_FILE_READ_WRITE + && os_file_lock(file, name)) { *success = FALSE; file = -1; #endif @@ -1194,7 +1193,8 @@ try_again: goto try_again; } #ifdef USE_FILE_LOCK - } else if (os_file_lock(file, name, F_WRLCK)) { + } else if (create_mode != OS_FILE_OPEN_RAW + && os_file_lock(file, name)) { *success = FALSE; file = -1; #endif @@ -1395,9 +1395,6 @@ os_file_close( #else int ret; -#ifdef USE_FILE_LOCK - (void) os_file_lock(file, "unknown", F_UNLCK); -#endif ret = close(file); if (ret == -1) { @@ -1434,9 +1431,6 @@ os_file_close_no_error_handling( #else int ret; -#ifdef USE_FILE_LOCK - (void) os_file_lock(file, "unknown", F_UNLCK); -#endif ret = close(file); if (ret == -1) { @@ -2331,31 +2325,22 @@ os_file_dirname( pathname */ const char* path) /* in: pathname */ { - char* dir; - int i, length, last_slash; - /* find the offset of the last slash */ - length = ut_strlen(path); - for (i = length - 1; i >= 0 && path[i] != OS_FILE_PATH_SEPARATOR; i++); - last_slash = i; - - if (last_slash < 0) { + const char* last_slash = strrchr(path, OS_FILE_PATH_SEPARATOR); + if (!last_slash) { /* no slash in the path, return "." */ return(mem_strdup(".")); } /* ok, there is a slash */ - if (last_slash == 0) { + if (last_slash == path) { /* last slash is the first char of the path */ return(mem_strdup("/")); } /* non-trivial directory component */ - dir = mem_strdup(path); - dir[last_slash] = 0; - - return(dir); + return(mem_strdupl(path, last_slash - path)); } /******************************************************************** @@ -2369,12 +2354,12 @@ os_file_create_subdirs_if_needed( const char* path) /* in: path name */ { char* subdir; - static char rootdir[2] = { OS_FILE_PATH_SEPARATOR, 0 }; ibool success, subdir_exists; os_file_type_t type; subdir = os_file_dirname(path); - if (0 == strcmp(subdir, rootdir) || 0 == strcmp(subdir, ".")) { + if (strlen(subdir) == 1 + && (*subdir == OS_FILE_PATH_SEPARATOR || *subdir == '.')) { /* subdir is root or cwd, nothing to do */ ut_free(subdir); return(TRUE); diff --git a/innobase/row/row0mysql.c b/innobase/row/row0mysql.c index 174b8cbae34..623069cc90c 100644 --- a/innobase/row/row0mysql.c +++ b/innobase/row/row0mysql.c @@ -1951,7 +1951,37 @@ row_discard_tablespace_for_mysql( que_t* graph = NULL; ibool success; ulint err; - char buf[2 * OS_FILE_MAX_PATH]; + char* buf; + + static const char discard_tablespace_proc1[] = + "PROCEDURE DISCARD_TABLESPACE_PROC () IS\n" + "old_id CHAR;\n" + "new_id CHAR;\n" + "new_id_low INT;\n" + "new_id_high INT;\n" + "table_name CHAR;\n" + "BEGIN\n" + "table_name := "; + static const char discard_tablespace_proc2[] = + ";\n" + "new_id_high := %lu;\n" + "new_id_low := %lu;\n" + "new_id := CONCAT(TO_BINARY(new_id_high, 4), TO_BINARY(new_id_low, 4));\n" + "SELECT ID INTO old_id\n" + "FROM SYS_TABLES\n" + "WHERE NAME = table_name;\n" + "IF (SQL %% NOTFOUND) THEN\n" + " COMMIT WORK;\n" + " RETURN;\n" + "END IF;\n" + "UPDATE SYS_TABLES SET ID = new_id\n" + "WHERE ID = old_id;\n" + "UPDATE SYS_COLUMNS SET TABLE_ID = new_id\n" + "WHERE TABLE_ID = old_id;\n" + "UPDATE SYS_INDEXES SET TABLE_ID = new_id\n" + "WHERE TABLE_ID = old_id;\n" + "COMMIT WORK;\n" + "END;\n"; ut_ad(trx->mysql_thread_id == os_thread_get_curr_id()); @@ -1973,9 +2003,10 @@ row_discard_tablespace_for_mysql( if (table->space == 0) { ut_print_timestamp(stderr); - fprintf(stderr, -" InnoDB: Error: table %s\n" -"InnoDB: is in the system tablespace 0 which cannot be discarded\n", name); + fputs(" InnoDB: Error: table ", stderr); + ut_print_name(stderr, name); + fputs("\n" +"InnoDB: is in the system tablespace 0 which cannot be discarded\n", stderr); err = DB_ERROR; goto funct_exit; @@ -1983,36 +2014,16 @@ row_discard_tablespace_for_mysql( new_id = dict_hdr_get_new_id(DICT_HDR_TABLE_ID); - sprintf(buf, - "PROCEDURE DISCARD_TABLESPACE_PROC () IS\n" - "old_id CHAR;\n" - "new_id CHAR;\n" - "new_id_low INT;\n" - "new_id_high INT;\n" - "table_name CHAR;\n" - "BEGIN\n" - "table_name :='%s';\n" - "new_id_high := %lu;\n" - "new_id_low := %lu;\n" - "new_id := CONCAT(TO_BINARY(new_id_high, 4), TO_BINARY(new_id_low, 4));\n" - "SELECT ID INTO old_id\n" - "FROM SYS_TABLES\n" - "WHERE NAME = table_name;\n" - "IF (SQL %% NOTFOUND) THEN\n" - " COMMIT WORK;\n" - " RETURN;\n" - "END IF;\n" - "UPDATE SYS_TABLES SET ID = new_id\n" - "WHERE ID = old_id;\n" - "UPDATE SYS_COLUMNS SET TABLE_ID = new_id\n" - "WHERE TABLE_ID = old_id;\n" - "UPDATE SYS_INDEXES SET TABLE_ID = new_id\n" - "WHERE TABLE_ID = old_id;\n" - "COMMIT WORK;\n" - "END;\n", name, (ulong) ut_dulint_get_high(new_id), - (ulong) ut_dulint_get_low(new_id)); + buf = mem_alloc((sizeof discard_tablespace_proc1) + + (sizeof discard_tablespace_proc2) + + 20 + ut_strlenq(name, '\'')); - ut_a(strlen(buf) < 2 * OS_FILE_MAX_PATH); + memcpy(buf, discard_tablespace_proc1, sizeof discard_tablespace_proc1); + sprintf(ut_strcpyq(buf + (sizeof discard_tablespace_proc1 - 1), + '\'', name), + discard_tablespace_proc2, + (ulong) ut_dulint_get_high(new_id), + (ulong) ut_dulint_get_low(new_id)); graph = pars_sql(buf); @@ -2126,9 +2137,10 @@ row_import_tablespace_for_mysql( if (table->space == 0) { ut_print_timestamp(stderr); - fprintf(stderr, -" InnoDB: Error: table %s\n" -"InnoDB: is in the system tablespace 0 which cannot be imported\n", name); + fputs(" InnoDB: Error: table ", stderr); + ut_print_name(stderr, name); + fputs("\n" +"InnoDB: is in the system tablespace 0 which cannot be imported\n", stderr); err = DB_ERROR; goto funct_exit; @@ -2136,10 +2148,12 @@ row_import_tablespace_for_mysql( if (!table->tablespace_discarded) { ut_print_timestamp(stderr); - fprintf(stderr, + fputs( " InnoDB: Error: you are trying to IMPORT a tablespace\n" -"InnoDB: %s, though you have not called DISCARD on it yet\n" -"InnoDB: during the lifetime of the mysqld process!\n", name); +"InnoDB: ", stderr); + ut_print_name(stderr, name); + fputs(", though you have not called DISCARD on it yet\n" +"InnoDB: during the lifetime of the mysqld process!\n", stderr); err = DB_ERROR; @@ -2469,7 +2483,7 @@ row_drop_table_for_mysql( if (dict_load_table(name) != NULL) { ut_print_timestamp(stderr); fputs(" InnoDB: Error: not able to remove table ", - stderr); + stderr); ut_print_name(stderr, name); fputs(" from the dictionary cache!\n", stderr); err = DB_ERROR; @@ -2491,8 +2505,10 @@ row_drop_table_for_mysql( if (!success) { ut_print_timestamp(stderr); fprintf(stderr, -" InnoDB: Error: not able to delete tablespace %lu of table %s!\n", - (ulong) space_id, name); +" InnoDB: Error: not able to delete tablespace %lu of table ", + (ulong) space_id); + ut_print_name(stderr, name); + fputs("!\n", stderr); err = DB_ERROR; } } @@ -2757,15 +2773,14 @@ row_rename_table_for_mysql( err = DB_TABLE_NOT_FOUND; ut_print_timestamp(stderr); - fprintf(stderr, - " InnoDB: Error: table %s\n" - "InnoDB: does not exist in the InnoDB internal\n" + fputs(" InnoDB: Error: table ", stderr); + ut_print_name(stderr, old_name); + fputs(" does not exist in the InnoDB internal\n" "InnoDB: data dictionary though MySQL is trying to rename the table.\n" "InnoDB: Have you copied the .frm file of the table to the\n" "InnoDB: MySQL database directory from another database?\n" "InnoDB: You can look for further help from section 15.1 of\n" - "InnoDB: http://www.innodb.com/ibman.html\n", - old_name); + "InnoDB: http://www.innodb.com/ibman.php\n", stderr); goto funct_exit; } @@ -2773,12 +2788,12 @@ row_rename_table_for_mysql( err = DB_TABLE_NOT_FOUND; ut_print_timestamp(stderr); - fprintf(stderr, - " InnoDB: Error: table %s\n" - "InnoDB: does not have an .ibd file in the database directory.\n" + fputs(" InnoDB: Error: table ", stderr); + ut_print_name(stderr, old_name); + fputs( + " does not have an .ibd file in the database directory.\n" "InnoDB: You can look for further help from section 15.1 of\n" - "InnoDB: http://www.innodb.com/ibman.html\n", - old_name); + "InnoDB: http://www.innodb.com/ibman.php\n", stderr); goto funct_exit; } @@ -2905,23 +2920,25 @@ row_rename_table_for_mysql( if (err != DB_SUCCESS) { if (err == DB_DUPLICATE_KEY) { ut_print_timestamp(stderr); - fprintf(stderr, - " InnoDB: Error: table %s exists in the InnoDB internal data\n" - "InnoDB: dictionary though MySQL is trying rename table %s to it.\n" + fputs(" InnoDB: Error: table ", stderr); + ut_print_name(stderr, new_name); + fputs(" exists in the InnoDB internal data\n" + "InnoDB: dictionary though MySQL is trying rename table ", stderr); + ut_print_name(stderr, old_name); + fputs(" to it.\n" "InnoDB: Have you deleted the .frm file and not used DROP TABLE?\n" "InnoDB: You can look for further help from section 15.1 of\n" - "InnoDB: http://www.innodb.com/ibman.html\n", - new_name, old_name); - fprintf(stderr, - "InnoDB: If table %s is a temporary table #sql..., then it can be that\n" + "InnoDB: http://www.innodb.com/ibman.php\n" + "InnoDB: If table ", stderr); + ut_print_name(stderr, new_name); + fputs(" is a temporary table #sql..., then it can be that\n" "InnoDB: there are still queries running on the table, and it will be\n" - "InnoDB: dropped automatically when the queries end.\n", new_name); - fprintf(stderr, + "InnoDB: dropped automatically when the queries end.\n" "InnoDB: You can drop the orphaned table inside InnoDB by\n" "InnoDB: creating an InnoDB table with the same name in another\n" "InnoDB: database and moving the .frm file to the current database.\n" "InnoDB: Then MySQL thinks the table exists, and DROP TABLE will\n" - "InnoDB: succeed.\n"); + "InnoDB: succeed.\n", stderr); } trx->error_state = DB_SUCCESS; trx_general_rollback_for_mysql(trx, FALSE, NULL); @@ -2937,9 +2954,12 @@ row_rename_table_for_mysql( trx_general_rollback_for_mysql(trx, FALSE, NULL); trx->error_state = DB_SUCCESS; ut_print_timestamp(stderr); - fprintf(stderr, -" InnoDB: Error in table rename, cannot rename %s to %s\n", old_name, - new_name); + fputs(" InnoDB: Error in table rename, cannot rename ", + stderr); + ut_print_name(stderr, old_name); + fputs(" to ", stderr); + ut_print_name(stderr, new_name); + putc('\n', stderr); err = DB_ERROR; goto funct_exit; @@ -2958,11 +2978,14 @@ row_rename_table_for_mysql( if (err != DB_SUCCESS) { ut_print_timestamp(stderr); - fprintf(stderr, - " InnoDB: Error: in ALTER TABLE table %s\n" - "InnoDB: has or is referenced in foreign key constraints\n" - "InnoDB: which are not compatible with the new table definition.\n", - new_name); + fputs(" InnoDB: Error: in ALTER TABLE ", + stderr); + ut_print_name(stderr, new_name); + fputs("\n" + "InnoDB: has or is referenced in foreign key constraints\n" + "InnoDB: which are not compatible with the new table definition.\n", + stderr); + ut_a(dict_table_rename_in_cache(table, old_name, FALSE)); trx->error_state = DB_SUCCESS; @@ -3160,9 +3183,11 @@ row_check_table_for_mysql( ret = DB_ERROR; + fputs("Error: ", stderr); + dict_index_name_print(stderr, index); fprintf(stderr, - "Error: index %s contains %lu entries, should be %lu\n", - index->name, (ulong) n_rows, + " contains %lu entries, should be %lu\n", + (ulong) n_rows, (ulong) n_rows_in_table); } } diff --git a/myisam/mi_open.c b/myisam/mi_open.c index 562227d2f03..d03c18091aa 100644 --- a/myisam/mi_open.c +++ b/myisam/mi_open.c @@ -20,6 +20,7 @@ #include "sp_defs.h" #include "rt_index.h" #include <m_ctype.h> +#include <assert.h> #if defined(MSDOS) || defined(__WIN__) #ifdef __WIN__ diff --git a/mysql-test/include/have_geometry.inc b/mysql-test/include/have_geometry.inc new file mode 100644 index 00000000000..169c3a41ee7 --- /dev/null +++ b/mysql-test/include/have_geometry.inc @@ -0,0 +1,4 @@ +-- require r/have_geometry.require +disable_query_log; +show variables like "have_geometry"; +enable_query_log; diff --git a/mysql-test/r/have_geometry.require b/mysql-test/r/have_geometry.require new file mode 100644 index 00000000000..ba515a4bbb6 --- /dev/null +++ b/mysql-test/r/have_geometry.require @@ -0,0 +1,2 @@ +Variable_name Value +have_geometry YES diff --git a/mysql-test/r/multi_update.result b/mysql-test/r/multi_update.result index 2b312a86289..d8c70625e35 100644 --- a/mysql-test/r/multi_update.result +++ b/mysql-test/r/multi_update.result @@ -446,6 +446,7 @@ grant update on mysqltest.t1 to mysqltest_1@localhost; update t1, t2 set t1.b=1 where t1.a=t2.a; update t1, t2 set t1.b=(select t3.b from t3 where t1.a=t3.a) where t1.a=t2.a; revoke all privileges on mysqltest.t1 from mysqltest_1@localhost; +revoke all privileges on mysqltest.* from mysqltest_1@localhost; delete from mysql.user where user='mysqltest_1'; drop database mysqltest; create table t1 (a int, primary key (a)); diff --git a/mysql-test/r/subselect.result b/mysql-test/r/subselect.result index 9ad3a5a9cf2..a6ff608ab66 100644 --- a/mysql-test/r/subselect.result +++ b/mysql-test/r/subselect.result @@ -334,7 +334,7 @@ Note 1276 Field or reference 'clinic_uq' of SELECT #2 was resolved in SELECT #1 Note 1003 select test.t6.patient_uq AS `patient_uq`,test.t6.clinic_uq AS `clinic_uq` from test.t6 where exists(select test.t7.uq AS `uq`,test.t7.name AS `name` from test.t7 where (test.t7.uq = test.t6.clinic_uq)) select * from t1 where a= (select a from t2,t4 where t2.b=t4.b); ERROR 23000: Column: 'a' in field list is ambiguous -drop table if exists t1,t2,t3; +drop table t1,t2,t3; CREATE TABLE t3 (a varchar(20),b char(1) NOT NULL default '0'); INSERT INTO t3 VALUES ('W','a'),('A','c'),('J','b'); CREATE TABLE t2 (a varchar(20),b int NOT NULL default '0'); diff --git a/mysql-test/t/gis-rtree.test b/mysql-test/t/gis-rtree.test index 8e91e5891b8..817249b7e4c 100644 --- a/mysql-test/t/gis-rtree.test +++ b/mysql-test/t/gis-rtree.test @@ -1,3 +1,5 @@ +-- source include/have_geometry.inc + # # test of rtree (using with spatial data) # diff --git a/mysql-test/t/gis.test b/mysql-test/t/gis.test index ea460d5f7b0..590007caba1 100644 --- a/mysql-test/t/gis.test +++ b/mysql-test/t/gis.test @@ -1,3 +1,5 @@ +-- source include/have_geometry.inc + # # Spatial objects # diff --git a/mysql-test/t/multi_update.test b/mysql-test/t/multi_update.test index 36854551a7f..492856f9280 100644 --- a/mysql-test/t/multi_update.test +++ b/mysql-test/t/multi_update.test @@ -404,6 +404,7 @@ update t1, t2 set t1.b=1 where t1.a=t2.a; update t1, t2 set t1.b=(select t3.b from t3 where t1.a=t3.a) where t1.a=t2.a; connection root; revoke all privileges on mysqltest.t1 from mysqltest_1@localhost; +revoke all privileges on mysqltest.* from mysqltest_1@localhost; delete from mysql.user where user='mysqltest_1'; drop database mysqltest; diff --git a/mysql-test/t/subselect.test b/mysql-test/t/subselect.test index 0f461ba5277..bdefc87b3fd 100644 --- a/mysql-test/t/subselect.test +++ b/mysql-test/t/subselect.test @@ -135,7 +135,7 @@ explain extended select * from t6 where exists (select * from t7 where uq = clin select * from t1 where a= (select a from t2,t4 where t2.b=t4.b); # different tipes & group functions -drop table if exists t1,t2,t3; +drop table t1,t2,t3; CREATE TABLE t3 (a varchar(20),b char(1) NOT NULL default '0'); INSERT INTO t3 VALUES ('W','a'),('A','c'),('J','b'); diff --git a/mysql-test/t/system_mysql_db_fix.test b/mysql-test/t/system_mysql_db_fix.test index 6f3979bf66e..41fbdec84e7 100644 --- a/mysql-test/t/system_mysql_db_fix.test +++ b/mysql-test/t/system_mysql_db_fix.test @@ -74,5 +74,9 @@ DROP TABLE user; DROP TABLE func;
DROP TABLE tables_priv;
DROP TABLE columns_priv;
+DROP TABLE help_category; +DROP TABLE help_keyword; +DROP TABLE help_relation; +DROP TABLE help_topic; -- enable_query_log
diff --git a/sql/ha_myisam.cc b/sql/ha_myisam.cc index 3c7852c703a..318e0fbb507 100644 --- a/sql/ha_myisam.cc +++ b/sql/ha_myisam.cc @@ -60,13 +60,11 @@ static void mi_check_print_msg(MI_CHECK *param, const char* msg_type, DBUG_PRINT(msg_type,("message: %s",msgbuf)); -#ifndef EMBEDDED_LIBRARY - if (thd->net.vio == 0) + if (!thd->vio_ok()) { sql_print_error(msgbuf); return; } -#endif if (param->testflag & (T_CREATE_MISSING_KEYS | T_SAFE_REPAIR | T_AUTO_REPAIR)) diff --git a/sql/item.cc b/sql/item.cc index f3a13411fe3..7db1a448e55 100644 --- a/sql/item.cc +++ b/sql/item.cc @@ -753,9 +753,10 @@ void Item_param::reset() str_value.free(); else str_value.length(0); + str_value_ptr.length(0); /* - We must prevent all charset conversions unless data of str_value - has been written to the binary log. + We must prevent all charset conversions untill data has been written + to the binary log. */ str_value.set_charset(&my_charset_bin); state= NO_VALUE; @@ -866,7 +867,7 @@ String *Item_param::val_str(String* str) switch (state) { case STRING_VALUE: case LONG_DATA_VALUE: - return &str_value; + return &str_value_ptr; case REAL_VALUE: str->set(value.real, NOT_FIXED_DEC, &my_charset_bin); return str; @@ -980,6 +981,12 @@ bool Item_param::convert_str_value(THD *thd) } max_length= str_value.length(); decimals= 0; + /* + str_value_ptr is returned from val_str(). It must be not alloced + to prevent it's modification by val_str() invoker. + */ + str_value_ptr.set(str_value.ptr(), str_value.length(), + str_value.charset()); } return rc; } diff --git a/sql/item.h b/sql/item.h index ccf8e8685d0..885a34dce81 100644 --- a/sql/item.h +++ b/sql/item.h @@ -160,6 +160,31 @@ public: /* valXXX methods must return NULL or 0 or 0.0 if null_value is set. */ virtual double val()=0; virtual longlong val_int()=0; + /* + Return string representation of this item object. + + The argument to val_str() is an allocated buffer this or any + nested Item object can use to store return value of this method. + This buffer should only be used if the item itself doesn't have an + own String buffer. In case when the item maintains it's own string + buffer, it's preferrable to return it instead to minimize number of + mallocs/memcpys. + The caller of this method can modify returned string, but only in + case when it was allocated on heap, (is_alloced() is true). This + allows the caller to efficiently use a buffer allocated by a child + without having to allocate a buffer of it's own. The buffer, given + to val_str() as agrument, belongs to the caller and is later used + by the caller at it's own choosing. + A few implications from the above: + - unless you return a string object which only points to your buffer + but doesn't manages it you should be ready that it will be + modified. + - even for not allocated strings (is_alloced() == false) the caller + can change charset (see Item_func_{typecast/binary}. XXX: is this + a bug? + - still you should try to minimize data copying and return internal + object whenever possible. + */ virtual String *val_str(String*)=0; virtual Field *get_tmp_table_field() { return 0; } virtual Field *tmp_table_field(TABLE *t_arg) { return 0; } @@ -390,6 +415,9 @@ public: void print(String *str) { str->append("NULL", 4); } }; + +/* Item represents one placeholder ('?') of prepared statement */ + class Item_param :public Item { public: @@ -399,6 +427,17 @@ public: STRING_VALUE, TIME_VALUE, LONG_DATA_VALUE } state; + /* + A buffer for string and long data values. Historically all allocated + values returned from val_str() were treated as eligible to + modification. I. e. in some cases Item_func_concat can append it's + second argument to return value of the first one. Because of that we + can't return the original buffer holding string data from val_str(), + and have to have one buffer for data and another just pointing to + the data. This is the latter one and it's returned from val_str(). + Can not be declared inside the union as it's not a POD type. + */ + String str_value_ptr; union { longlong integer; diff --git a/sql/mysql_priv.h b/sql/mysql_priv.h index fb9ff5be771..368774877d0 100644 --- a/sql/mysql_priv.h +++ b/sql/mysql_priv.h @@ -918,6 +918,7 @@ extern struct my_option my_long_options[]; extern SHOW_COMP_OPTION have_isam, have_innodb, have_berkeley_db, have_example_db; extern SHOW_COMP_OPTION have_raid, have_openssl, have_symlink; extern SHOW_COMP_OPTION have_query_cache, have_berkeley_db, have_innodb; +extern SHOW_COMP_OPTION have_geometry, have_rtree_keys; extern SHOW_COMP_OPTION have_crypt; extern SHOW_COMP_OPTION have_compress; diff --git a/sql/mysqld.cc b/sql/mysqld.cc index fbe70705be3..ccdb8674bc3 100644 --- a/sql/mysqld.cc +++ b/sql/mysqld.cc @@ -378,6 +378,7 @@ CHARSET_INFO *national_charset_info, *table_alias_charset; SHOW_COMP_OPTION have_berkeley_db, have_innodb, have_isam, have_ndbcluster, have_example_db; SHOW_COMP_OPTION have_raid, have_openssl, have_symlink, have_query_cache; +SHOW_COMP_OPTION have_geometry, have_rtree_keys; SHOW_COMP_OPTION have_crypt, have_compress; /* Thread specific variables */ @@ -661,7 +662,7 @@ static void close_connections(void) break; } #ifndef __bsdi__ // Bug in BSDI kernel - if (tmp->net.vio) + if (tmp->vio_ok()) { sql_print_error(ER(ER_FORCING_CLOSE),my_progname, tmp->thread_id,tmp->user ? tmp->user : ""); @@ -5362,6 +5363,16 @@ static void mysql_init_variables(void) #else have_query_cache=SHOW_OPTION_NO; #endif +#ifdef HAVE_SPATIAL + have_geometry=SHOW_OPTION_YES; +#else + have_geometry=SHOW_OPTION_NO; +#endif +#ifdef HAVE_RTREE_KEYS + have_rtree_keys=SHOW_OPTION_YES; +#else + have_rtree_keys=SHOW_OPTION_NO; +#endif #ifdef HAVE_CRYPT have_crypt=SHOW_OPTION_YES; #else diff --git a/sql/set_var.cc b/sql/set_var.cc index b3b0153652b..1112a869515 100644 --- a/sql/set_var.cc +++ b/sql/set_var.cc @@ -643,10 +643,12 @@ struct show_var_st init_vars[]= { {"have_crypt", (char*) &have_crypt, SHOW_HAVE}, {"have_innodb", (char*) &have_innodb, SHOW_HAVE}, {"have_isam", (char*) &have_isam, SHOW_HAVE}, + {"have_geometry", (char*) &have_geometry, SHOW_HAVE}, {"have_ndbcluster", (char*) &have_ndbcluster, SHOW_HAVE}, {"have_openssl", (char*) &have_openssl, SHOW_HAVE}, {"have_query_cache", (char*) &have_query_cache, SHOW_HAVE}, {"have_raid", (char*) &have_raid, SHOW_HAVE}, + {"have_rtree_keys", (char*) &have_rtree_keys, SHOW_HAVE}, {"have_symlink", (char*) &have_symlink, SHOW_HAVE}, {"init_connect", (char*) &sys_init_connect, SHOW_SYS}, {"init_file", (char*) &opt_init_file, SHOW_CHAR_PTR}, diff --git a/sql/slave.cc b/sql/slave.cc index fa17a192b12..59af7c663e9 100644 --- a/sql/slave.cc +++ b/sql/slave.cc @@ -1386,7 +1386,7 @@ int fetch_master_table(THD *thd, const char *db_name, const char *table_name, thd->net.no_send_ok = 0; // Clear up garbage after create_table_from_dump if (!called_connected) mysql_close(mysql); - if (errmsg && thd->net.vio) + if (errmsg && thd->vio_ok()) send_error(thd, error, errmsg); DBUG_RETURN(test(error)); // Return 1 on error } diff --git a/sql/sql_class.cc b/sql/sql_class.cc index 9d368db0229..d16d1de7607 100644 --- a/sql/sql_class.cc +++ b/sql/sql_class.cc @@ -746,7 +746,7 @@ bool select_send::send_data(List<Item> &items) } } thd->sent_row_count++; - if (!thd->net.vio) + if (!thd->vio_ok()) DBUG_RETURN(0); if (!thd->net.report_error) DBUG_RETURN(protocol->write()); diff --git a/sql/sql_class.h b/sql/sql_class.h index d787dcabd00..7c8533af285 100644 --- a/sql/sql_class.h +++ b/sql/sql_class.h @@ -932,8 +932,10 @@ public: net.last_errno= 0; net.report_error= 0; } + inline bool vio_ok() const { return net.vio; } #else void clear_error(); + inline bool vio_ok() const { return true; } #endif inline void fatal_error() { diff --git a/sql/sql_show.cc b/sql/sql_show.cc index a54a6fa1a4c..6c4b65a4a70 100644 --- a/sql/sql_show.cc +++ b/sql/sql_show.cc @@ -1540,13 +1540,8 @@ void mysqld_list_processes(THD *thd,const char *user, bool verbose) while ((tmp=it++)) { struct st_my_thread_var *mysys_var; -#ifndef EMBEDDED_LIBRARY - if ((tmp->net.vio || tmp->system_thread) && - (!user || (tmp->user && !strcmp(tmp->user,user)))) -#else - if (tmp->system_thread && + if ((tmp->vio_ok() || tmp->system_thread) && (!user || (tmp->user && !strcmp(tmp->user,user)))) -#endif { thread_info *thd_info=new thread_info; diff --git a/tests/client_test.c b/tests/client_test.c index 725d794c4a5..1f80ecc9481 100644 --- a/tests/client_test.c +++ b/tests/client_test.c @@ -9670,12 +9670,12 @@ static void test_union_param() /* bind parameters */ bind[0].buffer_type= FIELD_TYPE_STRING; - bind[0].buffer= &my_val; + bind[0].buffer= (char*) &my_val; bind[0].buffer_length= 4; bind[0].length= &my_length; bind[0].is_null= (char*)&my_null; bind[1].buffer_type= FIELD_TYPE_STRING; - bind[1].buffer= &my_val; + bind[1].buffer= (char*) &my_val; bind[1].buffer_length= 4; bind[1].length= &my_length; bind[1].is_null= (char*)&my_null; @@ -9872,7 +9872,90 @@ static void test_ps_i18n() mysql_stmt_close(stmt); stmt_text= "DROP TABLE t1"; - mysql_real_query(mysql, stmt_text, strlen(stmt_text)); + rc= mysql_real_query(mysql, stmt_text, strlen(stmt_text)); + myquery(rc); + stmt_text= "SET NAMES DEFAULT"; + rc= mysql_real_query(mysql, stmt_text, strlen(stmt_text)); + myquery(rc); +} + + +static void test_bug3796() +{ + MYSQL_STMT *stmt; + MYSQL_BIND bind[1]; + const char *concat_arg0= "concat_with_"; + const int OUT_BUFF_SIZE= 30; + char out_buff[OUT_BUFF_SIZE]; + char canonical_buff[OUT_BUFF_SIZE]; + ulong out_length; + const char *stmt_text; + int rc; + + myheader("test_bug3796"); + + /* Create and fill test table */ + stmt_text= "DROP TABLE IF EXISTS t1"; + rc= mysql_real_query(mysql, stmt_text, strlen(stmt_text)); + myquery(rc); + + stmt_text= "CREATE TABLE t1 (a INT, b VARCHAR(30))"; + rc= mysql_real_query(mysql, stmt_text, strlen(stmt_text)); + myquery(rc); + + stmt_text= "INSERT INTO t1 VALUES(1,'ONE'), (2,'TWO')"; + rc= mysql_real_query(mysql, stmt_text, strlen(stmt_text)); + myquery(rc); + + /* Create statement handle and prepare it with select */ + stmt = mysql_stmt_init(mysql); + stmt_text= "SELECT concat(?, b) FROM t1"; + + rc= mysql_stmt_prepare(stmt, stmt_text, strlen(stmt_text)); + check_execute(stmt, rc); + + /* Bind input buffers */ + bzero(bind, sizeof(bind)); + + bind[0].buffer_type= MYSQL_TYPE_STRING; + bind[0].buffer= (char*) concat_arg0; + bind[0].buffer_length= strlen(concat_arg0); + + mysql_stmt_bind_param(stmt, bind); + + /* Execute the select statement */ + rc= mysql_stmt_execute(stmt); + check_execute(stmt, rc); + + bind[0].buffer= (char*) out_buff; + bind[0].buffer_length= OUT_BUFF_SIZE; + bind[0].length= &out_length; + + mysql_stmt_bind_result(stmt, bind); + + rc= mysql_stmt_fetch(stmt); + printf("Concat result: '%s'\n", out_buff); + check_execute(stmt, rc); + strcpy(canonical_buff, concat_arg0); + strcat(canonical_buff, "ONE"); + assert(strlen(canonical_buff) == out_length && + strncmp(out_buff, canonical_buff, out_length) == 0); + + rc= mysql_stmt_fetch(stmt); + check_execute(stmt, rc); + strcpy(canonical_buff + strlen(concat_arg0), "TWO"); + assert(strlen(canonical_buff) == out_length && + strncmp(out_buff, canonical_buff, out_length) == 0); + printf("Concat result: '%s'\n", out_buff); + + rc= mysql_stmt_fetch(stmt); + assert(rc == MYSQL_NO_DATA); + + mysql_stmt_close(stmt); + + stmt_text= "DROP TABLE IF EXISTS t1"; + rc= mysql_real_query(mysql, stmt_text, strlen(stmt_text)); + myquery(rc); } /* @@ -10164,6 +10247,7 @@ int main(int argc, char **argv) test_order_param(); /* ORDER BY with parameters in select list (Bug #3686 */ test_ps_i18n(); /* test for i18n support in binary protocol */ + test_bug3796(); /* test for select concat(?, <string>) */ end_time= time((time_t *)0); total_time+= difftime(end_time, start_time); |