summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rwxr-xr-xBUILD/compile-pentium-maintainer13
-rw-r--r--acconfig.h9
-rw-r--r--configure.in26
-rw-r--r--include/my_global.h6
-rw-r--r--innobase/dict/dict0load.c9
-rw-r--r--innobase/fil/fil0fil.c242
-rw-r--r--innobase/os/os0file.c47
-rw-r--r--innobase/row/row0mysql.c169
-rw-r--r--myisam/mi_open.c1
-rw-r--r--mysql-test/include/have_geometry.inc4
-rw-r--r--mysql-test/r/have_geometry.require2
-rw-r--r--mysql-test/r/multi_update.result1
-rw-r--r--mysql-test/r/subselect.result2
-rw-r--r--mysql-test/t/gis-rtree.test2
-rw-r--r--mysql-test/t/gis.test2
-rw-r--r--mysql-test/t/multi_update.test1
-rw-r--r--mysql-test/t/subselect.test2
-rw-r--r--mysql-test/t/system_mysql_db_fix.test4
-rw-r--r--sql/ha_myisam.cc4
-rw-r--r--sql/item.cc13
-rw-r--r--sql/item.h39
-rw-r--r--sql/mysql_priv.h1
-rw-r--r--sql/mysqld.cc13
-rw-r--r--sql/set_var.cc2
-rw-r--r--sql/slave.cc2
-rw-r--r--sql/sql_class.cc2
-rw-r--r--sql/sql_class.h2
-rw-r--r--sql/sql_show.cc7
-rw-r--r--tests/client_test.c90
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);