mirror of
https://github.com/MariaDB/server.git
synced 2025-01-29 10:14:19 +01:00
Merge paul@bk-internal.mysql.com:/home/bk/mysql-4.1
into teton.kitebird.com:/home/paul/mysql-4.1 sql/share/english/errmsg.txt: Auto merged sql/share/russian/errmsg.txt: Auto merged sql/share/ukrainian/errmsg.txt: Auto merged
This commit is contained in:
commit
a1def0c2ab
75 changed files with 1577 additions and 630 deletions
|
@ -361,6 +361,7 @@ libmysqld/item_func.cc
|
|||
libmysqld/item_geofunc.cc
|
||||
libmysqld/item_row.cc
|
||||
libmysqld/item_strfunc.cc
|
||||
libmysqld/item_subselect.cc
|
||||
libmysqld/item_sum.cc
|
||||
libmysqld/item_timefunc.cc
|
||||
libmysqld/item_uniq.cc
|
||||
|
@ -396,6 +397,7 @@ libmysqld/sql_command
|
|||
libmysqld/sql_crypt.cc
|
||||
libmysqld/sql_db.cc
|
||||
libmysqld/sql_delete.cc
|
||||
libmysqld/sql_derived.cc
|
||||
libmysqld/sql_do.cc
|
||||
libmysqld/sql_handler.cc
|
||||
libmysqld/sql_help.cc
|
||||
|
|
|
@ -101,8 +101,12 @@ sub main
|
|||
unlink("$destdir/PUBLIC", "$destdir/README");
|
||||
copy("$WD/Docs/MySQLEULA.txt", "$destdir");
|
||||
|
||||
# remove readline subdir
|
||||
`rm -rf $destdir/cmd-line-utils/readline`;
|
||||
# remove readline subdir and update configure accordingly
|
||||
system("rm -rf $destdir/cmd-line-utils/readline");
|
||||
unlink ("$destdir/configure") or die "Can't delete $destdir/configure: $!\n";
|
||||
`(cd $destdir ; sed -e 's!\ cmd-line-utils\/readline\/Makefile\ dnl!!g' < configure.in > configure.in.new)`;
|
||||
rename ("$destdir/configure.in.new","$destdir/configure.in") or die "Can't rename $destdir/configure.in.new: $!\n";;
|
||||
`(cd $destdir ; autoconf)`;
|
||||
|
||||
# fix file copyrights
|
||||
&fix_usage_copyright();
|
||||
|
|
|
@ -43,4 +43,5 @@ enum options_client
|
|||
OPT_PROMPT, OPT_IGN_LINES,OPT_TRANSACTION,OPT_MYSQL_PROTOCOL,
|
||||
OPT_SHARED_MEMORY_BASE_NAME, OPT_FRM, OPT_SKIP_OPTIMIZATION,
|
||||
OPT_COMPATIBLE, OPT_RECONNECT, OPT_DELIMITER, OPT_SECURE_AUTH,
|
||||
OPT_OPEN_FILES_LIMIT
|
||||
};
|
||||
|
|
|
@ -33,6 +33,7 @@ ulong server_id = 0;
|
|||
// needed by net_serv.c
|
||||
ulong bytes_sent = 0L, bytes_received = 0L;
|
||||
ulong mysqld_net_retry_count = 10L;
|
||||
ulong open_files_limit;
|
||||
uint test_flags = 0;
|
||||
static uint opt_protocol= 0;
|
||||
static FILE *result_file;
|
||||
|
@ -68,7 +69,7 @@ static MYSQL* safe_connect();
|
|||
|
||||
class Load_log_processor
|
||||
{
|
||||
char target_dir_name[MY_NFILE];
|
||||
char target_dir_name[FN_REFLEN];
|
||||
int target_dir_name_len;
|
||||
DYNAMIC_ARRAY file_names;
|
||||
|
||||
|
@ -429,6 +430,10 @@ static struct my_option my_long_options[] =
|
|||
{"read-from-remote-server", 'R', "Read binary logs from a MySQL server",
|
||||
(gptr*) &remote_opt, (gptr*) &remote_opt, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0,
|
||||
0, 0},
|
||||
{"open_files_limit", OPT_OPEN_FILES_LIMIT,
|
||||
"Used to reserve file descriptors for usage by this program",
|
||||
(gptr*) &open_files_limit, (gptr*) &open_files_limit, 0, GET_ULONG,
|
||||
REQUIRED_ARG, MY_NFILE, 8, OS_FILE_LIMIT, 0, 1, 0},
|
||||
{"short-form", 's', "Just show the queries, no extra info.",
|
||||
(gptr*) &short_form, (gptr*) &short_form, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0,
|
||||
0, 0},
|
||||
|
@ -878,6 +883,7 @@ int main(int argc, char** argv)
|
|||
exit(1);
|
||||
}
|
||||
|
||||
my_set_max_open_files(open_files_limit);
|
||||
if (remote_opt)
|
||||
mysql = safe_connect();
|
||||
|
||||
|
@ -915,6 +921,7 @@ int main(int argc, char** argv)
|
|||
mysql_close(mysql);
|
||||
cleanup();
|
||||
free_defaults(defaults_argv);
|
||||
my_free_open_file_info();
|
||||
my_end(0);
|
||||
exit(exit_value);
|
||||
DBUG_RETURN(exit_value); // Keep compilers happy
|
||||
|
|
39
configure.in
39
configure.in
|
@ -1824,29 +1824,32 @@ AC_TYPE_SIGNAL
|
|||
MYSQL_TYPE_QSORT
|
||||
AC_FUNC_UTIME_NULL
|
||||
AC_FUNC_VPRINTF
|
||||
AC_CHECK_FUNCS(alarm bmove \
|
||||
chsize ftruncate rint finite isnan fpsetmask fpresetsticky\
|
||||
cuserid fcntl fconvert poll \
|
||||
getrusage getpwuid getcwd getrlimit getwd index stpcpy locking longjmp \
|
||||
perror pread realpath readlink rename \
|
||||
socket strnlen madvise mallinfo mkstemp \
|
||||
strtol strtoul strtoll strtoull snprintf tempnam thr_setconcurrency \
|
||||
gethostbyaddr_r gethostbyname_r getpwnam \
|
||||
bfill bzero bcmp strstr strpbrk strerror \
|
||||
tell isinf memcpy memmove \
|
||||
setupterm strcasecmp sighold vidattr lrand48 localtime_r gmtime_r \
|
||||
sigset sigthreadmask pthread_sigmask pthread_setprio pthread_setprio_np \
|
||||
pthread_setschedparam pthread_attr_setprio pthread_attr_setschedparam \
|
||||
pthread_attr_create pthread_getsequence_np pthread_attr_setstacksize \
|
||||
pthread_attr_getstacksize pthread_key_delete \
|
||||
pthread_condattr_create rwlock_init pthread_rwlock_rdlock \
|
||||
fsync fdatasync fchmod getpass getpassphrase initgroups mlockall)
|
||||
|
||||
AC_CHECK_FUNCS(alarm bcmp bfill bmove bzero chsize cuserid fchmod fcntl \
|
||||
fconvert fdatasync finite fpresetsticky fpsetmask fsync ftruncate \
|
||||
getcwd gethostbyaddr_r gethostbyname_r getpass getpassphrase getpwnam \
|
||||
getpwuid getrlimit getrusage getwd gmtime_r index initgroups isnan \
|
||||
localtime_r locking longjmp lrand48 madvise mallinfo memcpy memmove \
|
||||
mkstemp mlockall perror poll pread pthread_attr_create \
|
||||
pthread_attr_getstacksize pthread_attr_setprio pthread_attr_setschedparam \
|
||||
pthread_attr_setstacksize pthread_condattr_create pthread_getsequence_np \
|
||||
pthread_key_delete pthread_rwlock_rdlock pthread_setprio \
|
||||
pthread_setprio_np pthread_setschedparam pthread_sigmask readlink \
|
||||
realpath rename rint rwlock_init setupterm sighold sigset sigthreadmask \
|
||||
snprintf socket stpcpy strcasecmp strerror strnlen strpbrk strstr strtol \
|
||||
strtoll strtoul strtoull tell tempnam thr_setconcurrency vidattr)
|
||||
|
||||
# isinf() could be a function or a macro (HPUX)
|
||||
AC_MSG_CHECKING(for isinf with <math.h>)
|
||||
AC_TRY_LINK([#include <math.h>], [float f = 0.0; isinf(f)],
|
||||
AC_MSG_RESULT(yes) AC_DEFINE(HAVE_ISINF,,[isinf() macro or function]),
|
||||
AC_MSG_RESULT(no))
|
||||
|
||||
CFLAGS="$ORG_CFLAGS"
|
||||
|
||||
# Sanity check: We chould not have any fseeko symbol unless
|
||||
# large_file_support=yes
|
||||
AC_CHECK_FUNCS(fseeko,
|
||||
AC_CHECK_FUNC(fseeko,
|
||||
[if test "$large_file_support" = no -a "$IS_LINUX" = "true";
|
||||
then
|
||||
AC_MSG_ERROR("Found fseeko symbol but large_file_support is not enabled!");
|
||||
|
|
|
@ -323,7 +323,7 @@ inline double ulonglong2double(ulonglong value)
|
|||
#define FN_ROOTDIR "\\"
|
||||
#define FN_NETWORK_DRIVES /* Uses \\ to indicate network drives */
|
||||
#define FN_NO_CASE_SENCE /* Files are not case-sensitive */
|
||||
#define MY_NFILE 1024
|
||||
#define OS_FILE_LIMIT 2048
|
||||
|
||||
#define DO_NOT_REMOVE_THREAD_WRAPPERS
|
||||
#define thread_safe_increment(V,L) InterlockedIncrement((long*) &(V))
|
||||
|
|
|
@ -52,7 +52,7 @@ extern const char *ft_precompiled_stopwords[];
|
|||
extern ulong ft_min_word_len;
|
||||
extern ulong ft_max_word_len;
|
||||
extern ulong ft_query_expansion_limit;
|
||||
extern const char *ft_boolean_syntax;
|
||||
extern char ft_boolean_syntax[15];
|
||||
|
||||
int ft_init_stopwords(void);
|
||||
void ft_free_stopwords(void);
|
||||
|
@ -63,6 +63,7 @@ void ft_free_stopwords(void);
|
|||
#define FT_EXPAND 4 /* query expansion */
|
||||
|
||||
FT_INFO *ft_init_search(uint,void *, uint, byte *, uint, byte *);
|
||||
my_bool ft_boolean_check_syntax_string(const byte *);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
|
|
@ -384,8 +384,8 @@ typedef unsigned short ushort;
|
|||
#define sgn(a) (((a) < 0) ? -1 : ((a) > 0) ? 1 : 0)
|
||||
#define swap(t,a,b) { register t dummy; dummy = a; a = b; b = dummy; }
|
||||
#define test(a) ((a) ? 1 : 0)
|
||||
#define set_if_bigger(a,b) { if ((a) < (b)) (a)=(b); }
|
||||
#define set_if_smaller(a,b) { if ((a) > (b)) (a)=(b); }
|
||||
#define set_if_bigger(a,b) do { if ((a) < (b)) (a)=(b); } while(0)
|
||||
#define set_if_smaller(a,b) do { if ((a) > (b)) (a)=(b); } while(0)
|
||||
#define test_all_bits(a,b) (((a) & (b)) == (b))
|
||||
#define set_bits(type, bit_count) (sizeof(type)*8 <= (bit_count) ? ~(type) 0 : ((((type) 1) << (bit_count)) - (type) 1))
|
||||
#define array_elements(A) ((uint) (sizeof(A)/sizeof(A[0])))
|
||||
|
@ -535,7 +535,10 @@ typedef SOCKET_SIZE_TYPE size_socket;
|
|||
#define FN_LIBCHAR '/'
|
||||
#define FN_ROOTDIR "/"
|
||||
#endif
|
||||
#define MY_NFILE 1024 /* This is only used to save filenames */
|
||||
#endif
|
||||
#define MY_NFILE 64 /* This is only used to save filenames */
|
||||
#ifndef OS_FILE_LIMIT
|
||||
#define OS_FILE_LIMIT 65535
|
||||
#endif
|
||||
|
||||
/* #define EXT_IN_LIBNAME */
|
||||
|
|
|
@ -202,26 +202,13 @@ extern char NEAR curr_dir[]; /* Current directory for user */
|
|||
extern int (*error_handler_hook)(uint my_err, const char *str,myf MyFlags);
|
||||
extern int (*fatal_error_handler_hook)(uint my_err, const char *str,
|
||||
myf MyFlags);
|
||||
extern uint my_file_limit;
|
||||
|
||||
/* charsets */
|
||||
extern CHARSET_INFO *default_charset_info;
|
||||
extern CHARSET_INFO *all_charsets[256];
|
||||
extern CHARSET_INFO compiled_charsets[];
|
||||
|
||||
extern uint get_charset_number(const char *cs_name, uint cs_flags);
|
||||
extern uint get_collation_number(const char *name);
|
||||
extern const char *get_charset_name(uint cs_number);
|
||||
|
||||
extern CHARSET_INFO *get_charset(uint cs_number, myf flags);
|
||||
extern CHARSET_INFO *get_charset_by_name(const char *cs_name, myf flags);
|
||||
extern CHARSET_INFO *get_charset_by_csname(const char *cs_name,
|
||||
uint cs_flags, myf my_flags);
|
||||
extern void free_charsets(void);
|
||||
extern char *get_charsets_dir(char *buf);
|
||||
extern my_bool my_charset_same(CHARSET_INFO *cs1, CHARSET_INFO *cs2);
|
||||
extern my_bool init_compiled_charsets(myf flags);
|
||||
extern void add_compiled_collation(CHARSET_INFO *cs);
|
||||
|
||||
/* statistics */
|
||||
extern ulong my_cache_w_requests, my_cache_write, my_cache_r_requests,
|
||||
my_cache_read;
|
||||
|
@ -288,14 +275,16 @@ enum file_type
|
|||
FILE_BY_MKSTEMP, FILE_BY_DUP
|
||||
};
|
||||
|
||||
extern struct my_file_info
|
||||
struct st_my_file_info
|
||||
{
|
||||
my_string name;
|
||||
enum file_type type;
|
||||
#if defined(THREAD) && !defined(HAVE_PREAD)
|
||||
pthread_mutex_t mutex;
|
||||
#endif
|
||||
} my_file_info[MY_NFILE];
|
||||
};
|
||||
|
||||
extern struct st_my_file_info *my_file_info;
|
||||
|
||||
typedef struct st_my_tmpdir
|
||||
{
|
||||
|
@ -747,6 +736,23 @@ extern uint my_bit_log2(ulong value);
|
|||
extern uint my_count_bits(ulonglong v);
|
||||
extern void my_sleep(ulong m_seconds);
|
||||
extern ulong crc32(ulong crc, const uchar *buf, uint len);
|
||||
extern uint my_set_max_open_files(uint files);
|
||||
void my_free_open_file_info(void);
|
||||
|
||||
/* character sets */
|
||||
extern uint get_charset_number(const char *cs_name, uint cs_flags);
|
||||
extern uint get_collation_number(const char *name);
|
||||
extern const char *get_charset_name(uint cs_number);
|
||||
|
||||
extern CHARSET_INFO *get_charset(uint cs_number, myf flags);
|
||||
extern CHARSET_INFO *get_charset_by_name(const char *cs_name, myf flags);
|
||||
extern CHARSET_INFO *get_charset_by_csname(const char *cs_name,
|
||||
uint cs_flags, myf my_flags);
|
||||
extern void free_charsets(void);
|
||||
extern char *get_charsets_dir(char *buf);
|
||||
extern my_bool my_charset_same(CHARSET_INFO *cs1, CHARSET_INFO *cs2);
|
||||
extern my_bool init_compiled_charsets(myf flags);
|
||||
extern void add_compiled_collation(CHARSET_INFO *cs);
|
||||
|
||||
#ifdef __WIN__
|
||||
extern my_bool have_tcpip; /* Is set if tcpip is used */
|
||||
|
|
|
@ -12,7 +12,15 @@ Created 1/16/1996 Heikki Tuuri
|
|||
#include "data0type.ic"
|
||||
#endif
|
||||
|
||||
dtype_t dtype_binary_val = {DATA_BINARY, 0, 0, 0, 0};
|
||||
/* At the database startup we store the default-charset collation number of
|
||||
this MySQL installation to this global variable. If we have < 4.1.2 format
|
||||
column definitions, or records in the insert buffer, we use this
|
||||
charset-collation code for them. */
|
||||
|
||||
ulint data_mysql_default_charset_coll = 99999999;
|
||||
ulint data_mysql_latin1_swedish_charset_coll = 99999999;
|
||||
|
||||
dtype_t dtype_binary_val = {DATA_BINARY, 0, 0, 0};
|
||||
dtype_t* dtype_binary = &dtype_binary_val;
|
||||
|
||||
/*************************************************************************
|
||||
|
|
|
@ -1315,7 +1315,7 @@ loop:
|
|||
|
||||
if (error == DB_DUPLICATE_KEY) {
|
||||
mutex_enter(&dict_foreign_err_mutex);
|
||||
ut_sprintf_timestamp(dict_foreign_err_buf);
|
||||
ut_sprintf_timestamp(ebuf);
|
||||
sprintf(ebuf + strlen(ebuf),
|
||||
" Error in foreign key constraint creation for table %.500s.\n"
|
||||
"A foreign key constraint of name %.500s\n"
|
||||
|
|
|
@ -360,6 +360,15 @@ dict_load_columns(
|
|||
field = rec_get_nth_field(rec, 6, &len);
|
||||
prtype = mach_read_from_4(field);
|
||||
|
||||
if (dtype_is_non_binary_string_type(mtype, prtype)
|
||||
&& dtype_get_charset_coll(prtype) == 0) {
|
||||
/* This is a non-binary string type, and the table
|
||||
was created with < 4.1.2. Use the default charset. */
|
||||
|
||||
prtype = dtype_form_prtype(prtype,
|
||||
data_mysql_default_charset_coll);
|
||||
}
|
||||
|
||||
field = rec_get_nth_field(rec, 7, &len);
|
||||
col_len = mach_read_from_4(field);
|
||||
|
||||
|
|
|
@ -11,6 +11,9 @@ Created 1/16/1996 Heikki Tuuri
|
|||
|
||||
#include "univ.i"
|
||||
|
||||
extern ulint data_mysql_default_charset_coll;
|
||||
extern ulint data_mysql_latin1_swedish_charset_coll;
|
||||
|
||||
/* SQL data type struct */
|
||||
typedef struct dtype_struct dtype_t;
|
||||
|
||||
|
@ -18,31 +21,79 @@ typedef struct dtype_struct dtype_t;
|
|||
data type */
|
||||
extern dtype_t* dtype_binary;
|
||||
|
||||
/* Data main types of SQL data */
|
||||
#define DATA_VARCHAR 1 /* character varying */
|
||||
#define DATA_CHAR 2 /* fixed length character */
|
||||
/*-------------------------------------------*/
|
||||
/* The 'MAIN TYPE' of a column */
|
||||
#define DATA_VARCHAR 1 /* character varying of the
|
||||
latin1_swedish_ci charset-collation */
|
||||
#define DATA_CHAR 2 /* fixed length character of the
|
||||
latin1_swedish_ci charset-collation */
|
||||
#define DATA_FIXBINARY 3 /* binary string of fixed length */
|
||||
#define DATA_BINARY 4 /* binary string */
|
||||
#define DATA_BLOB 5 /* binary large object, or a TEXT type; if
|
||||
prtype & DATA_NONLATIN1 != 0 the data must
|
||||
be compared by MySQL as a whole field; if
|
||||
prtype & DATA_BINARY_TYPE == 0, then this is
|
||||
actually a TEXT column */
|
||||
#define DATA_BLOB 5 /* binary large object, or a TEXT type;
|
||||
if prtype & DATA_BINARY_TYPE == 0, then this is
|
||||
actually a TEXT column (or a BLOB created
|
||||
with < 4.0.14) */
|
||||
#define DATA_INT 6 /* integer: can be any size 1 - 8 bytes */
|
||||
#define DATA_SYS_CHILD 7 /* address of the child page in node pointer */
|
||||
#define DATA_SYS 8 /* system column */
|
||||
|
||||
/* Data types >= DATA_FLOAT must be compared using the whole field, not as
|
||||
binary strings */
|
||||
|
||||
#define DATA_FLOAT 9
|
||||
#define DATA_DOUBLE 10
|
||||
#define DATA_DECIMAL 11 /* decimal number stored as an ASCII string */
|
||||
#define DATA_VARMYSQL 12 /* non-latin1 varying length char */
|
||||
#define DATA_MYSQL 13 /* non-latin1 fixed length char */
|
||||
#define DATA_VARMYSQL 12 /* any charset varying length char */
|
||||
#define DATA_MYSQL 13 /* any charset fixed length char */
|
||||
/* NOTE that 4.1.1 used DATA_MYSQL and
|
||||
DATA_VARMYSQL for all character sets, and the
|
||||
charset-collation for tables created with it
|
||||
can also be latin1_swedish_ci */
|
||||
#define DATA_MTYPE_MAX 63 /* dtype_store_for_order_and_null_size()
|
||||
requires the values are <= 63 */
|
||||
/*-------------------------------------------*/
|
||||
/* In the lowest byte in the precise type we store the MySQL type code
|
||||
(not applicable for system columns). */
|
||||
/* The 'PRECISE TYPE' of a column */
|
||||
/*
|
||||
Tables created by a MySQL user have the following convention:
|
||||
|
||||
- In the least significant byte in the precise type we store the MySQL type
|
||||
code (not applicable for system columns).
|
||||
|
||||
- In the second least significant byte we OR flags DATA_NOT_NULL,
|
||||
DATA_UNSIGNED, DATA_BINARY_TYPE.
|
||||
|
||||
- In the third least significant byte of the precise type of string types we
|
||||
store the MySQL charset-collation code. In DATA_BLOB columns created with
|
||||
< 4.0.14 we do not actually know if it is a BLOB or a TEXT column. Since there
|
||||
are no indexes on prefixes of BLOB or TEXT columns in < 4.0.14, this is no
|
||||
problem, though.
|
||||
|
||||
Note that versions < 4.1.2 or < 5.0.1 did not store the charset code to the
|
||||
precise type, since the charset was always the default charset of the MySQL
|
||||
installation. If the stored charset code is 0 in the system table SYS_COLUMNS
|
||||
of InnoDB, that means that the default charset of this MySQL installation
|
||||
should be used.
|
||||
|
||||
When loading a table definition from the system tables to the InnoDB data
|
||||
dictionary cache in main memory, InnoDB versions >= 4.1.2 and >= 5.0.1 check
|
||||
if the stored charset-collation is 0, and if that is the case and the type is
|
||||
a non-binary string, replace that 0 by the default charset-collation code of
|
||||
this MySQL installation. In short, in old tables, the charset-collation code
|
||||
in the system tables on disk can be 0, but in in-memory data structures
|
||||
(dtype_t), the charset-collation code is always != 0 for non-binary string
|
||||
types.
|
||||
|
||||
In new tables, in binary string types, the charset-collation code is the
|
||||
MySQL code for the 'binary charset', that is, != 0.
|
||||
|
||||
For binary string types and for DATA_CHAR, DATA_VARCHAR, and for those
|
||||
DATA_BLOB which are binary or have the charset-collation latin1_swedish_ci,
|
||||
InnoDB performs all comparisons internally, without resorting to the MySQL
|
||||
comparison functions. This is to save CPU time.
|
||||
|
||||
InnoDB's own internal system tables have different precise types for their
|
||||
columns, and for them the precise type is usually not used at all.
|
||||
*/
|
||||
|
||||
#define DATA_ENGLISH 4 /* English language character string: this
|
||||
is a relic from pre-MySQL time and only used
|
||||
|
@ -69,7 +120,7 @@ be less than 256 */
|
|||
#define DATA_MIX_ID_LEN 9 /* maximum stored length for mix id (in a
|
||||
compressed dulint form) */
|
||||
#define DATA_N_SYS_COLS 4 /* number of system columns defined above */
|
||||
/*-------------------------------------------*/
|
||||
|
||||
/* Flags ORed to the precise data type */
|
||||
#define DATA_NOT_NULL 256 /* this is ORed to the precise type when
|
||||
the column is declared as NOT NULL */
|
||||
|
@ -79,19 +130,53 @@ be less than 256 */
|
|||
string, this is ORed to the precise type:
|
||||
this only holds for tables created with
|
||||
>= MySQL-4.0.14 */
|
||||
#define DATA_NONLATIN1 2048 /* if the data type is a DATA_BLOB (actually
|
||||
TEXT) of a non-latin1 type, this is ORed to
|
||||
the precise type: this only holds for tables
|
||||
created with >= MySQL-4.0.14 */
|
||||
/* #define DATA_NONLATIN1 2048 This is a relic from < 4.1.2 and < 5.0.1.
|
||||
In earlier versions this was set for some
|
||||
BLOB columns.
|
||||
*/
|
||||
/*-------------------------------------------*/
|
||||
|
||||
/* This many bytes we need to store the type information affecting the
|
||||
alphabetical order for a single field and decide the storage size of an
|
||||
SQL null*/
|
||||
#define DATA_ORDER_NULL_TYPE_BUF_SIZE 4
|
||||
/* In the >= 4.1.x storage format we need 2 bytes more for the charset */
|
||||
#define DATA_ORDER_NULL_TYPE_BUF_SIZE 4
|
||||
/* In the >= 4.1.x storage format we add 2 bytes more so that we can also
|
||||
store the charset-collation number; one byte is left unused, though */
|
||||
#define DATA_NEW_ORDER_NULL_TYPE_BUF_SIZE 6
|
||||
|
||||
/*************************************************************************
|
||||
Checks if a data main type is a string type. Also a BLOB is considered a
|
||||
string type. */
|
||||
UNIV_INLINE
|
||||
ibool
|
||||
dtype_is_string_type(
|
||||
/*=================*/
|
||||
/* out: TRUE if string type */
|
||||
ulint mtype); /* in: InnoDB main data type code: DATA_CHAR, ... */
|
||||
/*************************************************************************
|
||||
Checks if a type is a binary string type. Note that for tables created with
|
||||
< 4.0.14, we do not know if a DATA_BLOB column is a BLOB or a TEXT column. For
|
||||
those DATA_BLOB columns this function currently returns FALSE. */
|
||||
UNIV_INLINE
|
||||
ibool
|
||||
dtype_is_binary_string_type(
|
||||
/*========================*/
|
||||
/* out: TRUE if binary string type */
|
||||
ulint mtype, /* in: main data type */
|
||||
ulint prtype);/* in: precise type */
|
||||
/*************************************************************************
|
||||
Checks if a type is a non-binary string type. That is, dtype_is_string_type is
|
||||
TRUE and dtype_is_binary_string_type is FALSE. Note that for tables created
|
||||
with < 4.0.14, we do not know if a DATA_BLOB column is a BLOB or a TEXT column.
|
||||
For those DATA_BLOB columns this function currently returns TRUE. */
|
||||
|
||||
UNIV_INLINE
|
||||
ibool
|
||||
dtype_is_non_binary_string_type(
|
||||
/*============================*/
|
||||
/* out: TRUE if non-binary string type */
|
||||
ulint mtype, /* in: main data type */
|
||||
ulint prtype);/* in: precise type */
|
||||
/*************************************************************************
|
||||
Sets a data type structure. */
|
||||
UNIV_INLINE
|
||||
|
@ -126,6 +211,22 @@ dtype_get_prtype(
|
|||
/*=============*/
|
||||
dtype_t* type);
|
||||
/*************************************************************************
|
||||
Gets the MySQL charset-collation code for MySQL string types. */
|
||||
UNIV_INLINE
|
||||
ulint
|
||||
dtype_get_charset_coll(
|
||||
/*===================*/
|
||||
ulint prtype);/* in: precise data type */
|
||||
/*************************************************************************
|
||||
Forms a precise type from the < 4.1.2 format precise type plus the
|
||||
charset-collation code. */
|
||||
ulint
|
||||
dtype_form_prtype(
|
||||
/*==============*/
|
||||
ulint old_prtype, /* in: the MySQL type code and the flags
|
||||
DATA_BINARY_TYPE etc. */
|
||||
ulint charset_coll); /* in: MySQL charset-collation code */
|
||||
/*************************************************************************
|
||||
Gets the type length. */
|
||||
UNIV_INLINE
|
||||
ulint
|
||||
|
@ -225,9 +326,8 @@ dtype_print(
|
|||
struct dtype_struct{
|
||||
ulint mtype; /* main data type */
|
||||
ulint prtype; /* precise type; MySQL data type */
|
||||
ulint chrset; /* MySQL character set code */
|
||||
|
||||
/* remaining two fields do not affect alphabetical ordering: */
|
||||
/* the remaining two fields do not affect alphabetical ordering: */
|
||||
|
||||
ulint len; /* length */
|
||||
ulint prec; /* precision */
|
||||
|
|
|
@ -8,6 +8,70 @@ Created 1/16/1996 Heikki Tuuri
|
|||
|
||||
#include "mach0data.h"
|
||||
|
||||
/*************************************************************************
|
||||
Checks if a data main type is a string type. Also a BLOB is considered a
|
||||
string type. */
|
||||
|
||||
ibool
|
||||
dtype_is_string_type(
|
||||
/*=================*/
|
||||
/* out: TRUE if string type */
|
||||
ulint mtype) /* in: InnoDB main data type code: DATA_CHAR, ... */
|
||||
{
|
||||
if (mtype <= DATA_BLOB
|
||||
|| mtype == DATA_MYSQL
|
||||
|| mtype == DATA_VARMYSQL) {
|
||||
|
||||
return(TRUE);
|
||||
}
|
||||
|
||||
return(FALSE);
|
||||
}
|
||||
|
||||
/*************************************************************************
|
||||
Checks if a type is a binary string type. Note that for tables created with
|
||||
< 4.0.14, we do not know if a DATA_BLOB column is a BLOB or a TEXT column. For
|
||||
those DATA_BLOB columns this function currently returns FALSE. */
|
||||
UNIV_INLINE
|
||||
ibool
|
||||
dtype_is_binary_string_type(
|
||||
/*========================*/
|
||||
/* out: TRUE if binary string type */
|
||||
ulint mtype, /* in: main data type */
|
||||
ulint prtype) /* in: precise type */
|
||||
{
|
||||
if ((mtype == DATA_FIXBINARY)
|
||||
|| (mtype == DATA_BINARY)
|
||||
|| (mtype == DATA_BLOB && (prtype & DATA_BINARY_TYPE))) {
|
||||
|
||||
return(TRUE);
|
||||
}
|
||||
|
||||
return(FALSE);
|
||||
}
|
||||
|
||||
/*************************************************************************
|
||||
Checks if a type is a non-binary string type. That is, dtype_is_string_type is
|
||||
TRUE and dtype_is_binary_string_type is FALSE. Note that for tables created
|
||||
with < 4.0.14, we do not know if a DATA_BLOB column is a BLOB or a TEXT column.
|
||||
For those DATA_BLOB columns this function currently returns TRUE. */
|
||||
UNIV_INLINE
|
||||
ibool
|
||||
dtype_is_non_binary_string_type(
|
||||
/*============================*/
|
||||
/* out: TRUE if non-binary string type */
|
||||
ulint mtype, /* in: main data type */
|
||||
ulint prtype) /* in: precise type */
|
||||
{
|
||||
if (dtype_is_string_type(mtype) == TRUE
|
||||
&& dtype_is_binary_string_type(mtype, prtype) == FALSE) {
|
||||
|
||||
return(TRUE);
|
||||
}
|
||||
|
||||
return(FALSE);
|
||||
}
|
||||
|
||||
/*************************************************************************
|
||||
Sets a data type structure. */
|
||||
UNIV_INLINE
|
||||
|
@ -27,7 +91,6 @@ dtype_set(
|
|||
type->prtype = prtype;
|
||||
type->len = len;
|
||||
type->prec = prec;
|
||||
type->chrset = 0;
|
||||
|
||||
ut_ad(dtype_validate(type));
|
||||
}
|
||||
|
@ -72,6 +135,33 @@ dtype_get_prtype(
|
|||
return(type->prtype);
|
||||
}
|
||||
|
||||
/*************************************************************************
|
||||
Gets the MySQL charset-collation code for MySQL string types. */
|
||||
UNIV_INLINE
|
||||
ulint
|
||||
dtype_get_charset_coll(
|
||||
/*===================*/
|
||||
ulint prtype) /* in: precise data type */
|
||||
{
|
||||
return((prtype >> 16) & 0xFFUL);
|
||||
}
|
||||
|
||||
/*************************************************************************
|
||||
Forms a precise type from the < 4.1.2 format precise type plus the
|
||||
charset-collation code. */
|
||||
ulint
|
||||
dtype_form_prtype(
|
||||
/*==============*/
|
||||
ulint old_prtype, /* in: the MySQL type code and the flags
|
||||
DATA_BINARY_TYPE etc. */
|
||||
ulint charset_coll) /* in: MySQL charset-collation code */
|
||||
{
|
||||
ut_a(old_prtype < 256 * 256);
|
||||
ut_a(charset_coll < 256);
|
||||
|
||||
return(old_prtype + (charset_coll << 16));
|
||||
}
|
||||
|
||||
/*************************************************************************
|
||||
Gets the type length. */
|
||||
UNIV_INLINE
|
||||
|
@ -147,20 +237,25 @@ dtype_new_store_for_order_and_null_size(
|
|||
buf[0] = buf[0] | 128;
|
||||
}
|
||||
|
||||
if (type->prtype & DATA_NONLATIN1) {
|
||||
buf[0] = buf[0] | 64;
|
||||
}
|
||||
/* In versions < 4.1.2 we had: if (type->prtype & DATA_NONLATIN1) {
|
||||
buf[0] = buf[0] | 64;
|
||||
}
|
||||
*/
|
||||
|
||||
buf[1] = (byte)(type->prtype & 0xFFUL);
|
||||
|
||||
mach_write_to_2(buf + 2, type->len & 0xFFFFUL);
|
||||
|
||||
mach_write_to_2(buf + 4, type->chrset & 0xFFFFUL);
|
||||
mach_write_to_2(buf + 4, dtype_get_charset_coll(type->prtype));
|
||||
|
||||
/* Note that the second last byte is left unused, because the
|
||||
charset-collation code is always < 256 */
|
||||
}
|
||||
|
||||
/**************************************************************************
|
||||
Reads to a type the stored information which determines its alphabetical
|
||||
ordering and the storage size of an SQL NULL value. */
|
||||
ordering and the storage size of an SQL NULL value. This is the < 4.1.x
|
||||
storage format. */
|
||||
UNIV_INLINE
|
||||
void
|
||||
dtype_read_for_order_and_null_size(
|
||||
|
@ -177,17 +272,16 @@ dtype_read_for_order_and_null_size(
|
|||
type->prtype = type->prtype | DATA_BINARY_TYPE;
|
||||
}
|
||||
|
||||
if (buf[0] & 64) {
|
||||
type->prtype = type->prtype | DATA_NONLATIN1;
|
||||
}
|
||||
|
||||
type->len = mach_read_from_2(buf + 2);
|
||||
|
||||
type->prtype = dtype_form_prtype(type->prtype,
|
||||
data_mysql_default_charset_coll);
|
||||
}
|
||||
|
||||
/**************************************************************************
|
||||
Reads to a type the stored information which determines its alphabetical
|
||||
ordering and the storage size of an SQL NULL value. This is the 4.1.x storage
|
||||
format. */
|
||||
ordering and the storage size of an SQL NULL value. This is the >= 4.1.x
|
||||
storage format. */
|
||||
UNIV_INLINE
|
||||
void
|
||||
dtype_new_read_for_order_and_null_size(
|
||||
|
@ -195,6 +289,8 @@ dtype_new_read_for_order_and_null_size(
|
|||
dtype_t* type, /* in: type struct */
|
||||
byte* buf) /* in: buffer for stored type order info */
|
||||
{
|
||||
ulint charset_coll;
|
||||
|
||||
ut_ad(6 == DATA_NEW_ORDER_NULL_TYPE_BUF_SIZE);
|
||||
|
||||
type->mtype = buf[0] & 63;
|
||||
|
@ -204,14 +300,28 @@ dtype_new_read_for_order_and_null_size(
|
|||
type->prtype = type->prtype | DATA_BINARY_TYPE;
|
||||
}
|
||||
|
||||
if (buf[0] & 64) {
|
||||
type->prtype = type->prtype | DATA_NONLATIN1;
|
||||
}
|
||||
|
||||
type->len = mach_read_from_2(buf + 2);
|
||||
|
||||
type->chrset = mach_read_from_2(buf + 4);
|
||||
}
|
||||
mach_read_from_2(buf + 4);
|
||||
|
||||
charset_coll = mach_read_from_2(buf + 4);
|
||||
|
||||
if (dtype_is_string_type(type->mtype)) {
|
||||
ut_a(charset_coll < 256);
|
||||
|
||||
if (charset_coll == 0) {
|
||||
/* This insert buffer record was inserted with MySQL
|
||||
version < 4.1.2, and the charset-collation code was not
|
||||
explicitly stored to dtype->prtype at that time. It
|
||||
must be the default charset-collation of this MySQL
|
||||
installation. */
|
||||
|
||||
charset_coll = data_mysql_default_charset_coll;
|
||||
}
|
||||
|
||||
type->prtype = dtype_form_prtype(type->prtype, charset_coll);
|
||||
}
|
||||
}
|
||||
|
||||
/***************************************************************************
|
||||
Returns the size of a fixed size data type, 0 if not a fixed size type. */
|
||||
|
|
|
@ -61,10 +61,11 @@ must be a copy of the the one in ha_innobase.cc! */
|
|||
|
||||
int
|
||||
innobase_mysql_cmp(
|
||||
/*===============*/
|
||||
/*===============*/
|
||||
/* out: 1, 0, -1, if a is greater,
|
||||
equal, less than b, respectively */
|
||||
int mysql_type, /* in: MySQL type */
|
||||
int mysql_type, /* in: MySQL type */
|
||||
uint charset_number, /* in: number of the charset */
|
||||
unsigned char* a, /* in: data field */
|
||||
unsigned int a_length, /* in: data field length,
|
||||
not UNIV_SQL_NULL */
|
||||
|
@ -97,16 +98,28 @@ cmp_types_are_equal(
|
|||
dtype_t* type1, /* in: type 1 */
|
||||
dtype_t* type2) /* in: type 2 */
|
||||
{
|
||||
if ((type1->mtype == DATA_VARCHAR && type2->mtype == DATA_CHAR)
|
||||
|| (type1->mtype == DATA_CHAR && type2->mtype == DATA_VARCHAR)
|
||||
|| (type1->mtype == DATA_FIXBINARY && type2->mtype == DATA_BINARY)
|
||||
|| (type1->mtype == DATA_BINARY && type2->mtype == DATA_FIXBINARY)
|
||||
|| (type1->mtype == DATA_MYSQL && type2->mtype == DATA_VARMYSQL)
|
||||
|| (type1->mtype == DATA_VARMYSQL && type2->mtype == DATA_MYSQL)) {
|
||||
if (dtype_is_non_binary_string_type(type1->mtype, type1->prtype)
|
||||
&& dtype_is_non_binary_string_type(type2->mtype, type2->prtype)) {
|
||||
|
||||
return(TRUE);
|
||||
/* Both are non-binary string types: they can be compared if
|
||||
and only if the charset-collation is the same */
|
||||
|
||||
if (dtype_get_charset_coll(type1->prtype)
|
||||
== dtype_get_charset_coll(type2->prtype)) {
|
||||
return(TRUE);
|
||||
}
|
||||
|
||||
return(FALSE);
|
||||
}
|
||||
|
||||
if (dtype_is_binary_string_type(type1->mtype, type1->prtype)
|
||||
&& dtype_is_binary_string_type(type2->mtype, type2->prtype)) {
|
||||
|
||||
/* Both are binary string types: they can be compared */
|
||||
|
||||
return(TRUE);
|
||||
}
|
||||
|
||||
if (type1->mtype != type2->mtype) {
|
||||
|
||||
return(FALSE);
|
||||
|
@ -128,11 +141,6 @@ cmp_types_are_equal(
|
|||
return(FALSE);
|
||||
}
|
||||
|
||||
if (type1->mtype == DATA_BLOB && (type1->prtype & DATA_BINARY_TYPE)
|
||||
!= (type2->prtype & DATA_BINARY_TYPE)) {
|
||||
return(FALSE);
|
||||
}
|
||||
|
||||
return(TRUE);
|
||||
}
|
||||
|
||||
|
@ -269,6 +277,7 @@ cmp_whole_field(
|
|||
|
||||
return(innobase_mysql_cmp(
|
||||
(int)(type->prtype & DATA_MYSQL_TYPE_MASK),
|
||||
(uint)dtype_get_charset_coll(type->prtype),
|
||||
a, a_length, b, b_length));
|
||||
default:
|
||||
fprintf(stderr,
|
||||
|
@ -322,7 +331,9 @@ cmp_data_data_slow(
|
|||
|
||||
if (cur_type->mtype >= DATA_FLOAT
|
||||
|| (cur_type->mtype == DATA_BLOB
|
||||
&& (cur_type->prtype & DATA_NONLATIN1))) {
|
||||
&& 0 == (cur_type->prtype & DATA_BINARY_TYPE)
|
||||
&& dtype_get_charset_coll(cur_type->prtype) !=
|
||||
data_mysql_latin1_swedish_charset_coll)) {
|
||||
|
||||
return(cmp_whole_field(cur_type, data1, len1, data2, len2));
|
||||
}
|
||||
|
@ -523,8 +534,10 @@ cmp_dtuple_rec_with_match(
|
|||
}
|
||||
|
||||
if (cur_type->mtype >= DATA_FLOAT
|
||||
|| (cur_type->mtype == DATA_BLOB
|
||||
&& (cur_type->prtype & DATA_NONLATIN1))) {
|
||||
|| (cur_type->mtype == DATA_BLOB
|
||||
&& 0 == (cur_type->prtype & DATA_BINARY_TYPE)
|
||||
&& dtype_get_charset_coll(cur_type->prtype) !=
|
||||
data_mysql_latin1_swedish_charset_coll)) {
|
||||
|
||||
ret = cmp_whole_field(cur_type,
|
||||
dfield_get_data(dtuple_field), dtuple_f_len,
|
||||
|
@ -845,8 +858,10 @@ cmp_rec_rec_with_match(
|
|||
}
|
||||
|
||||
if (cur_type->mtype >= DATA_FLOAT
|
||||
|| (cur_type->mtype == DATA_BLOB
|
||||
&& (cur_type->prtype & DATA_NONLATIN1))) {
|
||||
|| (cur_type->mtype == DATA_BLOB
|
||||
&& 0 == (cur_type->prtype & DATA_BINARY_TYPE)
|
||||
&& dtype_get_charset_coll(cur_type->prtype) !=
|
||||
data_mysql_latin1_swedish_charset_coll)) {
|
||||
|
||||
ret = cmp_whole_field(cur_type,
|
||||
rec1_b_ptr, rec1_f_len,
|
||||
|
|
|
@ -45,43 +45,6 @@ or there was no master log position info inside InnoDB. */
|
|||
char trx_sys_mysql_master_log_name[TRX_SYS_MYSQL_LOG_NAME_LEN];
|
||||
ib_longlong trx_sys_mysql_master_log_pos = -1;
|
||||
|
||||
/* Do NOT merge this to the 4.1 code base! */
|
||||
ibool trx_sys_downgrading_from_4_1_1 = FALSE;
|
||||
|
||||
/********************************************************************
|
||||
Do NOT merge this to the 4.1 code base!
|
||||
Marks the trx sys header when we have successfully downgraded from the >= 4.1.1
|
||||
multiple tablespace format back to the 4.0 format. */
|
||||
|
||||
void
|
||||
trx_sys_mark_downgraded_from_4_1_1(void)
|
||||
/*====================================*/
|
||||
{
|
||||
page_t* page;
|
||||
byte* doublewrite;
|
||||
mtr_t mtr;
|
||||
|
||||
/* Let us mark to the trx_sys header that the downgrade has been
|
||||
done. */
|
||||
|
||||
mtr_start(&mtr);
|
||||
|
||||
page = buf_page_get(TRX_SYS_SPACE, TRX_SYS_PAGE_NO, RW_X_LATCH, &mtr);
|
||||
buf_page_dbg_add_level(page, SYNC_NO_ORDER_CHECK);
|
||||
|
||||
doublewrite = page + TRX_SYS_DOUBLEWRITE;
|
||||
|
||||
mlog_write_ulint(doublewrite + TRX_SYS_DOUBLEWRITE_SPACE_ID_STORED,
|
||||
TRX_SYS_DOUBLEWRITE_SPACE_ID_STORED_N + 1,
|
||||
MLOG_4BYTES, &mtr);
|
||||
mtr_commit(&mtr);
|
||||
|
||||
/* Flush the modified pages to disk and make a checkpoint */
|
||||
log_make_checkpoint_at(ut_dulint_max, TRUE);
|
||||
|
||||
trx_sys_downgrading_from_4_1_1 = FALSE;
|
||||
}
|
||||
|
||||
/********************************************************************
|
||||
Determines if a page number is located inside the doublewrite buffer. */
|
||||
|
||||
|
@ -388,31 +351,6 @@ trx_sys_doublewrite_init_or_restore_pages(
|
|||
== TRX_SYS_DOUBLEWRITE_MAGIC_N) {
|
||||
/* The doublewrite buffer has been created */
|
||||
|
||||
/* Do NOT merge to the 4.1 code base! */
|
||||
if (mach_read_from_4(doublewrite
|
||||
+ TRX_SYS_DOUBLEWRITE_SPACE_ID_STORED)
|
||||
== TRX_SYS_DOUBLEWRITE_SPACE_ID_STORED_N) {
|
||||
|
||||
fprintf(stderr,
|
||||
"InnoDB: You are downgrading from the multiple tablespace format of\n"
|
||||
"InnoDB: >= MySQL-4.1.1 back to the old format of MySQL-4.0.\n"
|
||||
"InnoDB:\n"
|
||||
"InnoDB: MAKE SURE that the mysqld server is idle, and purge and the insert\n"
|
||||
"InnoDB: buffer merge have run to completion under >= 4.1.1 before trying to\n"
|
||||
"InnoDB: downgrade! You can determine this by looking at SHOW INNODB STATUS:\n"
|
||||
"InnoDB: if the Main thread is 'waiting for server activity' and SHOW\n"
|
||||
"InnoDB: PROCESSLIST shows that you have ended all other connections\n"
|
||||
"InnoDB: to mysqld, then purge and the insert buffer merge have been\n"
|
||||
"InnoDB: completed.\n"
|
||||
"InnoDB: If you have already created tables in >= 4.1.1, then those\n"
|
||||
"InnoDB: tables cannot be used under 4.0.\n"
|
||||
"InnoDB: NOTE THAT this downgrade procedure has not been properly tested!\n"
|
||||
"InnoDB: The safe way to downgrade is to dump all InnoDB tables and recreate\n"
|
||||
"InnoDB: the whole tablespace.\n");
|
||||
|
||||
trx_sys_downgrading_from_4_1_1 = TRUE;
|
||||
}
|
||||
|
||||
trx_doublewrite_init(doublewrite);
|
||||
|
||||
block1 = trx_doublewrite->block1;
|
||||
|
|
|
@ -50,7 +50,7 @@ mysysheaders = mysys_priv.h my_static.h
|
|||
vioheaders = vio_priv.h
|
||||
mysysobjects1 = my_init.lo my_static.lo my_malloc.lo my_realloc.lo \
|
||||
my_create.lo my_delete.lo mf_tempfile.lo my_open.lo \
|
||||
my_read.lo my_write.lo errors.lo \
|
||||
my_file.lo my_read.lo my_write.lo errors.lo \
|
||||
my_error.lo my_getwd.lo my_div.lo \
|
||||
mf_pack.lo my_messnc.lo mf_dirname.lo mf_fn_ext.lo\
|
||||
mf_wcomp.lo typelib.lo safemalloc.lo my_alloc.lo \
|
||||
|
|
|
@ -22,7 +22,7 @@ extern my_string mysql_unix_port;
|
|||
CLIENT_PROTOCOL_41 | CLIENT_SECURE_CONNECTION)
|
||||
|
||||
sig_handler pipe_sig_handler(int sig __attribute__((unused)));
|
||||
my_bool stmt_close(MYSQL_STMT *stmt, my_bool skip_list);
|
||||
my_bool stmt_close(MYSQL_STMT *stmt, my_bool skip_list, my_bool skip_free);
|
||||
void read_user_name(char *name);
|
||||
my_bool send_file_to_server(MYSQL *mysql, const char *filename);
|
||||
|
||||
|
|
|
@ -89,7 +89,7 @@ static void append_wild(char *to,char *end,const char *wild);
|
|||
sig_handler pipe_sig_handler(int sig);
|
||||
static ulong mysql_sub_escape_string(CHARSET_INFO *charset_info, char *to,
|
||||
const char *from, ulong length);
|
||||
my_bool stmt_close(MYSQL_STMT *stmt, my_bool skip_list);
|
||||
my_bool stmt_close(MYSQL_STMT *stmt, my_bool skip_list, my_bool skip_free);
|
||||
|
||||
static my_bool mysql_client_init= 0;
|
||||
static my_bool org_my_init_done= 0;
|
||||
|
@ -1666,14 +1666,14 @@ mysql_prepare(MYSQL *mysql, const char *query, ulong length)
|
|||
}
|
||||
if (simple_command(mysql, COM_PREPARE, query, length, 1))
|
||||
{
|
||||
stmt_close(stmt, 1);
|
||||
stmt_close(stmt, 1, 0);
|
||||
DBUG_RETURN(0);
|
||||
}
|
||||
|
||||
init_alloc_root(&stmt->mem_root,8192,0);
|
||||
if ((*mysql->methods->read_prepare_result)(mysql, stmt))
|
||||
{
|
||||
stmt_close(stmt, 1);
|
||||
stmt_close(stmt, 1, 0);
|
||||
DBUG_RETURN(0);
|
||||
}
|
||||
|
||||
|
@ -3312,7 +3312,7 @@ my_bool STDCALL mysql_stmt_free_result(MYSQL_STMT *stmt)
|
|||
}
|
||||
|
||||
|
||||
my_bool stmt_close(MYSQL_STMT *stmt, my_bool skip_list)
|
||||
my_bool stmt_close(MYSQL_STMT *stmt, my_bool skip_list, my_bool skip_free)
|
||||
{
|
||||
MYSQL *mysql;
|
||||
DBUG_ENTER("mysql_stmt_close");
|
||||
|
@ -3321,7 +3321,8 @@ my_bool stmt_close(MYSQL_STMT *stmt, my_bool skip_list)
|
|||
|
||||
if (!(mysql= stmt->mysql))
|
||||
{
|
||||
my_free((gptr) stmt, MYF(MY_WME));
|
||||
if (!skip_free)
|
||||
my_free((gptr) stmt, MYF(MY_WME));
|
||||
DBUG_RETURN(0);
|
||||
}
|
||||
mysql_stmt_free_result(stmt);
|
||||
|
@ -3329,7 +3330,7 @@ my_bool stmt_close(MYSQL_STMT *stmt, my_bool skip_list)
|
|||
{
|
||||
char buff[4];
|
||||
int4store(buff, stmt->stmt_id);
|
||||
if (simple_command(mysql, COM_CLOSE_STMT, buff, 4, 1))
|
||||
if (skip_free || simple_command(mysql, COM_CLOSE_STMT, buff, 4, 1))
|
||||
{
|
||||
set_stmt_errmsg(stmt, mysql->net.last_error, mysql->net.last_errno,
|
||||
mysql->net.sqlstate);
|
||||
|
@ -3350,7 +3351,7 @@ my_bool stmt_close(MYSQL_STMT *stmt, my_bool skip_list)
|
|||
|
||||
my_bool STDCALL mysql_stmt_close(MYSQL_STMT *stmt)
|
||||
{
|
||||
return stmt_close(stmt, 0);
|
||||
return stmt_close(stmt, 0, 0);
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
3
ltconfig
3
ltconfig
|
@ -2877,6 +2877,9 @@ DLLTOOL="$DLLTOOL"
|
|||
# Used on cygwin: object dumper.
|
||||
OBJDUMP="$OBJDUMP"
|
||||
|
||||
# compatibility with ancient libtool :)
|
||||
SED=sed
|
||||
|
||||
# Used on cygwin: assembler.
|
||||
AS="$AS"
|
||||
|
||||
|
|
|
@ -132,7 +132,7 @@ win32_libid () {
|
|||
if eval $OBJDUMP -f $1 | $SED -e '10q' 2>/dev/null | \
|
||||
grep -E 'file format pe-i386(.*architecture: i386)?' >/dev/null ; then
|
||||
win32_nmres=`eval $NM -f posix -A $1 | \
|
||||
sed -n -e '1,100{/ I /{x;/import/!{s/^/import/;h;p;};x;};}'`
|
||||
$SED -n -e '1,100{/ I /{x;/import/!{s/^/import/;h;p;};x;};}'`
|
||||
if test "X$win32_nmres" = "Ximport" ; then
|
||||
win32_libid_type="x86 archive import"
|
||||
else
|
||||
|
|
|
@ -174,7 +174,7 @@ static int walk_and_push(FT_SUPERDOC *from,
|
|||
{
|
||||
DBUG_ENTER("walk_and_copy");
|
||||
from->doc.weight+=from->tmp_weight*from->word_ptr->weight;
|
||||
set_if_smaller(best->elements, ft_query_expansion_limit-1)
|
||||
set_if_smaller(best->elements, ft_query_expansion_limit-1);
|
||||
queue_insert(best, (byte *)& from->doc);
|
||||
DBUG_RETURN(0);
|
||||
}
|
||||
|
|
|
@ -73,6 +73,26 @@ FT_WORD * ft_linearize(TREE *wtree)
|
|||
DBUG_RETURN(wlist);
|
||||
}
|
||||
|
||||
my_bool ft_boolean_check_syntax_string(const byte *str)
|
||||
{
|
||||
uint i, j;
|
||||
|
||||
if (!str ||
|
||||
(strlen(str)+1 != sizeof(ft_boolean_syntax)) ||
|
||||
(str[0] != ' ' && str[1] != ' '))
|
||||
return 1;
|
||||
for (i=0; i<sizeof(ft_boolean_syntax); i++)
|
||||
{
|
||||
/* limiting to 7-bit ascii only */
|
||||
if ((unsigned char)(str[i]) > 127 || my_isalnum(default_charset_info, str[i]))
|
||||
return 1;
|
||||
for (j=0; j<i; j++)
|
||||
if (str[i] == str[j] && (i != 11 || j != 10))
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* returns:
|
||||
* 0 - eof
|
||||
* 1 - word found
|
||||
|
|
|
@ -21,7 +21,7 @@
|
|||
ulong ft_min_word_len=4;
|
||||
ulong ft_max_word_len=HA_FT_MAXCHARLEN;
|
||||
ulong ft_query_expansion_limit=5;
|
||||
const char *ft_boolean_syntax="+ -><()~*:\"\"&|";
|
||||
char ft_boolean_syntax[]="+ -><()~*:\"\"&|";
|
||||
|
||||
const HA_KEYSEG ft_keysegs[FT_SEGS]={
|
||||
{
|
||||
|
|
|
@ -409,7 +409,7 @@ int chk_key(MI_CHECK *param, register MI_INFO *info)
|
|||
if (chk_index(param,info,keyinfo,share->state.key_root[key],info->buff,
|
||||
&keys, param->key_crc+key,1))
|
||||
DBUG_RETURN(-1);
|
||||
if(!(keyinfo->flag & HA_FULLTEXT))
|
||||
if(!(keyinfo->flag & (HA_FULLTEXT | HA_SPATIAL)))
|
||||
{
|
||||
if (keys != info->state->records)
|
||||
{
|
||||
|
@ -558,6 +558,10 @@ static int chk_index(MI_CHECK *param, MI_INFO *info, MI_KEYDEF *keyinfo,
|
|||
DBUG_ENTER("chk_index");
|
||||
DBUG_DUMP("buff",(byte*) buff,mi_getint(buff));
|
||||
|
||||
/* TODO: implement appropriate check for RTree keys */
|
||||
if (keyinfo->flag & HA_SPATIAL)
|
||||
DBUG_RETURN(0);
|
||||
|
||||
if (!(temp_buff=(uchar*) my_alloca((uint) keyinfo->block_length)))
|
||||
{
|
||||
mi_check_print_error(param,"Not enough memory for keyblock");
|
||||
|
@ -1073,7 +1077,7 @@ int chk_data_link(MI_CHECK *param, MI_INFO *info,int extend)
|
|||
for (key=0 ; key < info->s->base.keys; key++)
|
||||
{
|
||||
if (key_checksum[key] != param->key_crc[key] &&
|
||||
!(info->s->keyinfo[key].flag & HA_FULLTEXT))
|
||||
!(info->s->keyinfo[key].flag & (HA_FULLTEXT | HA_SPATIAL)))
|
||||
{
|
||||
mi_check_print_error(param,"Checksum for key: %2d doesn't match checksum for records",
|
||||
key+1);
|
||||
|
|
|
@ -60,7 +60,6 @@ static int file_info_compare(void *cmp_arg, void *a,void *b);
|
|||
static int test_if_open(struct file_info *key,element_count count,
|
||||
struct test_if_open_param *param);
|
||||
static void fix_blob_pointers(MI_INFO *isam,byte *record);
|
||||
static uint set_maximum_open_files(uint);
|
||||
static int test_when_accessed(struct file_info *key,element_count count,
|
||||
struct st_access_param *access_param);
|
||||
static void file_info_free(struct file_info *info);
|
||||
|
@ -89,9 +88,8 @@ int main(int argc, char **argv)
|
|||
|
||||
log_filename=myisam_log_filename;
|
||||
get_options(&argc,&argv);
|
||||
/* Nr of isam-files */
|
||||
max_files=(set_maximum_open_files(min(max_files,8))-6)/2;
|
||||
|
||||
/* Number of MyISAM files we can have open at one time */
|
||||
max_files= (my_set_max_open_files(min(max_files,8))-6)/2;
|
||||
if (update)
|
||||
printf("Trying to %s MyISAM files according to log '%s'\n",
|
||||
(recover ? "recover" : "update"),log_filename);
|
||||
|
@ -123,6 +121,7 @@ int main(int argc, char **argv)
|
|||
printf("Had to do %d re-open because of too few possibly open files\n",
|
||||
re_open_count);
|
||||
VOID(mi_panic(HA_PANIC_CLOSE));
|
||||
my_free_open_file_info();
|
||||
my_end(test_info ? MY_CHECK_ERROR | MY_GIVE_INFO : MY_CHECK_ERROR);
|
||||
exit(error);
|
||||
return 0; /* No compiler warning */
|
||||
|
@ -732,38 +731,6 @@ static void fix_blob_pointers(MI_INFO *info, byte *record)
|
|||
}
|
||||
}
|
||||
|
||||
static uint set_maximum_open_files(uint maximum_files)
|
||||
{
|
||||
#if defined(HAVE_GETRUSAGE) && defined(RLIMIT_NOFILE)
|
||||
struct rlimit rlimit;
|
||||
int old_max;
|
||||
|
||||
if (maximum_files > MY_NFILE)
|
||||
maximum_files=MY_NFILE; /* Don't crash my_open */
|
||||
|
||||
if (!getrlimit(RLIMIT_NOFILE,&rlimit))
|
||||
{
|
||||
old_max=rlimit.rlim_max;
|
||||
if (maximum_files && (int) maximum_files > old_max)
|
||||
rlimit.rlim_max=maximum_files;
|
||||
rlimit.rlim_cur=rlimit.rlim_max;
|
||||
if (setrlimit(RLIMIT_NOFILE,&rlimit))
|
||||
{
|
||||
if (old_max != (int) maximum_files)
|
||||
{ /* Set as much as we can */
|
||||
rlimit.rlim_max=rlimit.rlim_cur=old_max;
|
||||
setrlimit(RLIMIT_NOFILE,&rlimit);
|
||||
}
|
||||
}
|
||||
getrlimit(RLIMIT_NOFILE,&rlimit); /* Read if broken setrlimit */
|
||||
if (maximum_files && maximum_files < rlimit.rlim_cur)
|
||||
VOID(fprintf(stderr,"Warning: Error from setrlimit: Max open files is %d\n",old_max));
|
||||
return rlimit.rlim_cur;
|
||||
}
|
||||
#endif
|
||||
return min(maximum_files,MY_NFILE);
|
||||
}
|
||||
|
||||
/* close the file with hasn't been accessed for the longest time */
|
||||
/* ARGSUSED */
|
||||
|
||||
|
|
|
@ -168,4 +168,4 @@ hex(s1)
|
|||
41
|
||||
drop table t1;
|
||||
create table t1 (a char(160) character set utf8, primary key(a));
|
||||
ERROR HY000: Incorrect sub part key. The used key part isn't a string, the used length is longer than the key part or the storage engine doesn't support unique sub keys
|
||||
ERROR 42000: Specified key was too long; max key length is 255 bytes
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
drop table if exists t1;
|
||||
show variables like "ft\_%";
|
||||
Variable_name Value
|
||||
ft_boolean_syntax + -><()~*:""&|
|
||||
|
@ -5,3 +6,33 @@ ft_min_word_len 4
|
|||
ft_max_word_len 84
|
||||
ft_query_expansion_limit 20
|
||||
ft_stopword_file (built-in)
|
||||
create table t1 (b text not null);
|
||||
insert t1 values ('aaaaaa bbbbbb cccccc');
|
||||
insert t1 values ('bbbbbb cccccc');
|
||||
insert t1 values ('aaaaaa cccccc');
|
||||
select * from t1 where match b against ('+aaaaaa bbbbbb' in boolean mode);
|
||||
b
|
||||
aaaaaa bbbbbb cccccc
|
||||
aaaaaa cccccc
|
||||
set ft_boolean_syntax=' +-><()~*:""&|';
|
||||
ERROR HY000: Variable 'ft_boolean_syntax' is a GLOBAL variable and should be set with SET GLOBAL
|
||||
set global ft_boolean_syntax=' +-><()~*:""&|';
|
||||
select * from t1 where match b against ('+aaaaaa bbbbbb' in boolean mode);
|
||||
b
|
||||
aaaaaa bbbbbb cccccc
|
||||
bbbbbb cccccc
|
||||
set global ft_boolean_syntax='@ -><()~*:""&|';
|
||||
select * from t1 where match b against ('+aaaaaa bbbbbb' in boolean mode);
|
||||
b
|
||||
aaaaaa bbbbbb cccccc
|
||||
bbbbbb cccccc
|
||||
aaaaaa cccccc
|
||||
select * from t1 where match b against ('+aaaaaa @bbbbbb' in boolean mode);
|
||||
b
|
||||
aaaaaa bbbbbb cccccc
|
||||
bbbbbb cccccc
|
||||
set global ft_boolean_syntax='@ -><()~*:""@|';
|
||||
ERROR 42000: Variable 'ft_boolean_syntax' can't be set to the value of '@ -><()~*:""@|'
|
||||
set global ft_boolean_syntax='+ -><()~*:""@!|';
|
||||
ERROR 42000: Variable 'ft_boolean_syntax' can't be set to the value of '+ -><()~*:""@!|'
|
||||
drop table t1;
|
||||
|
|
|
@ -710,3 +710,43 @@ SELECT count(*) FROM t2;
|
|||
count(*)
|
||||
0
|
||||
DROP TABLE t2;
|
||||
drop table if exists t1;
|
||||
Warnings:
|
||||
Note 1051 Unknown table 't1'
|
||||
CREATE TABLE t1 (a geometry NOT NULL, SPATIAL (a));
|
||||
INSERT INTO t1 VALUES (GeomFromText("LINESTRING(100 100, 200 200, 300 300)"));
|
||||
INSERT INTO t1 VALUES (GeomFromText("LINESTRING(100 100, 200 200, 300 300)"));
|
||||
INSERT INTO t1 VALUES (GeomFromText("LINESTRING(100 100, 200 200, 300 300)"));
|
||||
INSERT INTO t1 VALUES (GeomFromText("LINESTRING(100 100, 200 200, 300 300)"));
|
||||
INSERT INTO t1 VALUES (GeomFromText("LINESTRING(100 100, 200 200, 300 300)"));
|
||||
INSERT INTO t1 VALUES (GeomFromText("LINESTRING(100 100, 200 200, 300 300)"));
|
||||
INSERT INTO t1 VALUES (GeomFromText("LINESTRING(100 100, 200 200, 300 300)"));
|
||||
INSERT INTO t1 VALUES (GeomFromText("LINESTRING(100 100, 200 200, 300 300)"));
|
||||
INSERT INTO t1 VALUES (GeomFromText("LINESTRING(100 100, 200 200, 300 300)"));
|
||||
INSERT INTO t1 VALUES (GeomFromText("LINESTRING(100 100, 200 200, 300 300)"));
|
||||
INSERT INTO t1 VALUES (GeomFromText("LINESTRING(100 100, 200 200, 300 300)"));
|
||||
INSERT INTO t1 VALUES (GeomFromText("LINESTRING(100 100, 200 200, 300 300)"));
|
||||
INSERT INTO t1 VALUES (GeomFromText("LINESTRING(100 100, 200 200, 300 300)"));
|
||||
INSERT INTO t1 VALUES (GeomFromText("LINESTRING(100 100, 200 200, 300 300)"));
|
||||
INSERT INTO t1 VALUES (GeomFromText("LINESTRING(100 100, 200 200, 300 300)"));
|
||||
INSERT INTO t1 VALUES (GeomFromText("LINESTRING(100 100, 200 200, 300 300)"));
|
||||
INSERT INTO t1 VALUES (GeomFromText("LINESTRING(100 100, 200 200, 300 300)"));
|
||||
INSERT INTO t1 VALUES (GeomFromText("LINESTRING(100 100, 200 200, 300 300)"));
|
||||
INSERT INTO t1 VALUES (GeomFromText("LINESTRING(100 100, 200 200, 300 300)"));
|
||||
INSERT INTO t1 VALUES (GeomFromText("LINESTRING(100 100, 200 200, 300 300)"));
|
||||
INSERT INTO t1 VALUES (GeomFromText("LINESTRING(100 100, 200 200, 300 300)"));
|
||||
INSERT INTO t1 VALUES (GeomFromText("LINESTRING(100 100, 200 200, 300 300)"));
|
||||
INSERT INTO t1 VALUES (GeomFromText("LINESTRING(100 100, 200 200, 300 300)"));
|
||||
INSERT INTO t1 VALUES (GeomFromText("LINESTRING(100 100, 200 200, 300 300)"));
|
||||
INSERT INTO t1 VALUES (GeomFromText("LINESTRING(100 100, 200 200, 300 300)"));
|
||||
INSERT INTO t1 VALUES (GeomFromText("LINESTRING(100 100, 200 200, 300 300)"));
|
||||
INSERT INTO t1 VALUES (GeomFromText("LINESTRING(100 100, 200 200, 300 300)"));
|
||||
INSERT INTO t1 VALUES (GeomFromText("LINESTRING(100 100, 200 200, 300 300)"));
|
||||
INSERT INTO t1 VALUES (GeomFromText("LINESTRING(100 100, 200 200, 300 300)"));
|
||||
check table t1;
|
||||
Table Op Msg_type Msg_text
|
||||
test.t1 check status OK
|
||||
analyze table t1;
|
||||
Table Op Msg_type Msg_text
|
||||
test.t1 analyze status OK
|
||||
drop table t1;
|
||||
|
|
|
@ -323,10 +323,10 @@ Table Op Msg_type Msg_text
|
|||
test.t1 check status OK
|
||||
drop table t1;
|
||||
CREATE TABLE t1 (a varchar(255), b varchar(255), c varchar(255), KEY t1 (a, b, c));
|
||||
ERROR 42000: Specified key was too long. Max key length is 500
|
||||
ERROR 42000: Specified key was too long; max key length is 500 bytes
|
||||
CREATE TABLE t1 (a varchar(255), b varchar(255), c varchar(255));
|
||||
ALTER TABLE t1 ADD INDEX t1 (a, b, c);
|
||||
ERROR 42000: Specified key was too long. Max key length is 500
|
||||
ERROR 42000: Specified key was too long; max key length is 500 bytes
|
||||
DROP TABLE t1;
|
||||
CREATE TABLE t1 (a int not null, b int, c int, key(b), key(c), key(a,b), key(c,a));
|
||||
INSERT into t1 values (0, null, 0), (0, null, 1), (0, null, 2), (0, null,3), (1,1,4);
|
||||
|
|
|
@ -346,9 +346,17 @@ HELLO MY 1
|
|||
a 1
|
||||
hello 1
|
||||
drop table t1;
|
||||
create table t1 (a text, unique (a(300)));
|
||||
ERROR 42000: Specified key was too long; max key length is 255 bytes
|
||||
create table t1 (a text, key (a(300)));
|
||||
ERROR HY000: Incorrect sub part key. The used key part isn't a string, the used length is longer than the key part or the storage engine doesn't support unique sub keys
|
||||
create table t1 (a text, key (a(255)));
|
||||
Warnings:
|
||||
Warning 1071 Specified key was too long; max key length is 255 bytes
|
||||
show create table t1;
|
||||
Table Create Table
|
||||
t1 CREATE TABLE `t1` (
|
||||
`a` text,
|
||||
KEY `a` (`a`(255))
|
||||
) ENGINE=MyISAM DEFAULT CHARSET=latin1
|
||||
drop table t1;
|
||||
CREATE TABLE t1 (
|
||||
t1_id bigint(21) NOT NULL auto_increment,
|
||||
|
|
|
@ -103,5 +103,5 @@ drop table t1;
|
|||
# Bug 2699
|
||||
# UTF8 breaks primary keys for cols > 85 characters
|
||||
#
|
||||
--error 1089
|
||||
--error 1071
|
||||
create table t1 (a char(160) character set utf8, primary key(a));
|
||||
|
|
|
@ -1,5 +1,27 @@
|
|||
#
|
||||
# Fulltext configurable parameters
|
||||
#
|
||||
--disable_warnings
|
||||
drop table if exists t1;
|
||||
--enable_warnings
|
||||
|
||||
show variables like "ft\_%";
|
||||
|
||||
create table t1 (b text not null);
|
||||
insert t1 values ('aaaaaa bbbbbb cccccc');
|
||||
insert t1 values ('bbbbbb cccccc');
|
||||
insert t1 values ('aaaaaa cccccc');
|
||||
select * from t1 where match b against ('+aaaaaa bbbbbb' in boolean mode);
|
||||
-- error 1229
|
||||
set ft_boolean_syntax=' +-><()~*:""&|';
|
||||
set global ft_boolean_syntax=' +-><()~*:""&|';
|
||||
select * from t1 where match b against ('+aaaaaa bbbbbb' in boolean mode);
|
||||
set global ft_boolean_syntax='@ -><()~*:""&|';
|
||||
select * from t1 where match b against ('+aaaaaa bbbbbb' in boolean mode);
|
||||
select * from t1 where match b against ('+aaaaaa @bbbbbb' in boolean mode);
|
||||
-- error 1231
|
||||
set global ft_boolean_syntax='@ -><()~*:""@|';
|
||||
-- error 1231
|
||||
set global ft_boolean_syntax='+ -><()~*:""@!|';
|
||||
drop table t1;
|
||||
|
||||
|
|
|
@ -67,3 +67,39 @@ while ($1)
|
|||
}
|
||||
|
||||
DROP TABLE t2;
|
||||
|
||||
drop table if exists t1;
|
||||
CREATE TABLE t1 (a geometry NOT NULL, SPATIAL (a));
|
||||
INSERT INTO t1 VALUES (GeomFromText("LINESTRING(100 100, 200 200, 300 300)"));
|
||||
INSERT INTO t1 VALUES (GeomFromText("LINESTRING(100 100, 200 200, 300 300)"));
|
||||
INSERT INTO t1 VALUES (GeomFromText("LINESTRING(100 100, 200 200, 300 300)"));
|
||||
INSERT INTO t1 VALUES (GeomFromText("LINESTRING(100 100, 200 200, 300 300)"));
|
||||
INSERT INTO t1 VALUES (GeomFromText("LINESTRING(100 100, 200 200, 300 300)"));
|
||||
INSERT INTO t1 VALUES (GeomFromText("LINESTRING(100 100, 200 200, 300 300)"));
|
||||
INSERT INTO t1 VALUES (GeomFromText("LINESTRING(100 100, 200 200, 300 300)"));
|
||||
INSERT INTO t1 VALUES (GeomFromText("LINESTRING(100 100, 200 200, 300 300)"));
|
||||
INSERT INTO t1 VALUES (GeomFromText("LINESTRING(100 100, 200 200, 300 300)"));
|
||||
INSERT INTO t1 VALUES (GeomFromText("LINESTRING(100 100, 200 200, 300 300)"));
|
||||
INSERT INTO t1 VALUES (GeomFromText("LINESTRING(100 100, 200 200, 300 300)"));
|
||||
INSERT INTO t1 VALUES (GeomFromText("LINESTRING(100 100, 200 200, 300 300)"));
|
||||
INSERT INTO t1 VALUES (GeomFromText("LINESTRING(100 100, 200 200, 300 300)"));
|
||||
INSERT INTO t1 VALUES (GeomFromText("LINESTRING(100 100, 200 200, 300 300)"));
|
||||
INSERT INTO t1 VALUES (GeomFromText("LINESTRING(100 100, 200 200, 300 300)"));
|
||||
INSERT INTO t1 VALUES (GeomFromText("LINESTRING(100 100, 200 200, 300 300)"));
|
||||
INSERT INTO t1 VALUES (GeomFromText("LINESTRING(100 100, 200 200, 300 300)"));
|
||||
INSERT INTO t1 VALUES (GeomFromText("LINESTRING(100 100, 200 200, 300 300)"));
|
||||
INSERT INTO t1 VALUES (GeomFromText("LINESTRING(100 100, 200 200, 300 300)"));
|
||||
INSERT INTO t1 VALUES (GeomFromText("LINESTRING(100 100, 200 200, 300 300)"));
|
||||
INSERT INTO t1 VALUES (GeomFromText("LINESTRING(100 100, 200 200, 300 300)"));
|
||||
INSERT INTO t1 VALUES (GeomFromText("LINESTRING(100 100, 200 200, 300 300)"));
|
||||
INSERT INTO t1 VALUES (GeomFromText("LINESTRING(100 100, 200 200, 300 300)"));
|
||||
INSERT INTO t1 VALUES (GeomFromText("LINESTRING(100 100, 200 200, 300 300)"));
|
||||
INSERT INTO t1 VALUES (GeomFromText("LINESTRING(100 100, 200 200, 300 300)"));
|
||||
INSERT INTO t1 VALUES (GeomFromText("LINESTRING(100 100, 200 200, 300 300)"));
|
||||
INSERT INTO t1 VALUES (GeomFromText("LINESTRING(100 100, 200 200, 300 300)"));
|
||||
INSERT INTO t1 VALUES (GeomFromText("LINESTRING(100 100, 200 200, 300 300)"));
|
||||
INSERT INTO t1 VALUES (GeomFromText("LINESTRING(100 100, 200 200, 300 300)"));
|
||||
check table t1;
|
||||
analyze table t1;
|
||||
drop table t1;
|
||||
|
||||
|
|
|
@ -121,8 +121,10 @@ select c,count(*) from t1 group by c;
|
|||
select d,count(*) from t1 group by d;
|
||||
drop table t1;
|
||||
|
||||
!$1089 create table t1 (a text, key (a(300))); # should give an error
|
||||
create table t1 (a text, key (a(255)));
|
||||
-- error 1071
|
||||
create table t1 (a text, unique (a(300))); # should give an error
|
||||
create table t1 (a text, key (a(300))); # key is auto-truncated
|
||||
show create table t1;
|
||||
drop table t1;
|
||||
|
||||
#
|
||||
|
|
|
@ -25,8 +25,8 @@ noinst_HEADERS = mysys_priv.h my_static.h \
|
|||
my_os2cond.c my_os2dirsrch.c my_os2dirsrch.h \
|
||||
my_os2dlfcn.c my_os2file64.c my_os2mutex.c \
|
||||
my_os2thread.c my_os2tls.c
|
||||
libmysys_a_SOURCES = my_init.c my_getwd.c mf_getdate.c\
|
||||
mf_path.c mf_loadpath.c\
|
||||
libmysys_a_SOURCES = my_init.c my_getwd.c mf_getdate.c \
|
||||
mf_path.c mf_loadpath.c my_file.c \
|
||||
my_open.c my_create.c my_dup.c my_seek.c my_read.c \
|
||||
my_pread.c my_write.c \
|
||||
mf_keycache.c mf_keycaches.c my_crc32.c \
|
||||
|
|
|
@ -1961,7 +1961,7 @@ int key_cache_write(KEY_CACHE *keycache,
|
|||
else if (! (block->status & BLOCK_CHANGED))
|
||||
link_to_changed_list(keycache, block);
|
||||
|
||||
set_if_smaller(block->offset, offset)
|
||||
set_if_smaller(block->offset, offset);
|
||||
set_if_bigger(block->length, read_length+offset);
|
||||
|
||||
if (! (block->status & BLOCK_ERROR))
|
||||
|
|
|
@ -68,7 +68,7 @@ void init_alloc_root(MEM_ROOT *mem_root, uint block_size,
|
|||
*/
|
||||
|
||||
void reset_root_defaults(MEM_ROOT *mem_root, uint block_size,
|
||||
uint pre_alloc_size)
|
||||
uint pre_alloc_size __attribute__((unused)))
|
||||
{
|
||||
mem_root->block_size= block_size-MALLOC_OVERHEAD-sizeof(USED_MEM)-8;
|
||||
#if !(defined(HAVE_purify) && defined(EXTRA_DEBUG))
|
||||
|
|
|
@ -27,7 +27,7 @@
|
|||
my_string my_filename(File fd)
|
||||
{
|
||||
DBUG_ENTER("my_filename");
|
||||
if (fd >= MY_NFILE)
|
||||
if ((uint) fd >= (uint) my_file_limit)
|
||||
DBUG_RETURN((char*) "UNKNOWN");
|
||||
if (fd >= 0 && my_file_info[fd].type != UNOPEN)
|
||||
{
|
||||
|
|
|
@ -32,7 +32,7 @@ File my_dup(File file, myf MyFlags)
|
|||
DBUG_ENTER("my_dup");
|
||||
DBUG_PRINT("my",("file: %d MyFlags: %d", MyFlags));
|
||||
fd = dup(file);
|
||||
filename= (((int) file < MY_NFILE) ?
|
||||
filename= (((uint) file < my_file_limit) ?
|
||||
my_file_info[(int) file].name : "Unknown");
|
||||
DBUG_RETURN(my_register_filename(fd, filename, FILE_BY_DUP,
|
||||
EE_FILENOTFOUND, MyFlags));
|
||||
|
|
147
mysys/my_file.c
Normal file
147
mysys/my_file.c
Normal file
|
@ -0,0 +1,147 @@
|
|||
/* Copyright (C) 2000 MySQL AB
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
|
||||
|
||||
#include "mysys_priv.h"
|
||||
#include "my_static.h"
|
||||
#include <m_string.h>
|
||||
|
||||
/*
|
||||
set how many open files we want to be able to handle
|
||||
|
||||
SYNOPSIS
|
||||
set_maximum_open_files()
|
||||
max_file_limit Files to open
|
||||
|
||||
NOTES
|
||||
The request may not fulfilled becasue of system limitations
|
||||
|
||||
RETURN
|
||||
Files available to open.
|
||||
May be more or less than max_file_limit!
|
||||
*/
|
||||
|
||||
#if defined(HAVE_GETRLIMIT) && defined(RLIMIT_NOFILE) && !defined(HAVE_mit_thread)
|
||||
|
||||
#ifndef RLIM_INFINITY
|
||||
#define RLIM_INFINITY ((uint) 0xffffffff)
|
||||
#endif
|
||||
|
||||
static uint set_max_open_files(uint max_file_limit)
|
||||
{
|
||||
struct rlimit rlimit;
|
||||
uint old_cur;
|
||||
DBUG_ENTER("set_max_open_files");
|
||||
DBUG_PRINT("enter",("files: %u", max_file_limit));
|
||||
|
||||
if (!getrlimit(RLIMIT_NOFILE,&rlimit))
|
||||
{
|
||||
old_cur= (uint) rlimit.rlim_cur;
|
||||
DBUG_PRINT("info", ("rlim_cur: %u rlim_max: %u",
|
||||
(uint) rlimit.rlim_cur,
|
||||
(uint) rlimit.rlim_max));
|
||||
if (rlimit.rlim_cur == RLIM_INFINITY)
|
||||
rlimit.rlim_cur = max_file_limit;
|
||||
if (rlimit.rlim_cur >= max_file_limit)
|
||||
DBUG_RETURN(rlimit.rlim_cur); /* purecov: inspected */
|
||||
rlimit.rlim_cur= rlimit.rlim_max= max_file_limit;
|
||||
if (setrlimit(RLIMIT_NOFILE, &rlimit))
|
||||
max_file_limit= old_cur; /* Use original value */
|
||||
else
|
||||
{
|
||||
rlimit.rlim_cur= 0; /* Safety if next call fails */
|
||||
(void) getrlimit(RLIMIT_NOFILE,&rlimit);
|
||||
DBUG_PRINT("info", ("rlim_cur: %u", (uint) rlimit.rlim_cur));
|
||||
if (rlimit.rlim_cur) /* If call didn't fail */
|
||||
max_file_limit= (uint) rlimit.rlim_cur;
|
||||
}
|
||||
}
|
||||
DBUG_PRINT("exit",("max_file_limit: %u", max_file_limit));
|
||||
DBUG_RETURN(max_file_limit);
|
||||
}
|
||||
|
||||
#elif defined (OS2)
|
||||
|
||||
static uint set_max_open_files(uint max_file_limit)
|
||||
{
|
||||
LONG cbReqCount;
|
||||
ULONG cbCurMaxFH0;
|
||||
APIRET ulrc;
|
||||
DBUG_ENTER("set_max_open_files");
|
||||
|
||||
/* get current limit */
|
||||
cbReqCount = 0;
|
||||
DosSetRelMaxFH( &cbReqCount, &cbCurMaxFH0);
|
||||
|
||||
/* set new limit */
|
||||
if ((cbReqCount = max_file_limit - cbCurMaxFH0) > 0)
|
||||
ulrc = DosSetRelMaxFH( &cbReqCount, &cbCurMaxFH);
|
||||
DBUG_RETURN(cbCurMaxFH0);
|
||||
}
|
||||
|
||||
#else
|
||||
static int set_max_open_files(uint max_file_limit)
|
||||
{
|
||||
/* We don't know the limit. Return best guess */
|
||||
return min(max_file_limit, OS_FILE_LIMIT);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
/*
|
||||
Change number of open files
|
||||
|
||||
SYNOPSIS:
|
||||
my_set_max_open_files()
|
||||
files Number of requested files
|
||||
|
||||
RETURN
|
||||
number of files available for open
|
||||
*/
|
||||
|
||||
uint my_set_max_open_files(uint files)
|
||||
{
|
||||
struct st_my_file_info *tmp;
|
||||
DBUG_ENTER("my_set_max_open_files");
|
||||
DBUG_PRINT("enter",("files: %u my_file_limit: %u", files, my_file_limit));
|
||||
|
||||
files= set_max_open_files(min(files, OS_FILE_LIMIT));
|
||||
if (files <= MY_NFILE)
|
||||
DBUG_RETURN(files);
|
||||
|
||||
if (!(tmp= (struct st_my_file_info*) my_malloc(sizeof(*tmp) * files,
|
||||
MYF(MY_WME))))
|
||||
DBUG_RETURN(MY_NFILE);
|
||||
|
||||
/* Copy any initialized files */
|
||||
memcpy((char*) tmp, (char*) my_file_info, sizeof(*tmp) * my_file_limit);
|
||||
my_free_open_file_info(); /* Free if already allocated */
|
||||
my_file_info= tmp;
|
||||
my_file_limit= files;
|
||||
DBUG_PRINT("exit",("files: %u", files));
|
||||
DBUG_RETURN(files);
|
||||
}
|
||||
|
||||
|
||||
void my_free_open_file_info()
|
||||
{
|
||||
DBUG_ENTER("my_free_file_info");
|
||||
if (my_file_info != my_file_info_default)
|
||||
{
|
||||
my_free((char*) my_file_info, MYF(0));
|
||||
my_file_info= my_file_info_default;
|
||||
}
|
||||
DBUG_VOID_RETURN;
|
||||
}
|
|
@ -42,7 +42,7 @@ FILE *my_fopen(const char *FileName, int Flags, myf MyFlags)
|
|||
on some OS (SUNOS). Actually the filename save isn't that important
|
||||
so we can ignore if this doesn't work.
|
||||
*/
|
||||
if ((uint) fileno(fd) >= MY_NFILE)
|
||||
if ((uint) fileno(fd) >= my_file_limit)
|
||||
{
|
||||
thread_safe_increment(my_stream_opened,&THR_LOCK_open);
|
||||
DBUG_RETURN(fd); /* safeguard */
|
||||
|
@ -91,7 +91,7 @@ int my_fclose(FILE *fd, myf MyFlags)
|
|||
}
|
||||
else
|
||||
my_stream_opened--;
|
||||
if ((uint) file < MY_NFILE && my_file_info[file].type != UNOPEN)
|
||||
if ((uint) file < my_file_limit && my_file_info[file].type != UNOPEN)
|
||||
{
|
||||
my_file_info[file].type = UNOPEN;
|
||||
my_free(my_file_info[file].name, MYF(MY_ALLOW_ZERO_PTR));
|
||||
|
@ -123,11 +123,11 @@ FILE *my_fdopen(File Filedes, const char *name, int Flags, myf MyFlags)
|
|||
{
|
||||
pthread_mutex_lock(&THR_LOCK_open);
|
||||
my_stream_opened++;
|
||||
if (Filedes < MY_NFILE)
|
||||
if ((uint) Filedes < (uint) my_file_limit)
|
||||
{
|
||||
if (my_file_info[Filedes].type != UNOPEN)
|
||||
{
|
||||
my_file_opened--; /* File is opened with my_open ! */
|
||||
my_file_opened--; /* File is opened with my_open ! */
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
|
@ -86,7 +86,7 @@ int my_close(File fd, myf MyFlags)
|
|||
if (MyFlags & (MY_FAE | MY_WME))
|
||||
my_error(EE_BADCLOSE, MYF(ME_BELL+ME_WAITTANG),my_filename(fd),errno);
|
||||
}
|
||||
if ((uint) fd < MY_NFILE && my_file_info[fd].type != UNOPEN)
|
||||
if ((uint) fd < my_file_limit && my_file_info[fd].type != UNOPEN)
|
||||
{
|
||||
my_free(my_file_info[fd].name, MYF(0));
|
||||
#if defined(THREAD) && !defined(HAVE_PREAD)
|
||||
|
@ -115,7 +115,7 @@ File my_register_filename(File fd, const char *FileName, enum file_type
|
|||
{
|
||||
if ((int) fd >= 0)
|
||||
{
|
||||
if ((int) fd >= MY_NFILE)
|
||||
if ((uint) fd >= my_file_limit)
|
||||
{
|
||||
#if defined(THREAD) && !defined(HAVE_PREAD)
|
||||
(void) my_close(fd,MyFlags);
|
||||
|
|
|
@ -34,7 +34,9 @@ int NEAR my_umask=0664, NEAR my_umask_dir=0777;
|
|||
#ifndef THREAD
|
||||
int NEAR my_errno=0;
|
||||
#endif
|
||||
struct my_file_info my_file_info[MY_NFILE]= {{0,UNOPEN}};
|
||||
struct st_my_file_info my_file_info_default[MY_NFILE]= {{0,UNOPEN}};
|
||||
uint my_file_limit= MY_NFILE;
|
||||
struct st_my_file_info *my_file_info= my_file_info_default;
|
||||
|
||||
/* From mf_brkhant */
|
||||
int NEAR my_dont_interrupt=0;
|
||||
|
|
|
@ -68,6 +68,8 @@ extern byte *sf_min_adress,*sf_max_adress;
|
|||
extern uint sf_malloc_count;
|
||||
extern struct st_irem *sf_malloc_root;
|
||||
|
||||
extern struct st_my_file_info my_file_info_default[MY_NFILE];
|
||||
|
||||
#if defined(THREAD) && !defined(__WIN__)
|
||||
extern sigset_t my_signals; /* signals blocked by mf_brkhant */
|
||||
#endif
|
||||
|
|
|
@ -2197,7 +2197,7 @@ void STDCALL mysql_close(MYSQL *mysql)
|
|||
for (element= mysql->stmts; element; element= next_element)
|
||||
{
|
||||
next_element= element->next;
|
||||
stmt_close((MYSQL_STMT *)element->data, 0);
|
||||
stmt_close((MYSQL_STMT *)element->data, 0, 1);
|
||||
}
|
||||
mysql->stmts= 0;
|
||||
}
|
||||
|
|
112
sql/ha_innodb.cc
112
sql/ha_innodb.cc
|
@ -290,7 +290,7 @@ convert_error_code_to_mysql(
|
|||
|
||||
} else if (error == (int) DB_CANNOT_DROP_CONSTRAINT) {
|
||||
|
||||
return(HA_ERR_ROW_IS_REFERENCED);
|
||||
return(HA_ERR_ROW_IS_REFERENCED);
|
||||
|
||||
} else if (error == (int) DB_COL_APPEARS_TWICE_IN_INDEX) {
|
||||
|
||||
|
@ -755,7 +755,7 @@ innobase_init(void)
|
|||
srv_set_thread_priorities = TRUE;
|
||||
srv_query_thread_priority = QUERY_PRIOR;
|
||||
}
|
||||
|
||||
|
||||
/* Set InnoDB initialization parameters according to the values
|
||||
read from MySQL .cnf file */
|
||||
|
||||
|
@ -870,16 +870,22 @@ innobase_init(void)
|
|||
|
||||
srv_print_verbose_log = mysql_embedded ? 0 : 1;
|
||||
|
||||
if (strcmp(default_charset_info->name, "latin1") == 0) {
|
||||
/* Store the default charset-collation number of this MySQL
|
||||
installation */
|
||||
|
||||
/* Store the character ordering table to InnoDB.
|
||||
For non-latin1 charsets we use the MySQL comparison
|
||||
functions, and consequently we do not need to know
|
||||
the ordering internally in InnoDB. */
|
||||
data_mysql_default_charset_coll = (ulint)default_charset_info->number;
|
||||
|
||||
memcpy(srv_latin1_ordering,
|
||||
default_charset_info->sort_order, 256);
|
||||
}
|
||||
data_mysql_latin1_swedish_charset_coll =
|
||||
(ulint)my_charset_latin1.number;
|
||||
|
||||
/* Store the latin1_swedish_ci character ordering table to InnoDB. For
|
||||
non-latin1_swedish_ci charsets we use the MySQL comparison functions,
|
||||
and consequently we do not need to know the ordering internally in
|
||||
InnoDB. */
|
||||
|
||||
ut_a(0 == ut_strcmp((char*)my_charset_latin1.name,
|
||||
(char*)"latin1_swedish_ci"));
|
||||
memcpy(srv_latin1_ordering, my_charset_latin1.sort_order, 256);
|
||||
|
||||
/* Since we in this module access directly the fields of a trx
|
||||
struct, and due to different headers and flags it might happen that
|
||||
|
@ -1661,10 +1667,10 @@ reset_null_bits(
|
|||
|
||||
extern "C" {
|
||||
/*****************************************************************
|
||||
InnoDB uses this function is to compare two data fields for which the
|
||||
data type is such that we must use MySQL code to compare them. NOTE that the
|
||||
prototype of this function is in rem0cmp.c in InnoDB source code!
|
||||
If you change this function, remember to update the prototype there! */
|
||||
InnoDB uses this function to compare two data fields for which the data type
|
||||
is such that we must use MySQL code to compare them. NOTE that the prototype
|
||||
of this function is in rem0cmp.c in InnoDB source code! If you change this
|
||||
function, remember to update the prototype there! */
|
||||
|
||||
int
|
||||
innobase_mysql_cmp(
|
||||
|
@ -1672,6 +1678,7 @@ innobase_mysql_cmp(
|
|||
/* out: 1, 0, -1, if a is greater,
|
||||
equal, less than b, respectively */
|
||||
int mysql_type, /* in: MySQL type */
|
||||
uint charset_number, /* in: number of the charset */
|
||||
unsigned char* a, /* in: data field */
|
||||
unsigned int a_length, /* in: data field length,
|
||||
not UNIV_SQL_NULL */
|
||||
|
@ -1679,6 +1686,7 @@ innobase_mysql_cmp(
|
|||
unsigned int b_length) /* in: data field length,
|
||||
not UNIV_SQL_NULL */
|
||||
{
|
||||
CHARSET_INFO* charset;
|
||||
enum_field_types mysql_tp;
|
||||
int ret;
|
||||
|
||||
|
@ -1695,9 +1703,27 @@ innobase_mysql_cmp(
|
|||
case FIELD_TYPE_MEDIUM_BLOB:
|
||||
case FIELD_TYPE_BLOB:
|
||||
case FIELD_TYPE_LONG_BLOB:
|
||||
// BAR TODO: Discuss with heikki.tuuri@innodb.com
|
||||
// so that he sends CHARSET_INFO for the field to this function.
|
||||
ret = my_strnncoll(default_charset_info,
|
||||
/* Use the charset number to pick the right charset struct for
|
||||
the comparison. Since the MySQL function get_charset may be
|
||||
slow before Bar removes the mutex operation there, we first
|
||||
look at 2 common charsets directly. */
|
||||
|
||||
if (charset_number == default_charset_info->number) {
|
||||
charset = default_charset_info;
|
||||
} else if (charset_number == my_charset_latin1.number) {
|
||||
charset = &my_charset_latin1;
|
||||
} else {
|
||||
charset = get_charset(charset_number, MYF(MY_WME));
|
||||
|
||||
if (charset == NULL) {
|
||||
fprintf(stderr,
|
||||
"InnoDB: fatal error: InnoDB needs charset %lu for doing a comparison,\n"
|
||||
"InnoDB: but MySQL cannot find that charset.\n", (ulong)charset_number);
|
||||
ut_a(0);
|
||||
}
|
||||
}
|
||||
|
||||
ret = my_strnncoll(charset,
|
||||
a, a_length,
|
||||
b, b_length);
|
||||
if (ret < 0) {
|
||||
|
@ -1724,9 +1750,9 @@ get_innobase_type_from_mysql_type(
|
|||
/* out: DATA_BINARY, DATA_VARCHAR, ... */
|
||||
Field* field) /* in: MySQL field */
|
||||
{
|
||||
/* The following asserts check that the MySQL type code fits in
|
||||
8 bits: this is used in ibuf and also when DATA_NOT_NULL is
|
||||
ORed to the type */
|
||||
/* The following asserts try to check that the MySQL type code fits in
|
||||
8 bits: this is used in ibuf and also when DATA_NOT_NULL is ORed to
|
||||
the type */
|
||||
|
||||
DBUG_ASSERT((ulint)FIELD_TYPE_STRING < 256);
|
||||
DBUG_ASSERT((ulint)FIELD_TYPE_VAR_STRING < 256);
|
||||
|
@ -1741,8 +1767,8 @@ get_innobase_type_from_mysql_type(
|
|||
|
||||
return(DATA_BINARY);
|
||||
} else if (strcmp(
|
||||
default_charset_info->name,
|
||||
"latin1") == 0) {
|
||||
field->charset()->name,
|
||||
"latin1_swedish_ci") == 0) {
|
||||
return(DATA_VARCHAR);
|
||||
} else {
|
||||
return(DATA_VARMYSQL);
|
||||
|
@ -1751,8 +1777,8 @@ get_innobase_type_from_mysql_type(
|
|||
|
||||
return(DATA_FIXBINARY);
|
||||
} else if (strcmp(
|
||||
default_charset_info->name,
|
||||
"latin1") == 0) {
|
||||
field->charset()->name,
|
||||
"latin1_swedish_ci") == 0) {
|
||||
return(DATA_CHAR);
|
||||
} else {
|
||||
return(DATA_MYSQL);
|
||||
|
@ -3237,7 +3263,7 @@ create_table_def(
|
|||
ulint nulls_allowed;
|
||||
ulint unsigned_type;
|
||||
ulint binary_type;
|
||||
ulint nonlatin1_type;
|
||||
ulint charset_no;
|
||||
ulint i;
|
||||
|
||||
DBUG_ENTER("create_table_def");
|
||||
|
@ -3266,24 +3292,28 @@ create_table_def(
|
|||
unsigned_type = 0;
|
||||
}
|
||||
|
||||
if (col_type == DATA_BLOB
|
||||
&& strcmp(default_charset_info->name, "latin1") != 0) {
|
||||
nonlatin1_type = DATA_NONLATIN1;
|
||||
} else {
|
||||
nonlatin1_type = 0;
|
||||
}
|
||||
|
||||
if (field->binary()) {
|
||||
binary_type = DATA_BINARY_TYPE;
|
||||
nonlatin1_type = 0;
|
||||
} else {
|
||||
binary_type = 0;
|
||||
}
|
||||
|
||||
charset_no = 0;
|
||||
|
||||
if (dtype_is_string_type(col_type)) {
|
||||
|
||||
charset_no = (ulint)field->charset()->number;
|
||||
|
||||
ut_a(charset_no < 256); /* in ut0type.h we assume that
|
||||
the number fits in one byte */
|
||||
}
|
||||
|
||||
dict_mem_table_add_col(table, (char*) field->field_name,
|
||||
col_type, (ulint)field->type()
|
||||
col_type, dtype_form_prtype(
|
||||
(ulint)field->type()
|
||||
| nulls_allowed | unsigned_type
|
||||
| nonlatin1_type | binary_type,
|
||||
| binary_type,
|
||||
+ charset_no),
|
||||
field->pack_length(), 0);
|
||||
}
|
||||
|
||||
|
@ -3467,7 +3497,7 @@ ha_innobase::create(
|
|||
/* The limit probably should be REC_MAX_N_FIELDS - 3 = 1020,
|
||||
but we play safe here */
|
||||
|
||||
DBUG_RETURN(HA_ERR_TO_BIG_ROW);
|
||||
DBUG_RETURN(HA_ERR_TO_BIG_ROW);
|
||||
}
|
||||
|
||||
/* Get the transaction associated with the current thd, or create one
|
||||
|
@ -3681,7 +3711,7 @@ ha_innobase::delete_table(
|
|||
int error;
|
||||
trx_t* parent_trx;
|
||||
trx_t* trx;
|
||||
THD *thd= current_thd;
|
||||
THD *thd= current_thd;
|
||||
char norm_name[1000];
|
||||
|
||||
DBUG_ENTER("ha_innobase::delete_table");
|
||||
|
@ -4408,7 +4438,7 @@ ha_innobase::get_foreign_key_create_info(void)
|
|||
prebuilt->trx->op_info = (char*)"";
|
||||
|
||||
return(str);
|
||||
}
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
Checks if a table is referenced by a foreign key. The MySQL manual states that
|
||||
|
@ -4649,10 +4679,10 @@ ha_innobase::external_lock(
|
|||
if (trx->isolation_level == TRX_ISO_SERIALIZABLE
|
||||
&& prebuilt->select_lock_type == LOCK_NONE
|
||||
&& (thd->options
|
||||
& (OPTION_NOT_AUTOCOMMIT | OPTION_BEGIN))) {
|
||||
& (OPTION_NOT_AUTOCOMMIT | OPTION_BEGIN))) {
|
||||
|
||||
/* To get serializable execution, we let InnoDB
|
||||
conceptually add 'LOCK IN SHARE MODE' to all SELECTs
|
||||
/* To get serializable execution, we let InnoDB
|
||||
conceptually add 'LOCK IN SHARE MODE' to all SELECTs
|
||||
which otherwise would have been consistent reads. An
|
||||
exception is consistent reads in the AUTOCOMMIT=1 mode:
|
||||
we know that they are read-only transactions, and they
|
||||
|
|
|
@ -969,8 +969,10 @@ bool Item_field::fix_fields(THD *thd, TABLE_LIST *tables, Item **ref)
|
|||
|
||||
void Item_field::cleanup()
|
||||
{
|
||||
DBUG_ENTER("Item_field::cleanup");
|
||||
Item_ident::cleanup();
|
||||
field= result_field= 0;
|
||||
DBUG_VOID_RETURN;
|
||||
}
|
||||
|
||||
void Item::init_make_field(Send_field *tmp_field,
|
||||
|
@ -1613,9 +1615,11 @@ bool Item_ref::fix_fields(THD *thd,TABLE_LIST *tables, Item **reference)
|
|||
|
||||
void Item_ref::cleanup()
|
||||
{
|
||||
DBUG_ENTER("Item_ref::cleanup");
|
||||
Item_ident::cleanup();
|
||||
if (hook_ptr)
|
||||
*hook_ptr= orig_item;
|
||||
DBUG_VOID_RETURN;
|
||||
}
|
||||
|
||||
|
||||
|
|
25
sql/item.h
25
sql/item.h
|
@ -128,7 +128,13 @@ public:
|
|||
virtual ~Item() { name=0; } /*lint -e1509 */
|
||||
void set_name(const char *str,uint length, CHARSET_INFO *cs);
|
||||
void init_make_field(Send_field *tmp_field,enum enum_field_types type);
|
||||
virtual void cleanup() { fixed=0; }
|
||||
virtual void cleanup()
|
||||
{
|
||||
DBUG_ENTER("Item::cleanup");
|
||||
DBUG_PRINT("info", ("Type: %d", (int)type()));
|
||||
fixed=0;
|
||||
DBUG_VOID_RETURN;
|
||||
}
|
||||
virtual void make_field(Send_field *field);
|
||||
virtual bool fix_fields(THD *, struct st_table_list *, Item **);
|
||||
virtual int save_in_field(Field *field, bool no_conversions);
|
||||
|
@ -413,6 +419,7 @@ public:
|
|||
int save_in_field(Field *field, bool no_conversions);
|
||||
bool basic_const_item() const { return 1; }
|
||||
Item *new_item() { return new Item_int(name,value,max_length); }
|
||||
void cleanup() { fixed= 1; } // to prevent drop fixed flag
|
||||
void print(String *str);
|
||||
};
|
||||
|
||||
|
@ -900,6 +907,8 @@ public:
|
|||
enum Type type() const { return CACHE_ITEM; }
|
||||
static Item_cache* get_cache(Item_result type);
|
||||
table_map used_tables() const { return used_table_map; }
|
||||
virtual void keep_array() {}
|
||||
void cleanup() { fixed= 1; } // to prevent drop fixed flag
|
||||
void print(String *str);
|
||||
};
|
||||
|
||||
|
@ -952,8 +961,10 @@ class Item_cache_row: public Item_cache
|
|||
{
|
||||
Item_cache **values;
|
||||
uint item_count;
|
||||
bool save_array;
|
||||
public:
|
||||
Item_cache_row(): Item_cache(), values(0), item_count(2) {}
|
||||
Item_cache_row()
|
||||
:Item_cache(), values(0), item_count(2), save_array(0) {}
|
||||
|
||||
/*
|
||||
'allocate' used only in row transformer, to preallocate space for row
|
||||
|
@ -994,10 +1005,16 @@ public:
|
|||
bool check_cols(uint c);
|
||||
bool null_inside();
|
||||
void bring_value();
|
||||
void keep_array() { save_array= 1; }
|
||||
void cleanup()
|
||||
{
|
||||
DBUG_ENTER("Item_cache_row::cleanup");
|
||||
Item_cache::cleanup();
|
||||
values= 0;
|
||||
if (save_array)
|
||||
bzero(values, item_count*sizeof(Item**));
|
||||
else
|
||||
values= 0;
|
||||
DBUG_VOID_RETURN;
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -1023,8 +1040,10 @@ public:
|
|||
Field *example() { return field_example; }
|
||||
void cleanup()
|
||||
{
|
||||
DBUG_ENTER("Item_type_holder::cleanup");
|
||||
Item::cleanup();
|
||||
item_type= orig_type;
|
||||
DBUG_VOID_RETURN;
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
@ -500,7 +500,6 @@ bool Item_in_optimizer::fix_left(THD *thd,
|
|||
}
|
||||
|
||||
|
||||
|
||||
bool Item_in_optimizer::fix_fields(THD *thd, struct st_table_list *tables,
|
||||
Item ** ref)
|
||||
{
|
||||
|
@ -526,6 +525,7 @@ bool Item_in_optimizer::fix_fields(THD *thd, struct st_table_list *tables,
|
|||
return 0;
|
||||
}
|
||||
|
||||
|
||||
longlong Item_in_optimizer::val_int()
|
||||
{
|
||||
cache->store(args[0]);
|
||||
|
@ -539,18 +539,38 @@ longlong Item_in_optimizer::val_int()
|
|||
return tmp;
|
||||
}
|
||||
|
||||
|
||||
void Item_in_optimizer::keep_top_level_cache()
|
||||
{
|
||||
cache->keep_array();
|
||||
save_cache= 1;
|
||||
}
|
||||
|
||||
|
||||
void Item_in_optimizer::cleanup()
|
||||
{
|
||||
DBUG_ENTER("Item_in_optimizer::cleanup");
|
||||
Item_bool_func::cleanup();
|
||||
if (!save_cache)
|
||||
cache= 0;
|
||||
DBUG_VOID_RETURN;
|
||||
}
|
||||
|
||||
|
||||
bool Item_in_optimizer::is_null()
|
||||
{
|
||||
cache->store(args[0]);
|
||||
return (null_value= (cache->null_value || args[1]->is_null()));
|
||||
}
|
||||
|
||||
|
||||
longlong Item_func_eq::val_int()
|
||||
{
|
||||
int value= cmp.compare();
|
||||
return value == 0 ? 1 : 0;
|
||||
}
|
||||
|
||||
|
||||
/* Same as Item_func_eq, but NULL = NULL */
|
||||
|
||||
void Item_func_equal::fix_length_and_dec()
|
||||
|
|
|
@ -93,9 +93,10 @@ class Item_in_optimizer: public Item_bool_func
|
|||
{
|
||||
protected:
|
||||
Item_cache *cache;
|
||||
bool save_cache;
|
||||
public:
|
||||
Item_in_optimizer(Item *a, Item_in_subselect *b):
|
||||
Item_bool_func(a, (Item *)b), cache(0) {}
|
||||
Item_bool_func(a, (Item *)b), cache(0), save_cache(0) {}
|
||||
bool fix_fields(THD *, struct st_table_list *, Item **);
|
||||
bool fix_left(THD *thd, struct st_table_list *tables, Item **ref);
|
||||
bool is_null();
|
||||
|
@ -107,8 +108,10 @@ public:
|
|||
Item_in_optimizer return NULL, else it evaluate Item_in_subselect.
|
||||
*/
|
||||
longlong val_int();
|
||||
void cleanup();
|
||||
const char *func_name() const { return "<in_optimizer>"; }
|
||||
Item_cache **get_cache() { return &cache; }
|
||||
void keep_top_level_cache();
|
||||
};
|
||||
|
||||
class Comp_creator
|
||||
|
@ -209,9 +212,11 @@ public:
|
|||
}
|
||||
void cleanup()
|
||||
{
|
||||
DBUG_ENTER("Item_bool_rowready_func2::cleanup");
|
||||
Item_bool_func2::cleanup();
|
||||
tmp_arg[0]= orig_a;
|
||||
tmp_arg[1]= orig_b;
|
||||
DBUG_VOID_RETURN;
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -720,10 +725,12 @@ class Item_func_in :public Item_int_func
|
|||
void fix_length_and_dec();
|
||||
void cleanup()
|
||||
{
|
||||
DBUG_ENTER("Item_func_in::cleanup");
|
||||
delete array;
|
||||
delete in_item;
|
||||
array= 0;
|
||||
in_item= 0;
|
||||
DBUG_VOID_RETURN;
|
||||
}
|
||||
optimize_type select_optimize() const
|
||||
{ return array ? OPTIMIZE_KEY : OPTIMIZE_NONE; }
|
||||
|
|
|
@ -999,6 +999,7 @@ public:
|
|||
join_key(0), ft_handler(0), table(0), master(0), concat(0) { }
|
||||
void cleanup()
|
||||
{
|
||||
DBUG_ENTER("Item_func_match");
|
||||
if (!master && ft_handler)
|
||||
{
|
||||
ft_handler->please->close_search(ft_handler);
|
||||
|
@ -1008,7 +1009,11 @@ public:
|
|||
table->fulltext_searched=0;
|
||||
}
|
||||
if (concat)
|
||||
{
|
||||
delete concat;
|
||||
concat= 0;
|
||||
}
|
||||
DBUG_VOID_RETURN;
|
||||
}
|
||||
enum Functype functype() const { return FT_FUNC; }
|
||||
const char *func_name() const { return "match"; }
|
||||
|
|
|
@ -35,9 +35,9 @@ inline Item * and_items(Item* cond, Item *item)
|
|||
}
|
||||
|
||||
Item_subselect::Item_subselect():
|
||||
Item_result_field(), value_assigned(0), substitution(0),
|
||||
engine(0), used_tables_cache(0), have_to_be_excluded(0),
|
||||
const_item_cache(1), engine_changed(0)
|
||||
Item_result_field(), value_assigned(0), thd(0), substitution(0),
|
||||
engine(0), old_engine(0), used_tables_cache(0), have_to_be_excluded(0),
|
||||
const_item_cache(1), engine_changed(0), changed(0)
|
||||
{
|
||||
reset();
|
||||
/*
|
||||
|
@ -54,10 +54,10 @@ void Item_subselect::init(st_select_lex *select_lex,
|
|||
|
||||
DBUG_ENTER("Item_subselect::init");
|
||||
DBUG_PRINT("subs", ("select_lex 0x%xl", (ulong) select_lex));
|
||||
unit= select_lex->master_unit();
|
||||
|
||||
if (select_lex->next_select())
|
||||
engine= new subselect_union_engine(select_lex->master_unit(), result,
|
||||
this);
|
||||
engine= new subselect_union_engine(unit, result, this);
|
||||
else
|
||||
engine= new subselect_single_select_engine(select_lex, result, this);
|
||||
DBUG_VOID_RETURN;
|
||||
|
@ -65,8 +65,26 @@ void Item_subselect::init(st_select_lex *select_lex,
|
|||
|
||||
void Item_subselect::cleanup()
|
||||
{
|
||||
DBUG_ENTER("Item_subselect::cleanup");
|
||||
Item_result_field::cleanup();
|
||||
engine->cleanup();
|
||||
if (old_engine)
|
||||
{
|
||||
engine->cleanup();
|
||||
engine= old_engine;
|
||||
old_engine= 0;
|
||||
}
|
||||
engine->cleanup();
|
||||
reset();
|
||||
value_assigned= 0;
|
||||
DBUG_VOID_RETURN;
|
||||
}
|
||||
|
||||
void Item_singlerow_subselect::cleanup()
|
||||
{
|
||||
DBUG_ENTER("Item_singlerow_subselect::cleanup");
|
||||
value= 0; row= 0;
|
||||
Item_subselect::cleanup();
|
||||
DBUG_VOID_RETURN;
|
||||
}
|
||||
|
||||
Item_subselect::~Item_subselect()
|
||||
|
@ -85,13 +103,22 @@ Item_subselect::select_transformer(JOIN *join)
|
|||
bool Item_subselect::fix_fields(THD *thd_param, TABLE_LIST *tables, Item **ref)
|
||||
{
|
||||
engine->set_thd((thd= thd_param));
|
||||
stmt= thd->current_statement;
|
||||
|
||||
char const *save_where= thd->where;
|
||||
int res= engine->prepare();
|
||||
|
||||
// all transformetion is done (used by prepared statements)
|
||||
changed= 1;
|
||||
|
||||
if (!res)
|
||||
{
|
||||
if (substitution)
|
||||
{
|
||||
// did we changed top item of WHERE condition
|
||||
if (unit->outer_select()->where == (*ref))
|
||||
unit->outer_select()->where= substitution; // correct WHERE for PS
|
||||
|
||||
(*ref)= substitution;
|
||||
substitution->name= name;
|
||||
if (have_to_be_excluded)
|
||||
|
@ -240,8 +267,12 @@ void Item_singlerow_subselect::reset()
|
|||
Item_subselect::trans_res
|
||||
Item_singlerow_subselect::select_transformer(JOIN *join)
|
||||
{
|
||||
if (changed)
|
||||
return RES_OK;
|
||||
|
||||
SELECT_LEX *select_lex= join->select_lex;
|
||||
|
||||
Statement backup;
|
||||
|
||||
if (!select_lex->master_unit()->first_select()->next_select() &&
|
||||
!select_lex->table_list.elements &&
|
||||
select_lex->item_list.elements == 1 &&
|
||||
|
@ -275,20 +306,30 @@ Item_singlerow_subselect::select_transformer(JOIN *join)
|
|||
if (join->conds || join->having)
|
||||
{
|
||||
Item *cond;
|
||||
if (stmt)
|
||||
thd->set_n_backup_item_arena(stmt, &backup);
|
||||
|
||||
if (!join->having)
|
||||
cond= join->conds;
|
||||
else if (!join->conds)
|
||||
cond= join->having;
|
||||
else
|
||||
if (!(cond= new Item_cond_and(join->conds, join->having)))
|
||||
return RES_ERROR;
|
||||
goto err;
|
||||
if (!(substitution= new Item_func_if(cond, substitution,
|
||||
new Item_null())))
|
||||
return RES_ERROR;
|
||||
goto err;
|
||||
}
|
||||
if (stmt)
|
||||
thd->restore_backup_item_arena(stmt, &backup);
|
||||
return RES_REDUCE;
|
||||
}
|
||||
return RES_OK;
|
||||
|
||||
err:
|
||||
if (stmt)
|
||||
thd->restore_backup_item_arena(stmt, &backup);
|
||||
return RES_ERROR;
|
||||
}
|
||||
|
||||
void Item_singlerow_subselect::store(uint i, Item *item)
|
||||
|
@ -550,15 +591,22 @@ Item_in_subselect::single_value_transformer(JOIN *join,
|
|||
{
|
||||
DBUG_ENTER("Item_in_subselect::single_value_transformer");
|
||||
|
||||
SELECT_LEX *select_lex= join->select_lex;
|
||||
if (changed)
|
||||
{
|
||||
DBUG_RETURN(RES_OK);
|
||||
}
|
||||
|
||||
THD *thd_tmp= join->thd;
|
||||
thd_tmp->where= "scalar IN/ALL/ANY subquery";
|
||||
SELECT_LEX *select_lex= join->select_lex;
|
||||
Statement backup;
|
||||
|
||||
thd->where= "scalar IN/ALL/ANY subquery";
|
||||
if (stmt)
|
||||
thd->set_n_backup_item_arena(stmt, &backup);
|
||||
|
||||
if (select_lex->item_list.elements > 1)
|
||||
{
|
||||
my_error(ER_OPERAND_COLUMNS, MYF(0), 1);
|
||||
DBUG_RETURN(RES_ERROR);
|
||||
goto err;
|
||||
}
|
||||
|
||||
if ((abort_on_null || (upper_not && upper_not->top_level())) &&
|
||||
|
@ -567,7 +615,7 @@ Item_in_subselect::single_value_transformer(JOIN *join,
|
|||
if (substitution)
|
||||
{
|
||||
// It is second (third, ...) SELECT of UNION => All is done
|
||||
DBUG_RETURN(RES_OK);
|
||||
goto ok;
|
||||
}
|
||||
|
||||
Item *subs;
|
||||
|
@ -597,10 +645,9 @@ Item_in_subselect::single_value_transformer(JOIN *join,
|
|||
select_lex->item_list.empty();
|
||||
select_lex->item_list.push_back(item);
|
||||
|
||||
if (item->fix_fields(thd_tmp, join->tables_list, &item))
|
||||
{
|
||||
DBUG_RETURN(RES_ERROR);
|
||||
}
|
||||
if (item->fix_fields(thd, join->tables_list, &item))
|
||||
goto err;
|
||||
|
||||
subs= new Item_singlerow_subselect(select_lex);
|
||||
}
|
||||
else
|
||||
|
@ -611,16 +658,16 @@ Item_in_subselect::single_value_transformer(JOIN *join,
|
|||
subs= new Item_maxmin_subselect(this, select_lex, func->l_op());
|
||||
}
|
||||
// left expression belong to outer select
|
||||
SELECT_LEX *current= thd_tmp->lex->current_select, *up;
|
||||
thd_tmp->lex->current_select= up= current->return_after_parsing();
|
||||
if (left_expr->fix_fields(thd_tmp, up->get_table_list(), &left_expr))
|
||||
SELECT_LEX *current= thd->lex->current_select, *up;
|
||||
thd->lex->current_select= up= current->return_after_parsing();
|
||||
if (left_expr->fix_fields(thd, up->get_table_list(), &left_expr))
|
||||
{
|
||||
thd_tmp->lex->current_select= current;
|
||||
DBUG_RETURN(RES_ERROR);
|
||||
thd->lex->current_select= current;
|
||||
goto err;
|
||||
}
|
||||
thd_tmp->lex->current_select= current;
|
||||
thd->lex->current_select= current;
|
||||
substitution= func->create(left_expr, subs);
|
||||
DBUG_RETURN(RES_OK);
|
||||
goto ok;
|
||||
}
|
||||
|
||||
if (!substitution)
|
||||
|
@ -629,16 +676,16 @@ Item_in_subselect::single_value_transformer(JOIN *join,
|
|||
SELECT_LEX_UNIT *unit= select_lex->master_unit();
|
||||
substitution= optimizer= new Item_in_optimizer(left_expr, this);
|
||||
|
||||
SELECT_LEX *current= thd_tmp->lex->current_select, *up;
|
||||
SELECT_LEX *current= thd->lex->current_select, *up;
|
||||
|
||||
thd_tmp->lex->current_select= up= current->return_after_parsing();
|
||||
thd->lex->current_select= up= current->return_after_parsing();
|
||||
//optimizer never use Item **ref => we can pass 0 as parameter
|
||||
if (!optimizer || optimizer->fix_left(thd_tmp, up->get_table_list(), 0))
|
||||
if (!optimizer || optimizer->fix_left(thd, up->get_table_list(), 0))
|
||||
{
|
||||
thd_tmp->lex->current_select= current;
|
||||
DBUG_RETURN(RES_ERROR);
|
||||
thd->lex->current_select= current;
|
||||
goto err;
|
||||
}
|
||||
thd_tmp->lex->current_select= current;
|
||||
thd->lex->current_select= current;
|
||||
|
||||
/*
|
||||
As far as Item_ref_in_optimizer do not substitude itself on fix_fields
|
||||
|
@ -665,12 +712,17 @@ Item_in_subselect::single_value_transformer(JOIN *join,
|
|||
select_lex->ref_pointer_array,
|
||||
(char *)"<ref>",
|
||||
this->full_name()));
|
||||
join->having= and_items(join->having, item);
|
||||
/*
|
||||
AND and comparison functions can't be changed during fix_fields()
|
||||
we can assign select_lex->having here, and pass 0 as last
|
||||
argument (reference) to fix_fields()
|
||||
*/
|
||||
select_lex->having= join->having= and_items(join->having, item);
|
||||
select_lex->having_fix_field= 1;
|
||||
if (join->having->fix_fields(thd_tmp, join->tables_list, &join->having))
|
||||
if (join->having->fix_fields(thd, join->tables_list, 0))
|
||||
{
|
||||
select_lex->having_fix_field= 0;
|
||||
DBUG_RETURN(RES_ERROR);
|
||||
goto err;
|
||||
}
|
||||
select_lex->having_fix_field= 0;
|
||||
}
|
||||
|
@ -687,39 +739,56 @@ Item_in_subselect::single_value_transformer(JOIN *join,
|
|||
if (!abort_on_null)
|
||||
{
|
||||
having= new Item_is_not_null_test(this, having);
|
||||
join->having= (join->having ?
|
||||
new Item_cond_and(having, join->having) :
|
||||
having);
|
||||
/*
|
||||
Item_is_not_null_test can't be changed during fix_fields()
|
||||
we can assign select_lex->having here, and pass 0 as last
|
||||
argument (reference) to fix_fields()
|
||||
*/
|
||||
select_lex->having=
|
||||
join->having= (join->having ?
|
||||
new Item_cond_and(having, join->having) :
|
||||
having);
|
||||
select_lex->having_fix_field= 1;
|
||||
if (join->having->fix_fields(thd_tmp, join->tables_list,
|
||||
&join->having))
|
||||
if (join->having->fix_fields(thd, join->tables_list, 0))
|
||||
{
|
||||
select_lex->having_fix_field= 0;
|
||||
DBUG_RETURN(RES_ERROR);
|
||||
goto err;
|
||||
}
|
||||
select_lex->having_fix_field= 0;
|
||||
item= new Item_cond_or(item,
|
||||
new Item_func_isnull(isnull));
|
||||
}
|
||||
item->name= (char *)in_additional_cond;
|
||||
join->conds= and_items(join->conds, item);
|
||||
if (join->conds->fix_fields(thd_tmp, join->tables_list, &join->conds))
|
||||
DBUG_RETURN(RES_ERROR);
|
||||
/*
|
||||
AND can't be changed during fix_fields()
|
||||
we can assign select_lex->having here, and pass 0 as last
|
||||
argument (reference) to fix_fields()
|
||||
*/
|
||||
select_lex->where= join->conds= and_items(join->conds, item);
|
||||
if (join->conds->fix_fields(thd, join->tables_list, 0))
|
||||
goto err;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (select_lex->master_unit()->first_select()->next_select())
|
||||
{
|
||||
join->having= func->create(expr,
|
||||
new Item_null_helper(this, item,
|
||||
(char *)"<no matter>",
|
||||
(char *)"<result>"));
|
||||
/*
|
||||
comparison functions can't be changed during fix_fields()
|
||||
we can assign select_lex->having here, and pass 0 as last
|
||||
argument (reference) to fix_fields()
|
||||
*/
|
||||
select_lex->having=
|
||||
join->having=
|
||||
func->create(expr,
|
||||
new Item_null_helper(this, item,
|
||||
(char *)"<no matter>",
|
||||
(char *)"<result>"));
|
||||
select_lex->having_fix_field= 1;
|
||||
if (join->having->fix_fields(thd_tmp, join->tables_list,
|
||||
&join->having))
|
||||
if (join->having->fix_fields(thd, join->tables_list,
|
||||
0))
|
||||
{
|
||||
select_lex->having_fix_field= 0;
|
||||
DBUG_RETURN(RES_ERROR);
|
||||
goto err;
|
||||
}
|
||||
select_lex->having_fix_field= 0;
|
||||
}
|
||||
|
@ -730,18 +799,29 @@ Item_in_subselect::single_value_transformer(JOIN *join,
|
|||
// fix_field of item will be done in time of substituting
|
||||
substitution= item;
|
||||
have_to_be_excluded= 1;
|
||||
if (thd_tmp->lex->describe)
|
||||
if (thd->lex->describe)
|
||||
{
|
||||
char warn_buff[MYSQL_ERRMSG_SIZE];
|
||||
sprintf(warn_buff, ER(ER_SELECT_REDUCED), select_lex->select_number);
|
||||
push_warning(thd_tmp, MYSQL_ERROR::WARN_LEVEL_NOTE,
|
||||
push_warning(thd, MYSQL_ERROR::WARN_LEVEL_NOTE,
|
||||
ER_SELECT_REDUCED, warn_buff);
|
||||
}
|
||||
if (stmt)
|
||||
thd->restore_backup_item_arena(stmt, &backup);
|
||||
DBUG_RETURN(RES_REDUCE);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ok:
|
||||
if (stmt)
|
||||
thd->restore_backup_item_arena(stmt, &backup);
|
||||
DBUG_RETURN(RES_OK);
|
||||
|
||||
err:
|
||||
if (stmt)
|
||||
thd->restore_backup_item_arena(stmt, &backup);
|
||||
DBUG_RETURN(RES_ERROR);
|
||||
}
|
||||
|
||||
|
||||
|
@ -750,15 +830,23 @@ Item_in_subselect::row_value_transformer(JOIN *join)
|
|||
{
|
||||
DBUG_ENTER("Item_in_subselect::row_value_transformer");
|
||||
|
||||
THD *thd_tmp= join->thd;
|
||||
thd_tmp->where= "row IN/ALL/ANY subquery";
|
||||
if (changed)
|
||||
{
|
||||
DBUG_RETURN(RES_OK);
|
||||
}
|
||||
Statement backup;
|
||||
Item *item= 0;
|
||||
|
||||
thd->where= "row IN/ALL/ANY subquery";
|
||||
if (stmt)
|
||||
thd->set_n_backup_item_arena(stmt, &backup);
|
||||
|
||||
SELECT_LEX *select_lex= join->select_lex;
|
||||
|
||||
if (select_lex->item_list.elements != left_expr->cols())
|
||||
{
|
||||
my_error(ER_OPERAND_COLUMNS, MYF(0), left_expr->cols());
|
||||
DBUG_RETURN(RES_ERROR);
|
||||
goto err;
|
||||
}
|
||||
|
||||
if (!substitution)
|
||||
|
@ -767,62 +855,82 @@ Item_in_subselect::row_value_transformer(JOIN *join)
|
|||
SELECT_LEX_UNIT *unit= select_lex->master_unit();
|
||||
substitution= optimizer= new Item_in_optimizer(left_expr, this);
|
||||
|
||||
SELECT_LEX *current= thd_tmp->lex->current_select, *up;
|
||||
thd_tmp->lex->current_select= up= current->return_after_parsing();
|
||||
SELECT_LEX *current= thd->lex->current_select, *up;
|
||||
thd->lex->current_select= up= current->return_after_parsing();
|
||||
//optimizer never use Item **ref => we can pass 0 as parameter
|
||||
if (!optimizer || optimizer->fix_left(thd_tmp, up->get_table_list(), 0))
|
||||
if (!optimizer || optimizer->fix_left(thd, up->get_table_list(), 0))
|
||||
{
|
||||
thd_tmp->lex->current_select= current;
|
||||
DBUG_RETURN(RES_ERROR);
|
||||
thd->lex->current_select= current;
|
||||
goto err;
|
||||
}
|
||||
thd_tmp->lex->current_select= current;
|
||||
|
||||
// we will refer to apper level cache array => we have to save it in PS
|
||||
optimizer->keep_top_level_cache();
|
||||
|
||||
thd->lex->current_select= current;
|
||||
unit->uncacheable|= UNCACHEABLE_DEPENDENT;
|
||||
}
|
||||
|
||||
uint n= left_expr->cols();
|
||||
|
||||
select_lex->uncacheable|= UNCACHEABLE_DEPENDENT;
|
||||
select_lex->setup_ref_array(thd_tmp,
|
||||
select_lex->setup_ref_array(thd,
|
||||
select_lex->order_list.elements +
|
||||
select_lex->group_list.elements);
|
||||
Item *item= 0;
|
||||
List_iterator_fast<Item> li(select_lex->item_list);
|
||||
for (uint i= 0; i < n; i++)
|
||||
{
|
||||
Item *func= new Item_ref_null_helper(this,
|
||||
select_lex->ref_pointer_array+i,
|
||||
(char *) "<no matter>",
|
||||
(char *) "<list ref>");
|
||||
func=
|
||||
eq_creator.create(new Item_ref((*optimizer->get_cache())->
|
||||
addr(i),
|
||||
NULL,
|
||||
(char *)"<no matter>",
|
||||
uint n= left_expr->cols();
|
||||
List_iterator_fast<Item> li(select_lex->item_list);
|
||||
for (uint i= 0; i < n; i++)
|
||||
{
|
||||
Item *func= new Item_ref_null_helper(this,
|
||||
select_lex->ref_pointer_array+i,
|
||||
(char *) "<no matter>",
|
||||
(char *) "<list ref>");
|
||||
func=
|
||||
eq_creator.create(new Item_ref((*optimizer->get_cache())->
|
||||
addr(i),
|
||||
NULL,
|
||||
(char *)"<no matter>",
|
||||
(char *)in_left_expr_name),
|
||||
func);
|
||||
item= and_items(item, func);
|
||||
func);
|
||||
item= and_items(item, func);
|
||||
}
|
||||
}
|
||||
|
||||
if (join->having || select_lex->with_sum_func ||
|
||||
select_lex->group_list.first ||
|
||||
!select_lex->table_list.elements)
|
||||
{
|
||||
join->having= and_items(join->having, item);
|
||||
/*
|
||||
AND can't be changed during fix_fields()
|
||||
we can assign select_lex->having here, and pass 0 as last
|
||||
argument (reference) to fix_fields()
|
||||
*/
|
||||
select_lex->having= join->having= and_items(join->having, item);
|
||||
select_lex->having_fix_field= 1;
|
||||
if (join->having->fix_fields(thd_tmp, join->tables_list, &join->having))
|
||||
if (join->having->fix_fields(thd, join->tables_list, 0))
|
||||
{
|
||||
select_lex->having_fix_field= 0;
|
||||
DBUG_RETURN(RES_ERROR);
|
||||
goto err;
|
||||
}
|
||||
select_lex->having_fix_field= 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
join->conds= and_items(join->conds, item);
|
||||
if (join->conds->fix_fields(thd_tmp, join->tables_list, &join->having))
|
||||
DBUG_RETURN(RES_ERROR);
|
||||
/*
|
||||
AND can't be changed during fix_fields()
|
||||
we can assign select_lex->having here, and pass 0 as last
|
||||
argument (reference) to fix_fields()
|
||||
*/
|
||||
select_lex->where= join->conds= and_items(join->conds, item);
|
||||
if (join->conds->fix_fields(thd, join->tables_list, 0))
|
||||
goto err;
|
||||
}
|
||||
if (stmt)
|
||||
thd->restore_backup_item_arena(stmt, &backup);
|
||||
DBUG_RETURN(RES_OK);
|
||||
|
||||
err:
|
||||
if (stmt)
|
||||
thd->restore_backup_item_arena(stmt, &backup);
|
||||
DBUG_RETURN(RES_ERROR);
|
||||
}
|
||||
|
||||
|
||||
|
@ -894,13 +1002,31 @@ subselect_single_select_engine(st_select_lex *select,
|
|||
this->select_lex= select_lex;
|
||||
}
|
||||
|
||||
|
||||
void subselect_single_select_engine::cleanup()
|
||||
{
|
||||
prepared= 0;
|
||||
optimized= 0;
|
||||
executed= 0;
|
||||
DBUG_ENTER("subselect_single_select_engine::cleanup");
|
||||
prepared= optimized= executed= 0;
|
||||
join= 0;
|
||||
DBUG_VOID_RETURN;
|
||||
}
|
||||
|
||||
|
||||
void subselect_union_engine::cleanup()
|
||||
{
|
||||
DBUG_ENTER("subselect_union_engine::cleanup");
|
||||
unit->reinit_exec_mechanism();
|
||||
DBUG_VOID_RETURN;
|
||||
}
|
||||
|
||||
|
||||
void subselect_uniquesubquery_engine::cleanup()
|
||||
{
|
||||
DBUG_ENTER("subselect_uniquesubquery_engine::cleanup");
|
||||
DBUG_VOID_RETURN;
|
||||
}
|
||||
|
||||
|
||||
subselect_union_engine::subselect_union_engine(st_select_lex_unit *u,
|
||||
select_subselect *result_arg,
|
||||
Item_subselect *item_arg)
|
||||
|
|
|
@ -26,6 +26,7 @@ class JOIN;
|
|||
class select_subselect;
|
||||
class subselect_engine;
|
||||
class Item_bool_func2;
|
||||
class Statement;
|
||||
|
||||
/* base class for subselects */
|
||||
|
||||
|
@ -35,22 +36,30 @@ class Item_subselect :public Item_result_field
|
|||
protected:
|
||||
/* thread handler, will be assigned in fix_fields only */
|
||||
THD *thd;
|
||||
/* prepared statement, or 0 */
|
||||
Statement *stmt;
|
||||
/* substitution instead of subselect in case of optimization */
|
||||
Item *substitution;
|
||||
/* unit of subquery */
|
||||
st_select_lex_unit *unit;
|
||||
/* engine that perform execution of subselect (single select or union) */
|
||||
subselect_engine *engine;
|
||||
/* old engine if engine was changed */
|
||||
subselect_engine *old_engine;
|
||||
/* cache of used external tables */
|
||||
table_map used_tables_cache;
|
||||
/* allowed number of columns (1 for single value subqueries) */
|
||||
uint max_columns;
|
||||
/* work with 'substitution' */
|
||||
bool have_to_be_excluded;
|
||||
/* cache of constante state */
|
||||
/* cache of constant state */
|
||||
bool const_item_cache;
|
||||
|
||||
public:
|
||||
/* changed engine indicator */
|
||||
bool engine_changed;
|
||||
/* subquery is transformed */
|
||||
bool changed;
|
||||
|
||||
enum trans_res {RES_OK, RES_REDUCE, RES_ERROR};
|
||||
enum subs_type {UNKNOWN_SUBS, SINGLEROW_SUBS,
|
||||
|
@ -94,6 +103,7 @@ public:
|
|||
void print(String *str);
|
||||
bool change_engine(subselect_engine *eng)
|
||||
{
|
||||
old_engine= engine;
|
||||
engine= eng;
|
||||
engine_changed= 1;
|
||||
return eng == 0;
|
||||
|
@ -116,6 +126,7 @@ public:
|
|||
Item_singlerow_subselect(st_select_lex *select_lex);
|
||||
Item_singlerow_subselect() :Item_subselect(), value(0), row (0) {}
|
||||
|
||||
void cleanup();
|
||||
subs_type substype() { return SINGLEROW_SUBS; }
|
||||
|
||||
void reset();
|
||||
|
@ -200,13 +211,6 @@ public:
|
|||
|
||||
{}
|
||||
|
||||
void cleanup()
|
||||
{
|
||||
Item_exists_subselect::cleanup();
|
||||
abort_on_null= 0;
|
||||
transformed= 0;
|
||||
upper_not= 0;
|
||||
}
|
||||
subs_type substype() { return IN_SUBS; }
|
||||
void reset()
|
||||
{
|
||||
|
@ -269,7 +273,7 @@ public:
|
|||
maybe_null= 0;
|
||||
}
|
||||
virtual ~subselect_engine() {}; // to satisfy compiler
|
||||
virtual void cleanup() {}
|
||||
virtual void cleanup()= 0;
|
||||
|
||||
// set_thd should be called before prepare()
|
||||
void set_thd(THD *thd_arg) { thd= thd_arg; }
|
||||
|
@ -318,6 +322,7 @@ public:
|
|||
subselect_union_engine(st_select_lex_unit *u,
|
||||
select_subselect *result,
|
||||
Item_subselect *item);
|
||||
void cleanup();
|
||||
int prepare();
|
||||
void fix_length_and_dec(Item_cache** row);
|
||||
int exec();
|
||||
|
@ -345,6 +350,7 @@ public:
|
|||
set_thd(thd_arg);
|
||||
}
|
||||
~subselect_uniquesubquery_engine();
|
||||
void cleanup();
|
||||
int prepare();
|
||||
void fix_length_and_dec(Item_cache** row);
|
||||
int exec();
|
||||
|
|
|
@ -1084,6 +1084,7 @@ int dump_leaf(byte* key, uint32 count __attribute__((unused)),
|
|||
|
||||
void Item_sum_count_distinct::cleanup()
|
||||
{
|
||||
DBUG_ENTER("Item_sum_count_distinct::cleanup");
|
||||
Item_sum_int::cleanup();
|
||||
/*
|
||||
Free table and tree if they belong to this item (if item have not pointer
|
||||
|
@ -1104,6 +1105,7 @@ void Item_sum_count_distinct::cleanup()
|
|||
use_tree= 0;
|
||||
}
|
||||
}
|
||||
DBUG_VOID_RETURN;
|
||||
}
|
||||
|
||||
|
||||
|
@ -1672,6 +1674,7 @@ Item_func_group_concat::Item_func_group_concat(bool is_distinct,
|
|||
|
||||
void Item_func_group_concat::cleanup()
|
||||
{
|
||||
DBUG_ENTER("Item_func_group_concat::cleanup");
|
||||
/*
|
||||
Free table and tree if they belong to this item (if item have not pointer
|
||||
to original item from which was made copy => it own its objects )
|
||||
|
@ -1692,6 +1695,7 @@ void Item_func_group_concat::cleanup()
|
|||
delete_tree(tree);
|
||||
}
|
||||
}
|
||||
DBUG_VOID_RETURN;
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -60,8 +60,10 @@ public:
|
|||
Item_sum(THD *thd, Item_sum *item);
|
||||
void cleanup()
|
||||
{
|
||||
DBUG_ENTER("Item_sum::cleanup");
|
||||
Item_result_field::cleanup();
|
||||
result_field=0;
|
||||
DBUG_VOID_RETURN;
|
||||
}
|
||||
|
||||
enum Type type() const { return SUM_FUNC_ITEM; }
|
||||
|
|
|
@ -350,6 +350,11 @@ inline THD *_current_thd(void)
|
|||
#include "sql_udf.h"
|
||||
#include "item.h"
|
||||
typedef Comp_creator* (*chooser_compare_func_creator)(bool invert);
|
||||
/* sql_parse.cc */
|
||||
void free_items(Item *item);
|
||||
void cleanup_items(Item *item);
|
||||
class THD;
|
||||
void close_thread_tables(THD *thd, bool locked=0, bool skip_derived=0);
|
||||
#include "sql_class.h"
|
||||
#include "opt_range.h"
|
||||
|
||||
|
@ -411,7 +416,6 @@ bool mysql_rename_tables(THD *thd, TABLE_LIST *table_list);
|
|||
bool mysql_change_db(THD *thd,const char *name);
|
||||
void mysql_parse(THD *thd,char *inBuf,uint length);
|
||||
bool is_update_query(enum enum_sql_command command);
|
||||
void free_items(Item *item);
|
||||
bool alloc_query(THD *thd, char *packet, ulong packet_length);
|
||||
void mysql_init_select(LEX *lex);
|
||||
void mysql_init_query(THD *thd);
|
||||
|
@ -688,7 +692,6 @@ bool rm_temporary_table(enum db_type base, char *path);
|
|||
void free_io_cache(TABLE *entry);
|
||||
void intern_close_table(TABLE *entry);
|
||||
bool close_thread_table(THD *thd, TABLE **table_ptr);
|
||||
void close_thread_tables(THD *thd, bool locked=0, bool skip_derived=0);
|
||||
void close_temporary_tables(THD *thd);
|
||||
TABLE_LIST * find_table_in_list(TABLE_LIST *table,
|
||||
const char *db_name, const char *table_name);
|
||||
|
@ -766,9 +769,6 @@ uint check_word(TYPELIB *lib, const char *val, const char *end,
|
|||
|
||||
bool is_keyword(const char *name, uint len);
|
||||
|
||||
/* sql_parse.cc */
|
||||
void free_items(Item *item);
|
||||
void cleanup_items(Item *item);
|
||||
|
||||
#define MY_DB_OPT_FILE "db.opt"
|
||||
bool load_db_opt(THD *thd, const char *path, HA_CREATE_INFO *create);
|
||||
|
@ -779,7 +779,8 @@ bool load_db_opt(THD *thd, const char *path, HA_CREATE_INFO *create);
|
|||
|
||||
extern time_t start_time;
|
||||
extern char *mysql_data_home,server_version[SERVER_VERSION_LENGTH],
|
||||
mysql_real_data_home[], *opt_mysql_tmpdir, mysql_charsets_dir[];
|
||||
mysql_real_data_home[], *opt_mysql_tmpdir, mysql_charsets_dir[],
|
||||
opt_ft_boolean_syntax[sizeof(ft_boolean_syntax)];
|
||||
#define mysql_tmpdir (my_tmpdir(&mysql_tmpdir_list))
|
||||
extern MY_TMPDIR mysql_tmpdir_list;
|
||||
extern const char *command_name[];
|
||||
|
|
162
sql/mysqld.cc
162
sql/mysqld.cc
|
@ -183,9 +183,6 @@ inline void reset_floating_point_exceptions()
|
|||
#else
|
||||
#include <my_pthread.h> // For thr_setconcurency()
|
||||
#endif
|
||||
#if defined(HAVE_GETRLIMIT) && defined(RLIMIT_NOFILE) && !defined(HAVE_mit_thread)
|
||||
#define SET_RLIMIT_NOFILE
|
||||
#endif
|
||||
|
||||
#ifdef SOLARIS
|
||||
extern "C" int gethostname(char *name, int namelen);
|
||||
|
@ -318,7 +315,8 @@ char* log_error_file_ptr= log_error_file;
|
|||
char mysql_real_data_home[FN_REFLEN],
|
||||
language[LIBLEN],reg_ext[FN_EXTLEN], mysql_charsets_dir[FN_REFLEN],
|
||||
max_sort_char,*mysqld_user,*mysqld_chroot, *opt_init_file,
|
||||
*opt_init_connect, *opt_init_slave;
|
||||
*opt_init_connect, *opt_init_slave,
|
||||
opt_ft_boolean_syntax[sizeof(ft_boolean_syntax)];
|
||||
|
||||
const char *opt_date_time_formats[3];
|
||||
|
||||
|
@ -492,9 +490,6 @@ extern "C" pthread_handler_decl(handle_connections_namedpipes,arg);
|
|||
static pthread_handler_decl(handle_connections_shared_memory,arg);
|
||||
#endif
|
||||
extern "C" pthread_handler_decl(handle_slave,arg);
|
||||
#ifdef SET_RLIMIT_NOFILE
|
||||
static uint set_maximum_open_files(uint max_file_limit);
|
||||
#endif
|
||||
static ulong find_bit_type(const char *x, TYPELIB *bit_lib);
|
||||
static void clean_up(bool print_message);
|
||||
static void clean_up_mutexes(void);
|
||||
|
@ -919,6 +914,7 @@ void clean_up(bool print_message)
|
|||
#ifdef USE_RAID
|
||||
end_raid();
|
||||
#endif
|
||||
my_free_open_file_info();
|
||||
my_free((char*) global_system_variables.date_format,
|
||||
MYF(MY_ALLOW_ZERO_PTR));
|
||||
my_free((char*) global_system_variables.time_format,
|
||||
|
@ -2108,28 +2104,32 @@ static int init_common_variables(const char *conf_file_name, int argc,
|
|||
DBUG_PRINT("info",("%s Ver %s for %s on %s\n",my_progname,
|
||||
server_version, SYSTEM_TYPE,MACHINE_TYPE));
|
||||
|
||||
#if defined( SET_RLIMIT_NOFILE) || defined( OS2)
|
||||
/* connections and databases needs lots of files */
|
||||
{
|
||||
uint wanted_files=10+(uint) max(max_connections*5,
|
||||
max_connections+table_cache_size*2);
|
||||
uint files, wanted_files;
|
||||
|
||||
wanted_files= 10+(uint) max(max_connections*5,
|
||||
max_connections+table_cache_size*2);
|
||||
set_if_bigger(wanted_files, open_files_limit);
|
||||
// Note that some system returns 0 if we succeed here:
|
||||
uint files=set_maximum_open_files(wanted_files);
|
||||
if (files && files < wanted_files && ! open_files_limit)
|
||||
files= my_set_max_open_files(wanted_files);
|
||||
|
||||
if (files < wanted_files)
|
||||
{
|
||||
max_connections= (ulong) min((files-10),max_connections);
|
||||
table_cache_size= (ulong) max((files-10-max_connections)/2,64);
|
||||
DBUG_PRINT("warning",
|
||||
("Changed limits: max_connections: %ld table_cache: %ld",
|
||||
max_connections,table_cache_size));
|
||||
sql_print_error("Warning: Changed limits: max_connections: %ld table_cache: %ld",max_connections,table_cache_size);
|
||||
if (!open_files_limit)
|
||||
{
|
||||
max_connections= (ulong) min((files-10),max_connections);
|
||||
table_cache_size= (ulong) max((files-10-max_connections)/2,64);
|
||||
DBUG_PRINT("warning",
|
||||
("Changed limits: max_open_files: %u max_connections: %ld table_cache: %ld",
|
||||
files, max_connections, table_cache_size));
|
||||
sql_print_error("Warning: Changed limits: max_open_files: %u max_connections: %ld table_cache: %ld",
|
||||
files, max_connections, table_cache_size);
|
||||
}
|
||||
else
|
||||
sql_print_error("Warning: Could not increase number of max_open_files to more than %u (request: %u)", files, wanted_files);
|
||||
}
|
||||
open_files_limit= files;
|
||||
}
|
||||
#else
|
||||
open_files_limit= 0; /* Can't set or detect limit */
|
||||
#endif
|
||||
unireg_init(opt_specialflag); /* Set up extern variabels */
|
||||
if (init_errmessage()) /* Read error messages from file */
|
||||
return 1;
|
||||
|
@ -3603,7 +3603,7 @@ enum options_mysqld
|
|||
OPT_BACK_LOG, OPT_BINLOG_CACHE_SIZE,
|
||||
OPT_CONNECT_TIMEOUT, OPT_DELAYED_INSERT_TIMEOUT,
|
||||
OPT_DELAYED_INSERT_LIMIT, OPT_DELAYED_QUEUE_SIZE,
|
||||
OPT_FLUSH_TIME, OPT_FT_MIN_WORD_LEN,
|
||||
OPT_FLUSH_TIME, OPT_FT_MIN_WORD_LEN, OPT_FT_BOOLEAN_SYNTAX,
|
||||
OPT_FT_MAX_WORD_LEN, OPT_FT_QUERY_EXPANSION_LIMIT, OPT_FT_STOPWORD_FILE,
|
||||
OPT_INTERACTIVE_TIMEOUT, OPT_JOIN_BUFF_SIZE,
|
||||
OPT_KEY_BUFFER_SIZE, OPT_KEY_CACHE_BLOCK_SIZE,
|
||||
|
@ -3926,7 +3926,8 @@ Disable with --skip-bdb (will save memory).",
|
|||
0, 0, 0, 0},
|
||||
{"master-password", OPT_MASTER_PASSWORD,
|
||||
"The password the slave thread will authenticate with when connecting to the master. If not set, an empty password is assumed.The value in master.info will take precedence if it can be read.",
|
||||
0, 0, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
|
||||
(gptr*)&master_password, (gptr*)&master_password, 0,
|
||||
GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
|
||||
{"master-port", OPT_MASTER_PORT,
|
||||
"The port the master is listening on. If not set, the compiled setting of MYSQL_PORT is assumed. If you have not tinkered with configure options, this should be 3306. The value in master.info will take precedence if it can be read.",
|
||||
(gptr*) &master_port, (gptr*) &master_port, 0, GET_UINT, REQUIRED_ARG,
|
||||
|
@ -4257,6 +4258,10 @@ replicating a LOAD DATA INFILE command.",
|
|||
"A dedicated thread is created to flush all tables at the given interval.",
|
||||
(gptr*) &flush_time, (gptr*) &flush_time, 0, GET_ULONG, REQUIRED_ARG,
|
||||
FLUSH_TIME, 0, LONG_TIMEOUT, 0, 1, 0},
|
||||
{ "ft_boolean_syntax", OPT_FT_BOOLEAN_SYNTAX,
|
||||
"List of operators for MATCH ... AGAINST ( ... IN BOOLEAN MODE)",
|
||||
0, 0, 0, GET_STR,
|
||||
REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
|
||||
{ "ft_min_word_len", OPT_FT_MIN_WORD_LEN,
|
||||
"The minimum length of the word to be included in a FULLTEXT index. Note: FULLTEXT indexes must be rebuilt after changing this variable.",
|
||||
(gptr*) &ft_min_word_len, (gptr*) &ft_min_word_len, 0, GET_ULONG,
|
||||
|
@ -4506,7 +4511,7 @@ The minimum value for this variable is 4096.",
|
|||
{"open_files_limit", OPT_OPEN_FILES_LIMIT,
|
||||
"If this is not 0, then mysqld will use this value to reserve file descriptors to use with setrlimit(). If this value is 0 then mysqld will reserve max_connections*5 or max_connections + table_cache*2 (whichever is larger) number of files.",
|
||||
(gptr*) &open_files_limit, (gptr*) &open_files_limit, 0, GET_ULONG,
|
||||
REQUIRED_ARG, 0, 0, 65535, 0, 1, 0},
|
||||
REQUIRED_ARG, 0, 0, OS_FILE_LIMIT, 0, 1, 0},
|
||||
{"preload_buffer_size", OPT_PRELOAD_BUFFER_SIZE,
|
||||
"The size of the buffer that is allocated when preloading indexes",
|
||||
(gptr*) &global_system_variables.preload_buff_size,
|
||||
|
@ -5435,8 +5440,8 @@ get_one_option(int optid, const struct my_option *opt __attribute__((unused)),
|
|||
break;
|
||||
case OPT_STORAGE_ENGINE:
|
||||
{
|
||||
if ((enum db_type)((global_system_variables.table_type=
|
||||
ha_resolve_by_name(argument, strlen(argument)))) == DB_TYPE_UNKNOWN)
|
||||
if ((enum db_type)((global_system_variables.table_type=
|
||||
ha_resolve_by_name(argument, strlen(argument)))) == DB_TYPE_UNKNOWN)
|
||||
{
|
||||
fprintf(stderr,"Unknown table type: %s\n",argument);
|
||||
exit(1);
|
||||
|
@ -5608,8 +5613,13 @@ get_one_option(int optid, const struct my_option *opt __attribute__((unused)),
|
|||
global_system_variables.sql_mode= fix_sql_mode(global_system_variables.
|
||||
sql_mode);
|
||||
}
|
||||
case OPT_MASTER_PASSWORD:
|
||||
master_password=argument;
|
||||
case OPT_FT_BOOLEAN_SYNTAX:
|
||||
if (ft_boolean_check_syntax_string(argument))
|
||||
{
|
||||
fprintf(stderr, "Invalid ft-boolean-syntax string: %s\n", argument);
|
||||
exit(1);
|
||||
}
|
||||
strmake(opt_ft_boolean_syntax, argument, sizeof(ft_boolean_syntax)-1);
|
||||
break;
|
||||
case OPT_SKIP_SAFEMALLOC:
|
||||
#ifdef SAFEMALLOC
|
||||
|
@ -5658,6 +5668,8 @@ static void get_options(int argc,char **argv)
|
|||
int ho_error;
|
||||
|
||||
my_getopt_register_get_addr(mysql_getopt_value);
|
||||
strmake(opt_ft_boolean_syntax, ft_boolean_syntax,
|
||||
sizeof(ft_boolean_syntax)-1);
|
||||
if ((ho_error=handle_options(&argc, &argv, my_long_options, get_one_option)))
|
||||
exit(ho_error);
|
||||
if (argc > 0)
|
||||
|
@ -5713,6 +5725,9 @@ static void get_options(int argc,char **argv)
|
|||
table_alias_charset= (lower_case_table_names ?
|
||||
files_charset_info :
|
||||
&my_charset_bin);
|
||||
strmake(ft_boolean_syntax, opt_ft_boolean_syntax,
|
||||
sizeof(ft_boolean_syntax)-1);
|
||||
|
||||
if (opt_short_log_format)
|
||||
opt_specialflag|= SPECIAL_SHORT_LOG_FORMAT;
|
||||
if (opt_log_queries_not_using_indexes)
|
||||
|
@ -5812,95 +5827,6 @@ static void fix_paths(void)
|
|||
}
|
||||
|
||||
|
||||
/*
|
||||
set how many open files we want to be able to handle
|
||||
|
||||
SYNOPSIS
|
||||
set_maximum_open_files()
|
||||
max_file_limit Files to open
|
||||
|
||||
NOTES
|
||||
The request may not fulfilled becasue of system limitations
|
||||
|
||||
RETURN
|
||||
Files available to open
|
||||
*/
|
||||
|
||||
#ifdef SET_RLIMIT_NOFILE
|
||||
|
||||
#ifndef RLIM_INFINITY
|
||||
#define RLIM_INFINITY ((uint) 0xffffffff)
|
||||
#endif
|
||||
|
||||
static uint set_maximum_open_files(uint max_file_limit)
|
||||
{
|
||||
struct rlimit rlimit;
|
||||
uint old_cur;
|
||||
DBUG_ENTER("set_maximum_open_files");
|
||||
DBUG_PRINT("enter",("files: %u", max_file_limit));
|
||||
|
||||
if (!getrlimit(RLIMIT_NOFILE,&rlimit))
|
||||
{
|
||||
old_cur= (uint) rlimit.rlim_cur;
|
||||
DBUG_PRINT("info", ("rlim_cur: %u rlim_max: %u",
|
||||
(uint) rlimit.rlim_cur,
|
||||
(uint) rlimit.rlim_max));
|
||||
if (rlimit.rlim_cur >= max_file_limit ||
|
||||
rlimit.rlim_cur == RLIM_INFINITY)
|
||||
DBUG_RETURN(rlimit.rlim_cur); /* purecov: inspected */
|
||||
rlimit.rlim_cur= rlimit.rlim_max= max_file_limit;
|
||||
if (setrlimit(RLIMIT_NOFILE,&rlimit))
|
||||
{
|
||||
if (global_system_variables.log_warnings)
|
||||
sql_print_error("Warning: setrlimit couldn't increase number of open files to more than %u (request: %u)",
|
||||
old_cur, max_file_limit); /* purecov: inspected */
|
||||
max_file_limit= old_cur;
|
||||
}
|
||||
else
|
||||
{
|
||||
rlimit.rlim_cur= 0; // Safety if next call fails
|
||||
(void) getrlimit(RLIMIT_NOFILE,&rlimit);
|
||||
DBUG_PRINT("info", ("rlim_cur: %u", (uint) rlimit.rlim_cur));
|
||||
if ((uint) rlimit.rlim_cur < max_file_limit &&
|
||||
global_system_variables.log_warnings)
|
||||
sql_print_error("Warning: setrlimit returned ok, but didn't change limits. Max open files is %u (request: %u)",
|
||||
(uint) rlimit.rlim_cur,
|
||||
max_file_limit); /* purecov: inspected */
|
||||
max_file_limit= (uint) rlimit.rlim_cur;
|
||||
}
|
||||
}
|
||||
DBUG_PRINT("exit",("max_file_limit: %u", max_file_limit));
|
||||
DBUG_RETURN(max_file_limit);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
#ifdef OS2
|
||||
static uint set_maximum_open_files(uint max_file_limit)
|
||||
{
|
||||
LONG cbReqCount;
|
||||
ULONG cbCurMaxFH, cbCurMaxFH0;
|
||||
APIRET ulrc;
|
||||
DBUG_ENTER("set_maximum_open_files");
|
||||
|
||||
// get current limit
|
||||
cbReqCount = 0;
|
||||
DosSetRelMaxFH( &cbReqCount, &cbCurMaxFH0);
|
||||
|
||||
// set new limit
|
||||
cbReqCount = max_file_limit - cbCurMaxFH0;
|
||||
ulrc = DosSetRelMaxFH( &cbReqCount, &cbCurMaxFH);
|
||||
if (ulrc) {
|
||||
sql_print_error("Warning: DosSetRelMaxFH couldn't increase number of open files to more than %d",
|
||||
cbCurMaxFH0);
|
||||
cbCurMaxFH = cbCurMaxFH0;
|
||||
}
|
||||
|
||||
DBUG_RETURN(cbCurMaxFH);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
/*
|
||||
Return a bitfield from a string of substrings separated by ','
|
||||
returns ~(ulong) 0 on error.
|
||||
|
|
|
@ -19,18 +19,18 @@
|
|||
|
||||
To add a new variable, one has to do the following:
|
||||
|
||||
- If the variable is thread specific, add it to 'system_variables' struct.
|
||||
If not, add it to mysqld.cc and an declaration in 'mysql_priv.h'
|
||||
- Don't forget to initialize new fields in global_system_variables and
|
||||
max_system_variables!
|
||||
- Use one of the 'sys_var... classes from set_var.h or write a specific
|
||||
one for the variable type.
|
||||
- Define it in the 'variable definition list' in this file.
|
||||
- If the variable should be changeable or one should be able to access it
|
||||
with @@variable_name, it should be added to the 'list of all variables'
|
||||
list in this file.
|
||||
list (sys_variables) in this file.
|
||||
- If the variable is thread specific, add it to 'system_variables' struct.
|
||||
If not, add it to mysqld.cc and an declaration in 'mysql_priv.h'
|
||||
- If the variable should be changed from the command line, add a definition
|
||||
of it in the my_option structure list in mysqld.dcc
|
||||
- Don't forget to initialize new fields in global_system_variables and
|
||||
max_system_variables!
|
||||
- If the variable should show up in 'show variables' add it to the
|
||||
init_vars[] struct in this file
|
||||
|
||||
|
@ -73,9 +73,12 @@ TYPELIB delay_key_write_typelib=
|
|||
array_elements(delay_key_write_type_names)-1, "", delay_key_write_type_names
|
||||
};
|
||||
|
||||
static bool sys_check_charset(THD *thd, set_var *var);
|
||||
static int sys_check_charset(THD *thd, set_var *var);
|
||||
static bool sys_update_charset(THD *thd, set_var *var);
|
||||
static void sys_set_default_charset(THD *thd, enum_var_type type);
|
||||
static int sys_check_ftb_syntax(THD *thd, set_var *var);
|
||||
static bool sys_update_ftb_syntax(THD *thd, set_var * var);
|
||||
static void sys_default_ftb_syntax(THD *thd, enum_var_type type);
|
||||
static bool sys_update_init_connect(THD*, set_var*);
|
||||
static void sys_default_init_connect(THD*, enum_var_type type);
|
||||
static bool sys_update_init_slave(THD*, set_var*);
|
||||
|
@ -119,12 +122,6 @@ sys_var_str sys_charset_system("character_set_system",
|
|||
sys_check_charset,
|
||||
sys_update_charset,
|
||||
sys_set_default_charset);
|
||||
sys_var_str sys_init_connect("init_connect", 0,
|
||||
sys_update_init_connect,
|
||||
sys_default_init_connect);
|
||||
sys_var_str sys_init_slave("init_slave", 0,
|
||||
sys_update_init_slave,
|
||||
sys_default_init_slave);
|
||||
sys_var_character_set_database sys_character_set_database("character_set_database");
|
||||
sys_var_character_set_client sys_character_set_client("character_set_client");
|
||||
sys_var_character_set_connection sys_character_set_connection("character_set_connection");
|
||||
|
@ -150,6 +147,16 @@ sys_var_long_ptr sys_expire_logs_days("expire_logs_days",
|
|||
&expire_logs_days);
|
||||
sys_var_bool_ptr sys_flush("flush", &myisam_flush);
|
||||
sys_var_long_ptr sys_flush_time("flush_time", &flush_time);
|
||||
sys_var_str sys_ft_boolean_syntax("ft_boolean_syntax",
|
||||
sys_check_ftb_syntax,
|
||||
sys_update_ftb_syntax,
|
||||
sys_default_ftb_syntax);
|
||||
sys_var_str sys_init_connect("init_connect", 0,
|
||||
sys_update_init_connect,
|
||||
sys_default_init_connect);
|
||||
sys_var_str sys_init_slave("init_slave", 0,
|
||||
sys_update_init_slave,
|
||||
sys_default_init_slave);
|
||||
sys_var_thd_ulong sys_interactive_timeout("interactive_timeout",
|
||||
&SV::net_interactive_timeout);
|
||||
sys_var_thd_ulong sys_join_buffer_size("join_buffer_size",
|
||||
|
@ -318,7 +325,7 @@ sys_var_thd_ulong sys_net_wait_timeout("wait_timeout",
|
|||
#ifdef HAVE_INNOBASE_DB
|
||||
sys_var_long_ptr sys_innodb_max_dirty_pages_pct("innodb_max_dirty_pages_pct",
|
||||
&srv_max_buf_pool_modified_pct);
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/* Time/date/datetime formats */
|
||||
|
||||
|
@ -450,6 +457,7 @@ sys_var *sys_variables[]=
|
|||
&sys_expire_logs_days,
|
||||
&sys_flush,
|
||||
&sys_flush_time,
|
||||
&sys_ft_boolean_syntax,
|
||||
&sys_foreign_key_checks,
|
||||
&sys_group_concat_max_len,
|
||||
&sys_identity,
|
||||
|
@ -593,7 +601,7 @@ struct show_var_st init_vars[]= {
|
|||
{sys_expire_logs_days.name, (char*) &sys_expire_logs_days, SHOW_SYS},
|
||||
{sys_flush.name, (char*) &sys_flush, SHOW_SYS},
|
||||
{sys_flush_time.name, (char*) &sys_flush_time, SHOW_SYS},
|
||||
{"ft_boolean_syntax", (char*) ft_boolean_syntax, SHOW_CHAR},
|
||||
{sys_ft_boolean_syntax.name,(char*) &ft_boolean_syntax, SHOW_CHAR},
|
||||
{"ft_min_word_len", (char*) &ft_min_word_len, SHOW_LONG},
|
||||
{"ft_max_word_len", (char*) &ft_max_word_len, SHOW_LONG},
|
||||
{"ft_query_expansion_limit",(char*) &ft_query_expansion_limit, SHOW_LONG},
|
||||
|
@ -775,6 +783,18 @@ bool sys_var::check(THD *thd, set_var *var)
|
|||
return 0;
|
||||
}
|
||||
|
||||
bool sys_var_str::check(THD *thd, set_var *var)
|
||||
{
|
||||
int res;
|
||||
if (!check_func)
|
||||
return 0;
|
||||
|
||||
if ((res=(*check_func)(thd, var)) < 0)
|
||||
my_error(ER_WRONG_VALUE_FOR_VAR, MYF(0), name,
|
||||
var->value->str_value.ptr());
|
||||
return res;
|
||||
}
|
||||
|
||||
/*
|
||||
Functions to check and update variables
|
||||
*/
|
||||
|
@ -837,13 +857,37 @@ static void sys_default_init_slave(THD* thd, enum_var_type type)
|
|||
update_sys_var_str(&sys_init_slave, &LOCK_sys_init_slave, 0);
|
||||
}
|
||||
|
||||
static int sys_check_ftb_syntax(THD *thd, set_var *var)
|
||||
{
|
||||
if (thd->master_access & SUPER_ACL)
|
||||
return ft_boolean_check_syntax_string(var->value->str_value.c_ptr()) ?
|
||||
-1 : 0;
|
||||
else
|
||||
{
|
||||
my_error(ER_SPECIFIC_ACCESS_DENIED_ERROR, MYF(0), "SUPER");
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
static bool sys_update_ftb_syntax(THD *thd, set_var * var)
|
||||
{
|
||||
strmake(ft_boolean_syntax, var->value->str_value.c_ptr(),
|
||||
sizeof(ft_boolean_syntax)-1);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void sys_default_ftb_syntax(THD *thd, enum_var_type type)
|
||||
{
|
||||
strmake(ft_boolean_syntax, opt_ft_boolean_syntax,
|
||||
sizeof(ft_boolean_syntax)-1);
|
||||
}
|
||||
|
||||
/*
|
||||
The following 3 functions need to be changed in 4.1 when we allow
|
||||
one to change character sets
|
||||
*/
|
||||
|
||||
static bool sys_check_charset(THD *thd, set_var *var)
|
||||
static int sys_check_charset(THD *thd, set_var *var)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
@ -1898,7 +1942,7 @@ byte *sys_var_key_cache_param::value_ptr(THD *thd, enum_var_type type,
|
|||
key_cache= &zero_key_cache;
|
||||
return (byte*) key_cache + offset ;
|
||||
}
|
||||
|
||||
|
||||
|
||||
bool sys_var_key_buffer_size::update(THD *thd, set_var *var)
|
||||
{
|
||||
|
@ -1993,14 +2037,14 @@ bool sys_var_key_cache_long::update(THD *thd, set_var *var)
|
|||
|
||||
pthread_mutex_lock(&LOCK_global_system_variables);
|
||||
KEY_CACHE *key_cache= get_key_cache(base_name);
|
||||
|
||||
|
||||
if (!key_cache && !(key_cache= create_key_cache(base_name->str,
|
||||
base_name->length)))
|
||||
{
|
||||
error= 1;
|
||||
goto end;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
Abort if some other thread is changing the key cache
|
||||
TODO: This should be changed so that we wait until the previous
|
||||
|
|
|
@ -35,7 +35,7 @@ enum enum_var_type
|
|||
OPT_DEFAULT, OPT_SESSION, OPT_GLOBAL
|
||||
};
|
||||
|
||||
typedef bool (*sys_check_func)(THD *, set_var *);
|
||||
typedef int (*sys_check_func)(THD *, set_var *);
|
||||
typedef bool (*sys_update_func)(THD *, set_var *);
|
||||
typedef void (*sys_after_update_func)(THD *,enum_var_type);
|
||||
typedef void (*sys_set_default_func)(THD *, enum_var_type);
|
||||
|
@ -143,10 +143,7 @@ public:
|
|||
:sys_var(name_arg), check_func(check_func_arg),
|
||||
update_func(update_func_arg),set_default_func(set_default_func_arg)
|
||||
{}
|
||||
bool check(THD *thd, set_var *var)
|
||||
{
|
||||
return check_func ? (*check_func)(thd, var) : 0;
|
||||
}
|
||||
bool check(THD *thd, set_var *var);
|
||||
bool update(THD *thd, set_var *var)
|
||||
{
|
||||
return (*update_func)(thd, var);
|
||||
|
|
|
@ -72,9 +72,9 @@ character-set=latin1
|
|||
"Not unique table/alias: '%-.64s'",
|
||||
"Invalid default value for '%-.64s'",
|
||||
"Multiple primary key defined",
|
||||
"Too many keys specified. Max %d keys allowed",
|
||||
"Too many keys specified; max %d keys allowed",
|
||||
"Too many key parts specified. Max %d parts allowed",
|
||||
"Specified key was too long. Max key length is %d",
|
||||
"Specified key was too long; max key length is %d bytes",
|
||||
"Key column '%-.64s' doesn't exist in table",
|
||||
"BLOB column '%-.64s' can't be used in key specification with the used table type",
|
||||
"Too big column length for column '%-.64s' (max = %d). Use BLOB instead",
|
||||
|
|
|
@ -76,7 +76,7 @@ character-set=koi8r
|
|||
"Указано несколько первичных ключей",
|
||||
"Указано слишком много ключей. Разрешается указывать не более %d ключей",
|
||||
"Указано слишком много частей составного ключа. Разрешается указывать не более %d частей",
|
||||
"Указан слишком длинный ключ. Максимальная длина ключа составляет %d",
|
||||
"Указан слишком длинный ключ. Максимальная длина ключа составляет %d байт",
|
||||
"Ключевой столбец '%-.64s' в таблице не существует",
|
||||
"Столбец типа BLOB '%-.64s' не может быть использован как значение ключа в таблице такого типа",
|
||||
"Слишком большая длина столбца '%-.64s' (максимум = %d). Используйте тип BLOB вместо текущего",
|
||||
|
|
|
@ -79,7 +79,7 @@ character-set=koi8u
|
|||
"Первинного ключа визначено неодноразово",
|
||||
"Забагато ключ╕в зазначено. Дозволено не б╕льше %d ключ╕в",
|
||||
"Забагато частин ключа зазначено. Дозволено не б╕льше %d частин",
|
||||
"ת<><D7AA><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>. מ<><D79E><EFBFBD>¦<EFBFBD><C2A6><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD> %d",
|
||||
"ת<><D7AA><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>. מ<><D79E><EFBFBD>¦<EFBFBD><C2A6><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD> %d <20><><EFBFBD><EFBFBD>¦<EFBFBD>",
|
||||
"Ключовий стовбець '%-.64s' не ╕сну╓ у таблиц╕",
|
||||
"BLOB стовбець '%-.64s' не може бути використаний у визначенн╕ ключа в цьому тип╕ таблиц╕",
|
||||
"Задовга довжина стовбця '%-.64s' (max = %d). Використайте тип BLOB",
|
||||
|
|
|
@ -2080,6 +2080,14 @@ int setup_wild(THD *thd, TABLE_LIST *tables, List<Item> &fields,
|
|||
{
|
||||
if (!wild_num)
|
||||
return 0;
|
||||
Statement *stmt= thd->current_statement, backup;
|
||||
|
||||
/*
|
||||
If we are in preparing prepared statement phase then we have change
|
||||
temporary mem_root to statement mem root to save changes of SELECT list
|
||||
*/
|
||||
if (stmt)
|
||||
thd->set_n_backup_item_arena(stmt, &backup);
|
||||
reg2 Item *item;
|
||||
List_iterator<Item> it(fields);
|
||||
while ( wild_num && (item= it++))
|
||||
|
@ -2091,7 +2099,11 @@ int setup_wild(THD *thd, TABLE_LIST *tables, List<Item> &fields,
|
|||
uint elem= fields.elements;
|
||||
if (insert_fields(thd,tables,((Item_field*) item)->db_name,
|
||||
((Item_field*) item)->table_name, &it))
|
||||
{
|
||||
if (stmt)
|
||||
thd->restore_backup_item_arena(stmt, &backup);
|
||||
return (-1);
|
||||
}
|
||||
if (sum_func_list)
|
||||
{
|
||||
/*
|
||||
|
@ -2104,6 +2116,8 @@ int setup_wild(THD *thd, TABLE_LIST *tables, List<Item> &fields,
|
|||
wild_num--;
|
||||
}
|
||||
}
|
||||
if (stmt)
|
||||
thd->restore_backup_item_arena(stmt, &backup);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
@ -83,7 +83,7 @@ extern "C" void free_user_var(user_var_entry *entry)
|
|||
** Thread specific functions
|
||||
****************************************************************************/
|
||||
|
||||
THD::THD():user_time(0), is_fatal_error(0),
|
||||
THD::THD():user_time(0), current_statement(0), is_fatal_error(0),
|
||||
last_insert_id_used(0),
|
||||
insert_id_used(0), rand_used(0), in_lock_tables(0),
|
||||
global_read_lock(0), bootstrap(0)
|
||||
|
@ -1247,6 +1247,27 @@ void Statement::set_statement(Statement *stmt)
|
|||
}
|
||||
|
||||
|
||||
void Statement::set_n_backup_item_arena(Statement *set, Statement *backup)
|
||||
{
|
||||
backup->set_item_arena(this);
|
||||
set_item_arena(set);
|
||||
}
|
||||
|
||||
|
||||
void Statement::restore_backup_item_arena(Statement *set, Statement *backup)
|
||||
{
|
||||
set->set_item_arena(this);
|
||||
set_item_arena(backup);
|
||||
// reset backup mem_root to avoid its freeing
|
||||
init_alloc_root(&backup->mem_root, 0, 0);
|
||||
}
|
||||
|
||||
void Statement::set_item_arena(Statement *set)
|
||||
{
|
||||
mem_root= set->mem_root;
|
||||
free_list= set->free_list;
|
||||
}
|
||||
|
||||
Statement::~Statement()
|
||||
{
|
||||
free_root(&mem_root, MYF(0));
|
||||
|
|
|
@ -427,7 +427,7 @@ class Statement
|
|||
public:
|
||||
/* FIXME: must be private */
|
||||
LEX main_lex;
|
||||
public:
|
||||
|
||||
/*
|
||||
Uniquely identifies each statement object in thread scope; change during
|
||||
statement lifetime. FIXME: must be const
|
||||
|
@ -476,7 +476,7 @@ public:
|
|||
char *query;
|
||||
uint32 query_length; // current query length
|
||||
/*
|
||||
List of items created in the parser for this query. Every item puts
|
||||
List of items created in the parser for this query. Every item puts
|
||||
itself to the list on creation (see Item::Item() for details))
|
||||
*/
|
||||
Item *free_list;
|
||||
|
@ -503,6 +503,32 @@ public:
|
|||
void set_statement(Statement *stmt);
|
||||
/* return class type */
|
||||
virtual Type type() const;
|
||||
|
||||
inline gptr alloc(unsigned int size) { return alloc_root(&mem_root,size); }
|
||||
inline gptr calloc(unsigned int size)
|
||||
{
|
||||
gptr ptr;
|
||||
if ((ptr=alloc_root(&mem_root,size)))
|
||||
bzero((char*) ptr,size);
|
||||
return ptr;
|
||||
}
|
||||
inline char *strdup(const char *str)
|
||||
{ return strdup_root(&mem_root,str); }
|
||||
inline char *strmake(const char *str, uint size)
|
||||
{ return strmake_root(&mem_root,str,size); }
|
||||
inline char *memdup(const char *str, uint size)
|
||||
{ return memdup_root(&mem_root,str,size); }
|
||||
inline char *memdup_w_gap(const char *str, uint size, uint gap)
|
||||
{
|
||||
gptr ptr;
|
||||
if ((ptr=alloc_root(&mem_root,size+gap)))
|
||||
memcpy(ptr,str,size);
|
||||
return ptr;
|
||||
}
|
||||
|
||||
void set_n_backup_item_arena(Statement *set, Statement *backup);
|
||||
void restore_backup_item_arena(Statement *set, Statement *backup);
|
||||
void Statement::set_item_arena(Statement *set);
|
||||
};
|
||||
|
||||
|
||||
|
@ -689,6 +715,10 @@ public:
|
|||
#ifdef SIGNAL_WITH_VIO_CLOSE
|
||||
Vio* active_vio;
|
||||
#endif
|
||||
/*
|
||||
Current prepared Statement if there one, or 0
|
||||
*/
|
||||
Statement *current_statement;
|
||||
/*
|
||||
next_insert_id is set on SET INSERT_ID= #. This is used as the next
|
||||
generated auto_increment value in handler.cc
|
||||
|
@ -850,34 +880,14 @@ public:
|
|||
return 0;
|
||||
#endif
|
||||
}
|
||||
inline gptr alloc(unsigned int size) { return alloc_root(&mem_root,size); }
|
||||
inline gptr calloc(unsigned int size)
|
||||
{
|
||||
gptr ptr;
|
||||
if ((ptr=alloc_root(&mem_root,size)))
|
||||
bzero((char*) ptr,size);
|
||||
return ptr;
|
||||
}
|
||||
inline char *strdup(const char *str)
|
||||
{ return strdup_root(&mem_root,str); }
|
||||
inline char *strmake(const char *str, uint size)
|
||||
{ return strmake_root(&mem_root,str,size); }
|
||||
inline char *memdup(const char *str, uint size)
|
||||
{ return memdup_root(&mem_root,str,size); }
|
||||
inline char *memdup_w_gap(const char *str, uint size, uint gap)
|
||||
{
|
||||
gptr ptr;
|
||||
if ((ptr=alloc_root(&mem_root,size+gap)))
|
||||
memcpy(ptr,str,size);
|
||||
return ptr;
|
||||
}
|
||||
bool convert_string(LEX_STRING *to, CHARSET_INFO *to_cs,
|
||||
const char *from, uint from_length,
|
||||
CHARSET_INFO *from_cs);
|
||||
inline gptr trans_alloc(unsigned int size)
|
||||
{
|
||||
return alloc_root(&transaction.mem_root,size);
|
||||
}
|
||||
|
||||
bool convert_string(LEX_STRING *to, CHARSET_INFO *to_cs,
|
||||
const char *from, uint from_length,
|
||||
CHARSET_INFO *from_cs);
|
||||
void add_changed_table(TABLE *table);
|
||||
void add_changed_table(const char *key, long key_length);
|
||||
CHANGED_TABLE_LIST * changed_table_dup(const char *key, long key_length);
|
||||
|
@ -900,6 +910,33 @@ public:
|
|||
}
|
||||
inline CHARSET_INFO *charset() { return variables.character_set_client; }
|
||||
void update_charset();
|
||||
|
||||
inline void allocate_temporary_memory_pool_for_ps_preparing()
|
||||
{
|
||||
DBUG_ASSERT(current_statement!=0);
|
||||
/*
|
||||
We do not want to have in PS memory all that junk,
|
||||
which will be created by preparation => substitute memory
|
||||
from original thread pool.
|
||||
|
||||
We know that PS memory pool is now copied to THD, we move it back
|
||||
to allow some code use it.
|
||||
*/
|
||||
current_statement->set_item_arena(this);
|
||||
init_sql_alloc(&mem_root,
|
||||
variables.query_alloc_block_size,
|
||||
variables.query_prealloc_size);
|
||||
free_list= 0;
|
||||
}
|
||||
inline void free_temporary_memory_pool_for_ps_preparing()
|
||||
{
|
||||
DBUG_ASSERT(current_statement!=0);
|
||||
cleanup_items(current_statement->free_list);
|
||||
free_items(free_list);
|
||||
close_thread_tables(this); // to close derived tables
|
||||
free_root(&mem_root, MYF(0));
|
||||
set_item_arena(current_statement);
|
||||
}
|
||||
};
|
||||
|
||||
/* Flags for the THD::system_thread (bitmap) variable */
|
||||
|
|
|
@ -58,9 +58,9 @@ static bool write_db_opt(THD *thd, const char *path, HA_CREATE_INFO *create)
|
|||
if ((file=my_create(path, CREATE_MODE,O_RDWR | O_TRUNC,MYF(MY_WME))) >= 0)
|
||||
{
|
||||
ulong length;
|
||||
CHARSET_INFO *cs= (create && create->default_table_charset) ?
|
||||
create->default_table_charset :
|
||||
thd->variables.collation_server;
|
||||
CHARSET_INFO *cs= ((create && create->default_table_charset) ?
|
||||
create->default_table_charset :
|
||||
thd->variables.collation_server);
|
||||
length= my_sprintf(buf,(buf,
|
||||
"default-character-set=%s\ndefault-collation=%s\n",
|
||||
cs->csname,cs->name));
|
||||
|
@ -116,9 +116,10 @@ bool load_db_opt(THD *thd, const char *path, HA_CREATE_INFO *create)
|
|||
{
|
||||
if (!strncmp(buf,"default-character-set", (pos-buf)))
|
||||
{
|
||||
if (!(create->default_table_charset= get_charset_by_csname(pos+1,
|
||||
MY_CS_PRIMARY,
|
||||
MYF(0))))
|
||||
if (!(create->default_table_charset=
|
||||
get_charset_by_csname(pos+1,
|
||||
MY_CS_PRIMARY,
|
||||
MYF(0))))
|
||||
{
|
||||
sql_print_error(ER(ER_UNKNOWN_CHARACTER_SET),pos+1);
|
||||
}
|
||||
|
|
|
@ -1500,11 +1500,17 @@ bool st_select_lex::setup_ref_array(THD *thd, uint order_group_num)
|
|||
{
|
||||
if (ref_pointer_array)
|
||||
return 0;
|
||||
|
||||
/*
|
||||
We have to create array in prepared statement memory if it is
|
||||
prepared statement
|
||||
*/
|
||||
Statement *stmt= thd->current_statement ? thd->current_statement : thd;
|
||||
return (ref_pointer_array=
|
||||
(Item **)thd->alloc(sizeof(Item*) *
|
||||
(item_list.elements +
|
||||
select_n_having_items +
|
||||
order_group_num)* 5)) == 0;
|
||||
(Item **)stmt->alloc(sizeof(Item*) *
|
||||
(item_list.elements +
|
||||
select_n_having_items +
|
||||
order_group_num)* 5)) == 0;
|
||||
}
|
||||
|
||||
|
||||
|
@ -1629,7 +1635,11 @@ void st_select_lex::print_limit(THD *thd, String *str)
|
|||
|
||||
/*
|
||||
There are st_select_lex::add_table_to_list &
|
||||
st_select_lex::set_lock_for_tables in sql_parse.cc
|
||||
st_select_lex::set_lock_for_tables are in sql_parse.cc
|
||||
|
||||
st_select_lex::print is in sql_select.h
|
||||
|
||||
st_select_lex_unit::prepare, st_select_lex_unit::exec,
|
||||
st_select_lex_unit::cleanup, st_select_lex_unit::reinit_exec_mechanism
|
||||
are in sql_union.cc
|
||||
*/
|
||||
|
|
|
@ -355,6 +355,8 @@ public:
|
|||
int prepare(THD *thd, select_result *result, ulong additional_options);
|
||||
int exec();
|
||||
int cleanup();
|
||||
inline void unclean() { cleaned= 0; }
|
||||
void reinit_exec_mechanism();
|
||||
|
||||
bool check_updateable(char *db, char *table);
|
||||
void print(String *str);
|
||||
|
|
|
@ -621,8 +621,18 @@ static bool mysql_test_insert_fields(Prepared_statement *stmt,
|
|||
(grant_option && check_grant(thd,privilege,table_list,0,0)))
|
||||
DBUG_RETURN(1);
|
||||
#endif
|
||||
|
||||
/*
|
||||
open temporary memory pool for temporary data allocated by derived
|
||||
tables & preparation procedure
|
||||
*/
|
||||
thd->allocate_temporary_memory_pool_for_ps_preparing();
|
||||
if (open_and_lock_tables(thd, table_list))
|
||||
DBUG_RETURN(1);
|
||||
{
|
||||
thd->free_temporary_memory_pool_for_ps_preparing();
|
||||
DBUG_RETURN(1);
|
||||
}
|
||||
|
||||
table= table_list->table;
|
||||
|
||||
if ((values= its++))
|
||||
|
@ -631,7 +641,11 @@ static bool mysql_test_insert_fields(Prepared_statement *stmt,
|
|||
ulong counter= 0;
|
||||
|
||||
if (check_insert_fields(thd,table,fields,*values,1))
|
||||
{
|
||||
thd->free_temporary_memory_pool_for_ps_preparing();
|
||||
DBUG_RETURN(1);
|
||||
}
|
||||
thd->free_temporary_memory_pool_for_ps_preparing();
|
||||
|
||||
value_count= values->elements;
|
||||
its.rewind();
|
||||
|
@ -648,6 +662,10 @@ static bool mysql_test_insert_fields(Prepared_statement *stmt,
|
|||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
thd->free_temporary_memory_pool_for_ps_preparing();
|
||||
}
|
||||
if (send_prep_stmt(stmt, 0))
|
||||
DBUG_RETURN(1);
|
||||
DBUG_RETURN(0);
|
||||
|
@ -677,12 +695,21 @@ static bool mysql_test_upd_fields(Prepared_statement *stmt,
|
|||
(grant_option && check_grant(thd,UPDATE_ACL,table_list,0,0)))
|
||||
DBUG_RETURN(1);
|
||||
#endif
|
||||
|
||||
/*
|
||||
open temporary memory pool for temporary data allocated by derived
|
||||
tables & preparation procedure
|
||||
*/
|
||||
thd->allocate_temporary_memory_pool_for_ps_preparing();
|
||||
|
||||
if (open_and_lock_tables(thd, table_list))
|
||||
DBUG_RETURN(1);
|
||||
goto err;
|
||||
if (setup_tables(table_list) ||
|
||||
setup_fields(thd, 0, table_list, fields, 1, 0, 0) ||
|
||||
setup_conds(thd, table_list, &conds) || thd->net.report_error)
|
||||
DBUG_RETURN(1);
|
||||
setup_fields(thd, 0, table_list, fields, 1, 0, 0) ||
|
||||
setup_conds(thd, table_list, &conds) || thd->net.report_error)
|
||||
goto err;
|
||||
|
||||
thd->free_temporary_memory_pool_for_ps_preparing();
|
||||
|
||||
/*
|
||||
Currently return only column list info only, and we are not
|
||||
|
@ -691,6 +718,9 @@ static bool mysql_test_upd_fields(Prepared_statement *stmt,
|
|||
if (send_prep_stmt(stmt, 0))
|
||||
DBUG_RETURN(1);
|
||||
DBUG_RETURN(0);
|
||||
err:
|
||||
thd->free_temporary_memory_pool_for_ps_preparing();
|
||||
DBUG_RETURN(1);
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -735,41 +765,51 @@ static bool mysql_test_select_fields(Prepared_statement *stmt,
|
|||
if ((&lex->select_lex != lex->all_selects_list &&
|
||||
lex->unit.create_total_list(thd, lex, &tables)))
|
||||
DBUG_RETURN(1);
|
||||
|
||||
|
||||
/*
|
||||
open temporary memory pool for temporary data allocated by derived
|
||||
tables & preparation procedure
|
||||
*/
|
||||
thd->allocate_temporary_memory_pool_for_ps_preparing();
|
||||
if (open_and_lock_tables(thd, tables))
|
||||
DBUG_RETURN(1);
|
||||
goto err;
|
||||
|
||||
if (lex->describe)
|
||||
{
|
||||
if (send_prep_stmt(stmt, 0))
|
||||
DBUG_RETURN(1);
|
||||
goto err;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!result && !(result= new select_send()))
|
||||
{
|
||||
send_error(thd, ER_OUT_OF_RESOURCES);
|
||||
DBUG_RETURN(1);
|
||||
goto err;
|
||||
}
|
||||
|
||||
JOIN *join= new JOIN(thd, fields, select_options, result);
|
||||
thd->used_tables= 0; // Updated by setup_fields
|
||||
|
||||
if (join->prepare(&select_lex->ref_pointer_array,
|
||||
(TABLE_LIST*)select_lex->get_table_list(),
|
||||
wild_num, conds, og_num, order, group, having, proc,
|
||||
select_lex, unit))
|
||||
DBUG_RETURN(1);
|
||||
if (unit->prepare(thd, result, 0))
|
||||
goto err_prep;
|
||||
|
||||
if (send_prep_stmt(stmt, fields.elements) ||
|
||||
thd->protocol_simple.send_fields(&fields, 0)
|
||||
#ifndef EMBEDDED_LIBRARY
|
||||
|| net_flush(&thd->net)
|
||||
|| net_flush(&thd->net)
|
||||
#endif
|
||||
)
|
||||
DBUG_RETURN(1);
|
||||
join->cleanup();
|
||||
)
|
||||
goto err_prep;
|
||||
|
||||
unit->cleanup();
|
||||
}
|
||||
DBUG_RETURN(0);
|
||||
thd->free_temporary_memory_pool_for_ps_preparing();
|
||||
DBUG_RETURN(0);
|
||||
|
||||
err_prep:
|
||||
unit->cleanup();
|
||||
err:
|
||||
thd->free_temporary_memory_pool_for_ps_preparing();
|
||||
DBUG_RETURN(1);
|
||||
}
|
||||
|
||||
|
||||
|
@ -898,6 +938,7 @@ bool mysql_stmt_prepare(THD *thd, char *packet, uint packet_length)
|
|||
|
||||
thd->stmt_backup.set_statement(thd);
|
||||
thd->set_statement(stmt);
|
||||
thd->current_statement= stmt;
|
||||
|
||||
if (alloc_query(thd, packet, packet_length))
|
||||
goto alloc_query_err;
|
||||
|
@ -925,9 +966,9 @@ bool mysql_stmt_prepare(THD *thd, char *packet, uint packet_length)
|
|||
sl->prep_where= sl->where;
|
||||
}
|
||||
|
||||
cleanup_items(thd->free_list);
|
||||
stmt->set_statement(thd);
|
||||
thd->set_statement(&thd->stmt_backup);
|
||||
thd->current_statement= 0;
|
||||
|
||||
if (init_param_items(stmt))
|
||||
goto init_param_err;
|
||||
|
@ -944,8 +985,14 @@ init_param_err:
|
|||
alloc_query_err:
|
||||
/* Statement map deletes statement on erase */
|
||||
thd->stmt_map.erase(stmt);
|
||||
thd->current_statement= 0;
|
||||
DBUG_RETURN(1);
|
||||
insert_stmt_err:
|
||||
stmt->set_statement(thd);
|
||||
thd->set_statement(&thd->stmt_backup);
|
||||
/* Statement map deletes statement on erase */
|
||||
thd->stmt_map.erase(stmt);
|
||||
thd->current_statement= 0;
|
||||
delete stmt;
|
||||
DBUG_RETURN(1);
|
||||
}
|
||||
|
@ -1010,24 +1057,36 @@ void mysql_stmt_execute(THD *thd, char *packet)
|
|||
/* Fix ORDER list */
|
||||
for (order=(ORDER *)sl->order_list.first ; order ; order=order->next)
|
||||
order->item= (Item **)(order+1);
|
||||
|
||||
/*
|
||||
TODO: When the new table structure is ready, then have a status bit
|
||||
to indicate the table is altered, and re-do the setup_*
|
||||
and open the tables back.
|
||||
*/
|
||||
for (TABLE_LIST *tables= (TABLE_LIST*) sl->table_list.first;
|
||||
tables;
|
||||
tables= tables->next)
|
||||
{
|
||||
tables->table= 0; // safety - nasty init
|
||||
tables->table_list= 0;
|
||||
}
|
||||
|
||||
{
|
||||
SELECT_LEX_UNIT *unit= sl->master_unit();
|
||||
unit->unclean();
|
||||
unit->types.empty();
|
||||
// for derived tables & PS (which can't be reset by Item_subquery)
|
||||
unit->reinit_exec_mechanism();
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
TODO: When the new table structure is ready, then have a status bit
|
||||
to indicate the table is altered, and re-do the setup_*
|
||||
and open the tables back.
|
||||
*/
|
||||
for (TABLE_LIST *tables= (TABLE_LIST*) stmt->lex->select_lex.table_list.first;
|
||||
tables;
|
||||
tables= tables->next)
|
||||
tables->table= 0; // safety - nasty init
|
||||
|
||||
#ifndef EMBEDDED_LIBRARY
|
||||
if (stmt->param_count && setup_params_data(stmt))
|
||||
DBUG_VOID_RETURN;
|
||||
goto end;
|
||||
#else
|
||||
if (stmt->param_count && (*stmt->setup_params_data)(stmt))
|
||||
DBUG_VOID_RETURN;
|
||||
goto end;
|
||||
#endif
|
||||
|
||||
if (!(specialflag & SPECIAL_NO_PRIOR))
|
||||
|
@ -1048,8 +1107,10 @@ void mysql_stmt_execute(THD *thd, char *packet)
|
|||
|
||||
free_items(thd->free_list);
|
||||
cleanup_items(stmt->free_list);
|
||||
close_thread_tables(thd); // to close derived tables
|
||||
free_root(&thd->mem_root, MYF(0));
|
||||
thd->set_statement(&thd->stmt_backup);
|
||||
end:
|
||||
DBUG_VOID_RETURN;
|
||||
}
|
||||
|
||||
|
|
|
@ -327,8 +327,7 @@ JOIN::prepare(Item ***rref_pointer_array,
|
|||
// Is it subselect
|
||||
{
|
||||
Item_subselect *subselect;
|
||||
if ((subselect= select_lex->master_unit()->item) &&
|
||||
select_lex->linkage != GLOBAL_OPTIONS_TYPE)
|
||||
if ((subselect= select_lex->master_unit()->item))
|
||||
{
|
||||
Item_subselect::trans_res res;
|
||||
if ((res= subselect->select_transformer(this)) !=
|
||||
|
@ -1519,10 +1518,10 @@ JOIN::cleanup()
|
|||
|
||||
lock=0; // It's faster to unlock later
|
||||
join_free(1);
|
||||
if (exec_tmp_table1)
|
||||
free_tmp_table(thd, exec_tmp_table1);
|
||||
if (exec_tmp_table2)
|
||||
free_tmp_table(thd, exec_tmp_table2);
|
||||
if (exec_tmp_table1)
|
||||
free_tmp_table(thd, exec_tmp_table1);
|
||||
if (exec_tmp_table2)
|
||||
free_tmp_table(thd, exec_tmp_table2);
|
||||
delete select;
|
||||
delete_dynamic(&keyuse);
|
||||
delete procedure;
|
||||
|
|
|
@ -853,26 +853,35 @@ int mysql_create_table(THD *thd,const char *db, const char *table_name,
|
|||
{
|
||||
if ((length=column->length) > file->max_key_length() ||
|
||||
length > file->max_key_part_length())
|
||||
{
|
||||
my_error(ER_WRONG_SUB_KEY,MYF(0));
|
||||
DBUG_RETURN(-1);
|
||||
}
|
||||
{
|
||||
length=min(file->max_key_length(), file->max_key_part_length());
|
||||
if (key->type == Key::MULTIPLE)
|
||||
{
|
||||
/* not a critical problem */
|
||||
char warn_buff[MYSQL_ERRMSG_SIZE];
|
||||
sprintf(warn_buff,ER(ER_TOO_LONG_KEY),length);
|
||||
push_warning(thd, MYSQL_ERROR::WARN_LEVEL_WARN,
|
||||
ER_TOO_LONG_KEY, warn_buff);
|
||||
}
|
||||
else
|
||||
{
|
||||
my_error(ER_TOO_LONG_KEY,MYF(0),length);
|
||||
DBUG_RETURN(-1);
|
||||
}
|
||||
}
|
||||
}
|
||||
/* TODO HF What's this for??? */
|
||||
else if (f_is_geom(sql_field->pack_flag))
|
||||
{
|
||||
}
|
||||
else if (column->length > length ||
|
||||
((f_is_packed(sql_field->pack_flag) ||
|
||||
((file->table_flags() & HA_NO_PREFIX_CHAR_KEYS) &&
|
||||
(key_info->flags & HA_NOSAME))) &&
|
||||
column->length != length))
|
||||
{
|
||||
my_error(ER_WRONG_SUB_KEY,MYF(0));
|
||||
DBUG_RETURN(-1);
|
||||
}
|
||||
if (!(file->table_flags() & HA_NO_PREFIX_CHAR_KEYS))
|
||||
length=column->length;
|
||||
else if (!f_is_geom(sql_field->pack_flag) &&
|
||||
(column->length > length ||
|
||||
((f_is_packed(sql_field->pack_flag) ||
|
||||
((file->table_flags() & HA_NO_PREFIX_CHAR_KEYS) &&
|
||||
(key_info->flags & HA_NOSAME))) &&
|
||||
column->length != length)))
|
||||
{
|
||||
my_error(ER_WRONG_SUB_KEY,MYF(0));
|
||||
DBUG_RETURN(-1);
|
||||
}
|
||||
else if (!(file->table_flags() & HA_NO_PREFIX_CHAR_KEYS))
|
||||
length=column->length;
|
||||
}
|
||||
else if (length == 0)
|
||||
{
|
||||
|
@ -882,8 +891,20 @@ int mysql_create_table(THD *thd,const char *db, const char *table_name,
|
|||
}
|
||||
if (length > file->max_key_part_length())
|
||||
{
|
||||
my_error(ER_WRONG_SUB_KEY,MYF(0));
|
||||
DBUG_RETURN(-1);
|
||||
length=file->max_key_part_length();
|
||||
if (key->type == Key::MULTIPLE)
|
||||
{
|
||||
/* not a critical problem */
|
||||
char warn_buff[MYSQL_ERRMSG_SIZE];
|
||||
sprintf(warn_buff,ER(ER_TOO_LONG_KEY),length);
|
||||
push_warning(thd, MYSQL_ERROR::WARN_LEVEL_WARN,
|
||||
ER_TOO_LONG_KEY, warn_buff);
|
||||
}
|
||||
else
|
||||
{
|
||||
my_error(ER_TOO_LONG_KEY,MYF(0),length);
|
||||
DBUG_RETURN(-1);
|
||||
}
|
||||
}
|
||||
key_part_info->length=(uint16) length;
|
||||
/* Use packed keys for long strings on the first column */
|
||||
|
|
|
@ -453,3 +453,9 @@ int st_select_lex_unit::cleanup()
|
|||
}
|
||||
DBUG_RETURN(error);
|
||||
}
|
||||
|
||||
|
||||
void st_select_lex_unit::reinit_exec_mechanism()
|
||||
{
|
||||
prepared= optimized= executed= 0;
|
||||
}
|
||||
|
|
|
@ -36,7 +36,7 @@ static double scaler1[] = {
|
|||
1.0, 10.0, 1e2, 1e3, 1e4, 1e5, 1e6, 1e7, 1e8, 1e9
|
||||
};
|
||||
|
||||
// let's use a static array for not to accumulate the error
|
||||
/* let's use a static array for not to accumulate the error */
|
||||
static double pastpoint[] = {
|
||||
1e-1, 1e-2, 1e-3, 1e-4, 1e-5, 1e-6, 1e-7, 1e-8, 1e-9,
|
||||
1e-10, 1e-11, 1e-12, 1e-13, 1e-14, 1e-15, 1e-16, 1e-17, 1e-18, 1e-19,
|
||||
|
|
|
@ -8189,6 +8189,90 @@ static void test_bug2247()
|
|||
fprintf(stdout, "OK");
|
||||
}
|
||||
|
||||
|
||||
|
||||
static void test_subqueries()
|
||||
{
|
||||
MYSQL_STMT *stmt;
|
||||
int rc, i;
|
||||
const char *query= "SELECT (SELECT SUM(a+b) FROM t2 where t1.b=t2.b GROUP BY t1.a LIMIT 1) as scalar_s, exists (select 1 from t2 where t2.a/2=t1.a) as exists_s, a in (select a+3 from t2) as in_s, (a-1,b-1) in (select a,b from t2) as in_row_s FROM t1, (select a x, b y from t2) tt WHERE x=a";
|
||||
|
||||
myheader("test_subquery");
|
||||
|
||||
rc = mysql_query(mysql, "DROP TABLE IF EXISTS t1,t2");
|
||||
myquery(rc);
|
||||
|
||||
rc= mysql_query(mysql,"CREATE TABLE t1 (a int , b int);");
|
||||
myquery(rc);
|
||||
|
||||
rc= mysql_query(mysql,
|
||||
"insert into t1 values (1,1), (2, 2), (3,3), (4,4), (5,5);");
|
||||
myquery(rc);
|
||||
|
||||
rc= mysql_query(mysql,"create table t2 select * from t1;");
|
||||
myquery(rc);
|
||||
|
||||
stmt= mysql_prepare(mysql, query, strlen(query));
|
||||
mystmt_init(stmt);
|
||||
for (i= 0; i < 3; i++)
|
||||
{
|
||||
rc= mysql_execute(stmt);
|
||||
mystmt(stmt, rc);
|
||||
assert(5 == my_process_stmt_result(stmt));
|
||||
}
|
||||
mysql_stmt_close(stmt);
|
||||
|
||||
rc= mysql_query(mysql, "DROP TABLE t1,t2");
|
||||
myquery(rc);
|
||||
}
|
||||
|
||||
|
||||
static void test_bad_union()
|
||||
{
|
||||
MYSQL_STMT *stmt;
|
||||
const char *query= "SELECT 1, 2 union SELECT 1";
|
||||
|
||||
myheader("test_bad_union");
|
||||
|
||||
stmt= mysql_prepare(mysql, query, strlen(query));
|
||||
assert(stmt == 0);
|
||||
myerror(NULL);
|
||||
}
|
||||
|
||||
static void test_distinct()
|
||||
{
|
||||
MYSQL_STMT *stmt;
|
||||
int rc, i;
|
||||
const char *query=
|
||||
"SELECT 2+count(distinct b), group_concat(a) FROM t1 group by a";
|
||||
|
||||
myheader("test_subquery");
|
||||
|
||||
rc = mysql_query(mysql, "DROP TABLE IF EXISTS t1");
|
||||
myquery(rc);
|
||||
|
||||
rc= mysql_query(mysql,"CREATE TABLE t1 (a int , b int);");
|
||||
myquery(rc);
|
||||
|
||||
rc= mysql_query(mysql,
|
||||
"insert into t1 values (1,1), (2, 2), (3,3), (4,4), (5,5),\
|
||||
(1,10), (2, 20), (3,30), (4,40), (5,50)\;");
|
||||
myquery(rc);
|
||||
|
||||
for (i= 0; i < 3; i++)
|
||||
{
|
||||
stmt= mysql_prepare(mysql, query, strlen(query));
|
||||
mystmt_init(stmt);
|
||||
rc= mysql_execute(stmt);
|
||||
mystmt(stmt, rc);
|
||||
assert(5 == my_process_stmt_result(stmt));
|
||||
mysql_stmt_close(stmt);
|
||||
}
|
||||
|
||||
rc= mysql_query(mysql, "DROP TABLE t1");
|
||||
myquery(rc);
|
||||
}
|
||||
|
||||
/*
|
||||
Test for bug#2248 "mysql_fetch without prior mysql_execute hangs"
|
||||
*/
|
||||
|
@ -8385,6 +8469,9 @@ int main(int argc, char **argv)
|
|||
test_count= 1;
|
||||
|
||||
start_time= time((time_t *)0);
|
||||
|
||||
test_subqueries();
|
||||
|
||||
client_query(); /* simple client query test */
|
||||
#if NOT_YET_WORKING
|
||||
/* Used for internal new development debugging */
|
||||
|
@ -8437,7 +8524,8 @@ int main(int argc, char **argv)
|
|||
client_use_result(); /* usage of mysql_use_result() */
|
||||
test_tran_bdb(); /* transaction test on BDB table type */
|
||||
test_tran_innodb(); /* transaction test on InnoDB table type */
|
||||
test_prepare_ext(); /* test prepare with all types conversion -- TODO */
|
||||
test_prepare_ext(); /* test prepare with all types
|
||||
conversion -- TODO */
|
||||
test_prepare_syntax(); /* syntax check for prepares */
|
||||
test_field_names(); /* test for field names */
|
||||
test_field_flags(); /* test to help .NET provider team */
|
||||
|
@ -8450,7 +8538,7 @@ int main(int argc, char **argv)
|
|||
test_stmt_close(); /* mysql_stmt_close() test -- hangs */
|
||||
test_prepare_field_result(); /* prepare meta info */
|
||||
test_multi_stmt(); /* multi stmt test */
|
||||
test_multi_statements(); /* test multi statement execution */
|
||||
test_multi_statements();/* test multi statement execution */
|
||||
test_store_result(); /* test the store_result */
|
||||
test_store_result1(); /* test store result without buffers */
|
||||
test_store_result2(); /* test store result for misc case */
|
||||
|
@ -8497,6 +8585,10 @@ int main(int argc, char **argv)
|
|||
test_bug2247(); /* test that mysql_stmt_affected_rows() returns
|
||||
number of rows affected by last prepared
|
||||
statement execution */
|
||||
test_subqueries(); /* repeatable subqueries */
|
||||
test_bad_union(); /* correct setup of UNION */
|
||||
test_distinct(); /* distinct aggregate functions */
|
||||
|
||||
|
||||
end_time= time((time_t *)0);
|
||||
total_time+= difftime(end_time, start_time);
|
||||
|
|
Loading…
Add table
Reference in a new issue