Commit fbfef628 authored by Georgi Kodinov's avatar Georgi Kodinov

automatic merge of 5.0-bugteam into the 5.0.66 release clone.

parents 0d62f60b b93fcb9b
--require r/have_archive.require
--disable_query_log
show variables like "have_archive";
show variables like 'have_archive';
--enable_query_log
-- require r/have_bdb.require
disable_query_log;
show variables like "have_bdb";
show variables like 'have_bdb';
enable_query_log;
-- require r/have_big5.require
disable_query_log;
show collation like "big5_chinese_ci";
show collation like 'big5_chinese_ci';
enable_query_log;
-- require r/have_blackhole.require
disable_query_log;
show variables like "have_blackhole_engine";
show variables like 'have_blackhole_engine';
enable_query_log;
--require r/case_sensitive_file_system.require
--disable_query_log
show variables like "lower_case_file_system";
show variables like 'lower_case_file_system';
--enable_query_log
-- require r/have_compress.require
disable_query_log;
show variables like "have_compress";
show variables like 'have_compress';
enable_query_log;
-- require r/have_cp1250_ch.require
disable_query_log;
show collation like "cp1250_czech_cs";
show collation like 'cp1250_czech_cs';
enable_query_log;
-- require r/have_cp932.require
disable_query_log;
show collation like "cp932_japanese_ci";
show collation like 'cp932_japanese_ci';
enable_query_log;
-- require r/have_crypt.require
disable_query_log;
show variables like "have_crypt";
show variables like 'have_crypt';
enable_query_log;
-- require r/have_csv.require
disable_query_log;
show variables like "have_csv";
show variables like 'have_csv';
enable_query_log;
-- require r/have_eucjpms.require
disable_query_log;
show collation like "eucjpms_japanese_ci";
show collation like 'eucjpms_japanese_ci';
enable_query_log;
-- require r/have_euckr.require
disable_query_log;
show collation like "euckr_korean_ci";
show collation like 'euckr_korean_ci';
enable_query_log;
-- require r/have_exampledb.require
disable_query_log;
show variables like "have_example_engine";
show variables like 'have_example_engine';
enable_query_log;
-- require r/have_federated_db.require
disable_query_log;
show variables like "have_federated_engine";
show variables like 'have_federated_engine';
enable_query_log;
-- require r/have_gb2312.require
disable_query_log;
show collation like "gb2312_chinese_ci";
show collation like 'gb2312_chinese_ci';
enable_query_log;
-- require r/have_gbk.require
disable_query_log;
show collation like "gbk_chinese_ci";
show collation like 'gbk_chinese_ci';
enable_query_log;
--require r/have_geometry.require
--disable_query_log
show variables like "have_geometry";
show variables like 'have_geometry';
--enable_query_log
-- require r/have_innodb.require
disable_query_log;
show variables like "have_innodb";
show variables like 'have_innodb';
enable_query_log;
-- require r/have_latin2_ch.require
disable_query_log;
show collation like "latin2_czech_cs";
show collation like 'latin2_czech_cs';
enable_query_log;
-- require r/have_log_bin.require
disable_query_log;
show variables like "log_bin";
show variables like 'log_bin';
enable_query_log;
--require r/lowercase0.require
--disable_query_log
show variables like "lower_case_%";
show variables like 'lower_case_%';
--enable_query_log
......@@ -10,7 +10,7 @@ drop table if exists t1, t2;
--enable_warnings
flush tables;
--require r/have_ndb.require
show variables like "have_ndbcluster";
show variables like 'have_ndbcluster';
enable_query_log;
# Check that server2 has NDB support
......@@ -21,7 +21,7 @@ drop table if exists t1, t2;
--enable_warnings
flush tables;
--require r/have_ndb.require
show variables like "have_ndbcluster";
show variables like 'have_ndbcluster';
enable_query_log;
# Set the default connection to 'server1'
......
# Check that server is compiled and started with support for NDB
-- require r/have_ndb.require
disable_query_log;
show variables like "have_ndbcluster";
show variables like 'have_ndbcluster';
enable_query_log;
# Check that NDB is installed and known to be working
......
......@@ -3,5 +3,5 @@
# of query cache hits
-- disable_ps_protocol
disable_query_log;
show variables like "have_query_cache";
show variables like 'have_query_cache';
enable_query_log;
-- require r/have_sjis.require
disable_query_log;
show collation like "sjis_japanese_ci";
show collation like 'sjis_japanese_ci';
enable_query_log;
-- require r/have_ssl.require
disable_query_log;
show variables like "have_ssl";
show variables like 'have_ssl';
enable_query_log;
-- require r/have_tis620.require
disable_query_log;
show collation like "tis620_thai_ci";
show collation like 'tis620_thai_ci';
enable_query_log;
-- require r/have_ucs2.require
disable_query_log;
show collation like "ucs2_general_ci";
show collation like 'ucs2_general_ci';
enable_query_log;
......@@ -4,7 +4,7 @@
#
--require r/have_udf.require
disable_query_log;
show variables like "have_dynamic_loading";
show variables like 'have_dynamic_loading';
enable_query_log;
#
......
-- require r/have_ujis.require
disable_query_log;
show collation like "ujis_japanese_ci";
show collation like 'ujis_japanese_ci';
enable_query_log;
......@@ -35,7 +35,7 @@ ERROR 42000: You have an error in your SQL syntax; check the manual that corresp
prepare bar from "DELETE FROM table_28779 WHERE a = 7 OR 1=1/*! AND 2=2;";
ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '' at line 1
prepare bar from "DELETE FROM table_28779 WHERE a = 7 OR 1=1/*! AND 2=2;*";
ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near ';*' at line 1
ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '*' at line 1
prepare bar from "DELETE FROM table_28779 WHERE a = 7 OR 1=1/*!98765' AND b = 'bar';";
ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '/*!98765' AND b = 'bar'' at line 1
prepare bar from "DELETE FROM table_28779 WHERE a = 7 OR 1=1/*!98765' AND b = 'bar';*";
......
DROP PROCEDURE IF EXISTS p26030;
select "non terminated"$$
non terminated
non terminated
select "terminated";$$
terminated
terminated
select "non terminated, space" $$
non terminated, space
non terminated, space
select "terminated, space"; $$
terminated, space
terminated, space
select "non terminated, comment" /* comment */$$
non terminated, comment
non terminated, comment
select "terminated, comment"; /* comment */$$
terminated, comment
terminated, comment
select "stmt 1";select "stmt 2 non terminated"$$
stmt 1
stmt 1
stmt 2 non terminated
stmt 2 non terminated
select "stmt 1";select "stmt 2 terminated";$$
stmt 1
stmt 1
stmt 2 terminated
stmt 2 terminated
select "stmt 1";select "stmt 2 non terminated, space" $$
stmt 1
stmt 1
stmt 2 non terminated, space
stmt 2 non terminated, space
select "stmt 1";select "stmt 2 terminated, space"; $$
stmt 1
stmt 1
stmt 2 terminated, space
stmt 2 terminated, space
select "stmt 1";select "stmt 2 non terminated, comment" /* comment */$$
stmt 1
stmt 1
stmt 2 non terminated, comment
stmt 2 non terminated, comment
select "stmt 1";select "stmt 2 terminated, comment"; /* comment */$$
stmt 1
stmt 1
stmt 2 terminated, comment
stmt 2 terminated, comment
select "stmt 1"; select "space, stmt 2"$$
stmt 1
stmt 1
space, stmt 2
space, stmt 2
select "stmt 1";/* comment */select "comment, stmt 2"$$
stmt 1
stmt 1
comment, stmt 2
comment, stmt 2
DROP PROCEDURE IF EXISTS p26030; CREATE PROCEDURE p26030() BEGIN SELECT 1; END; CALL p26030()
$$
1
1
DROP PROCEDURE IF EXISTS p26030; CREATE PROCEDURE p26030() SELECT 1; CALL p26030()
$$
1
1
DROP PROCEDURE p26030;
......@@ -85,9 +85,9 @@ NULL
NULL
NULL
prepare stmt6 from 'select 1; select2';
ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '; select2' at line 1
ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'select2' at line 1
prepare stmt6 from 'insert into t1 values (5,"five"); select2';
ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '; select2' at line 1
ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'select2' at line 1
explain prepare stmt6 from 'insert into t1 values (5,"five"); select2';
ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'from 'insert into t1 values (5,"five"); select2'' at line 1
create table t2
......
......@@ -78,3 +78,34 @@ alter table t1 modify a varchar(255);
select length(a) from t1;
length(a)
6
select 0b01000001;
0b01000001
A
select 0x41;
0x41
A
select b'01000001';
b'01000001'
A
select x'41', 0+x'41';
x'41' 0+x'41'
A 65
select N'abc', length(N'abc');
abc length(N'abc')
abc 3
select N'', length(N'');
length(N'')
0
select '', length('');
length('')
0
select b'', 0+b'';
b'' 0+b''
0
select x'', 0+x'';
x'' 0+x''
0
select 0x;
ERROR 42S22: Unknown column '0x' in 'field list'
select 0b;
ERROR 42S22: Unknown column '0b' in 'field list'
......@@ -10,11 +10,6 @@
# 2008-06-06 mleich Create this this variant for the embedded server.
#
let $value= query_get_value(SHOW VARIABLES LIKE 'version_compile_os',Value,1);
if (`SELECT '$value' LIKE 'apple-darwin%'`)
{
skip Bug#37380 Test funcs_1.is_columns_myisam_embedded fails on OS X;
}
if (`SELECT VERSION() NOT LIKE '%embedded%'`)
{
--skip Test requires: embedded server
......
#
# This file contains tests covering the parser
#
#=============================================================================
# LEXICAL PARSER (lex)
#=============================================================================
#
# Maintainer: these tests are for the lexical parser, so every character,
# even whitespace or comments, is significant here.
#
#
# Bug#26030 (Parsing fails for stored routine w/multi-statement execution
# enabled)
#
--disable_warnings
DROP PROCEDURE IF EXISTS p26030;
--enable_warnings
delimiter $$;
select "non terminated"$$
select "terminated";$$
select "non terminated, space" $$
select "terminated, space"; $$
select "non terminated, comment" /* comment */$$
select "terminated, comment"; /* comment */$$
# Multi queries can not be used in --ps-protocol test mode
--disable_ps_protocol
select "stmt 1";select "stmt 2 non terminated"$$
select "stmt 1";select "stmt 2 terminated";$$
select "stmt 1";select "stmt 2 non terminated, space" $$
select "stmt 1";select "stmt 2 terminated, space"; $$
select "stmt 1";select "stmt 2 non terminated, comment" /* comment */$$
select "stmt 1";select "stmt 2 terminated, comment"; /* comment */$$
select "stmt 1"; select "space, stmt 2"$$
select "stmt 1";/* comment */select "comment, stmt 2"$$
DROP PROCEDURE IF EXISTS p26030; CREATE PROCEDURE p26030() BEGIN SELECT 1; END; CALL p26030()
$$
DROP PROCEDURE IF EXISTS p26030; CREATE PROCEDURE p26030() SELECT 1; CALL p26030()
$$
--enable_ps_protocol
delimiter ;$$
DROP PROCEDURE p26030;
#============================================================================r
# SYNTACTIC PARSER (bison)
#=============================================================================
......@@ -84,3 +84,31 @@ select length(a) from t1;
alter table t1 modify a varchar(255);
select length(a) from t1;
#
# Bug#35658 (An empty binary value leads to mysqld crash)
#
select 0b01000001;
select 0x41;
select b'01000001';
select x'41', 0+x'41';
select N'abc', length(N'abc');
select N'', length(N'');
select '', length('');
select b'', 0+b'';
select x'', 0+x'';
--error ER_BAD_FIELD_ERROR
select 0x;
--error ER_BAD_FIELD_ERROR
select 0b;
......@@ -48,13 +48,12 @@ char *my_defaults_extra_file=0;
/* Which directories are searched for options (and in which order) */
#define MAX_DEFAULT_DIRS 6
const char *default_directories[MAX_DEFAULT_DIRS + 1];
#define DEFAULT_DIRS_SIZE (MAX_DEFAULT_DIRS + 1) /* Terminate with NULL */
static const char **default_directories = NULL;
#ifdef __WIN__
static const char *f_extensions[]= { ".ini", ".cnf", 0 };
#define NEWLINE "\r\n"
static char system_dir[FN_REFLEN], shared_system_dir[FN_REFLEN],
config_dir[FN_REFLEN];
#else
static const char *f_extensions[]= { ".cnf", 0 };
#define NEWLINE "\n"
......@@ -85,19 +84,34 @@ static int search_default_file_with_ext(Process_option_func func,
const char *config_file, int recursion_level);
/**
Create the list of default directories.
@param alloc MEM_ROOT where the list of directories is stored
@details
The directories searched, in order, are:
- Windows: GetSystemWindowsDirectory()
- Windows: GetWindowsDirectory()
- Windows: C:/
- Windows: Directory above where the executable is located
- Netware: sys:/etc/
- Unix & OS/2: /etc/
- Unix: --sysconfdir=<path> (compile-time option)
- OS/2: getenv(ETC)
- ALL: getenv(DEFAULT_HOME_ENV)
- ALL: --defaults-extra-file=<path> (run-time option)
- Unix: ~/
On all systems, if a directory is already in the list, it will be moved
to the end of the list. This avoids reading defaults files multiple times,
while ensuring the correct precedence.
@return void
@retval NULL Failure (out of memory, probably)
@retval other Pointer to NULL-terminated array of default directories
*/
static void (*init_default_directories)();
static const char **init_default_directories(MEM_ROOT *alloc);
static char *remove_end_comment(char *ptr);
......@@ -386,8 +400,9 @@ int load_defaults(const char *conf_file, const char **groups,
struct handle_option_ctx ctx;
DBUG_ENTER("load_defaults");
init_default_directories();
init_alloc_root(&alloc,512,0);
if ((default_directories= init_default_directories(&alloc)) == NULL)
goto err;
/*
Check if the user doesn't want any default option processing
--no-defaults is always the first option
......@@ -864,16 +879,28 @@ void my_print_default_files(const char *conf_file)
my_bool have_ext= fn_ext(conf_file)[0] != 0;
const char **exts_to_use= have_ext ? empty_list : f_extensions;
char name[FN_REFLEN], **ext;
const char **dirs;
init_default_directories();
puts("\nDefault options are read from the following files in the given order:");
if (dirname_length(conf_file))
fputs(conf_file,stdout);
else
{
for (dirs=default_directories ; *dirs; dirs++)
/*
If default_directories is already initialized, use it. Otherwise,
use a private MEM_ROOT.
*/
const char **dirs = default_directories;
MEM_ROOT alloc;
init_alloc_root(&alloc,512,0);
if (!dirs && (dirs= init_default_directories(&alloc)) == NULL)
{
fputs("Internal error initializing default directories list", stdout);
}
else
{
for ( ; *dirs; dirs++)
{
for (ext= (char**) exts_to_use; *ext; ext++)
{
......@@ -887,11 +914,14 @@ void my_print_default_files(const char *conf_file)
continue;
end= convert_dirname(name, pos, NullS);
if (name[0] == FN_HOMELIB) /* Add . to filenames in home */
*end++='.';
*end++= '.';
strxmov(end, conf_file, *ext, " ", NullS);
fputs(name,stdout);
fputs(name, stdout);
}
}
}
free_root(&alloc, MYF(0));
}
puts("");
}
......@@ -928,32 +958,23 @@ void print_defaults(const char *conf_file, const char **groups)
#include <help_end.h>
/*
This extra complexity is to avoid declaring 'rc' if it won't be
used.
*/
#define ADD_DIRECTORY_INTERNAL(DIR) \
array_append_string_unique((DIR), default_directories, \
array_elements(default_directories))
#ifdef DBUG_OFF
# define ADD_DIRECTORY(DIR) (void) ADD_DIRECTORY_INTERNAL(DIR)
#else
#define ADD_DIRECTORY(DIR) \
do { \
my_bool rc= ADD_DIRECTORY_INTERNAL(DIR); \
DBUG_ASSERT(rc == FALSE); /* Success */ \
} while (0)
#endif
static int add_directory(MEM_ROOT *alloc, const char *dir, const char **dirs)
{
char buf[FN_REFLEN];
uint len;
char *p;
my_bool err __attribute__((unused));
/* Normalize directory name */
len= unpack_dirname(buf, dir);
if (!(p= strmake_root(alloc, buf, len)))
return 1; /* Failure */
/* Should never fail if DEFAULT_DIRS_SIZE is correct size */
err= array_append_string_unique(p, dirs, DEFAULT_DIRS_SIZE);
DBUG_ASSERT(err == FALSE);
#define ADD_COMMON_DIRECTORIES() \
do { \
char *env; \
if ((env= getenv(STRINGIFY_ARG(DEFAULT_HOME_ENV)))) \
ADD_DIRECTORY(env); \
/* Placeholder for --defaults-extra-file=<path> */ \
ADD_DIRECTORY(""); \
} while (0)
return 0;
}
#ifdef __WIN__
......@@ -992,138 +1013,93 @@ static uint my_get_system_windows_directory(char *buffer, uint size)
}
/**
Initialize default directories for Microsoft Windows
@details
1. GetSystemWindowsDirectory()
2. GetWindowsDirectory()
3. C:/
4. Directory above where the executable is located
5. getenv(DEFAULT_HOME_ENV)
6. --defaults-extra-file=<path> (run-time option)
*/
static void init_default_directories_win()
static const char *my_get_module_parent(char *buf, size_t size)
{
bzero((char *) default_directories, sizeof(default_directories));
if (my_get_system_windows_directory(shared_system_dir,
sizeof(shared_system_dir)))
ADD_DIRECTORY(shared_system_dir);
if (GetWindowsDirectory(system_dir,sizeof(system_dir)))
ADD_DIRECTORY(system_dir);
ADD_DIRECTORY("C:/");
char *last= NULL;
char *end;
if (!GetModuleFileName(NULL, buf, size))
return NULL;
end= strend(buf);
if (GetModuleFileName(NULL, config_dir, sizeof(config_dir)))
{
char *last= NULL, *end= strend(config_dir);
/*
Look for the second-to-last \ in the filename, but hang on
to a pointer after the last \ in case we're in the root of
a drive.
*/
for ( ; end > config_dir; end--)
for ( ; end > buf; end--)
{
if (*end == FN_LIBCHAR)
{
if (last)
{
if (end != config_dir)
{
/* Keep the last '\' as this works both with D:\ and a directory */
end[1]= 0;
}
else
{
/* No parent directory (strange). Use current dir + '\' */
last[1]= 0;
}
break;
}
last= end;
}
}
ADD_DIRECTORY(config_dir);
}
ADD_COMMON_DIRECTORIES();
return buf;
}
#endif /* __WIN__ */
static void (*init_default_directories)()= init_default_directories_win;
#elif defined(__NETWARE__)
/**
Initialize default directories for Novell Netware
@details
1. sys:/etc/
2. getenv(DEFAULT_HOME_ENV)
3. --defaults-extra-file=<path> (run-time option)
*/
static void init_default_directories_netware()
static const char **init_default_directories(MEM_ROOT *alloc)
{
bzero((char *) default_directories, sizeof(default_directories));
ADD_DIRECTORY("sys:/etc/");
ADD_COMMON_DIRECTORIES();
}
const char **dirs;
char *env;
int errors= 0;
static void (*init_default_directories)()= init_default_directories_netware;
dirs= (const char **)alloc_root(alloc, DEFAULT_DIRS_SIZE * sizeof(char *));
if (dirs == NULL)
return NULL;
bzero((char *) dirs, DEFAULT_DIRS_SIZE * sizeof(char *));
#elif defined(__EMX__) || defined(OS2)
#ifdef __WIN__
/**
Initialize default directories for OS/2
{
char fname_buffer[FN_REFLEN];
if (my_get_system_windows_directory(fname_buffer, sizeof(fname_buffer)))
errors += add_directory(alloc, fname_buffer, dirs);
@details
1. /etc/
2. getenv(ETC)
3. getenv(DEFAULT_HOME_ENV)
4. --defaults-extra-file=<path> (run-time option)
*/
if (GetWindowsDirectory(fname_buffer, sizeof(fname_buffer)))
errors += add_directory(alloc, fname_buffer, dirs);
static void init_default_directories_os2()
{
const char *env;
errors += add_directory(alloc, "C:/", dirs);
bzero((char *) default_directories, sizeof(default_directories));
ADD_DIRECTORY("/etc/");
if ((env= getenv("ETC")))
ADD_DIRECTORY(env);
ADD_COMMON_DIRECTORIES();
}
if (my_get_module_parent(fname_buffer, sizeof(fname_buffer)) != NULL)
errors += add_directory(alloc, fname_buffer, dirs);
}
static void (*init_default_directories)()= init_default_directories_os2;
#elif defined(__NETWARE__)
#else
errors += add_directory(alloc, "sys:/etc/", dirs);
/**
Initialize default directories for Unix
#else
@details
1. /etc/
2. --sysconfdir=<path> (compile-time option)
3. getenv(DEFAULT_HOME_ENV)
4. --defaults-extra-file=<path> (run-time option)
5. "~/"
*/
errors += add_directory(alloc, "/etc/", dirs);
static void init_default_directories_unix()
{
bzero((char *) default_directories, sizeof(default_directories));
ADD_DIRECTORY("/etc/");
#ifdef DEFAULT_SYSCONFDIR
#if defined(__EMX__) || defined(OS2)
if ((env= getenv("ETC")))
errors += add_directory(alloc, env, dirs);
#elif defined(DEFAULT_SYSCONFDIR)
if (DEFAULT_SYSCONFDIR != "")
ADD_DIRECTORY(DEFAULT_SYSCONFDIR);
errors += add_directory(alloc, DEFAULT_SYSCONFDIR, dirs);
#endif /* __EMX__ || __OS2__ */
#endif
ADD_COMMON_DIRECTORIES();
ADD_DIRECTORY("~/");
}
static void (*init_default_directories)()= init_default_directories_unix;
if ((env= getenv(STRINGIFY_ARG(DEFAULT_HOME_ENV))))
errors += add_directory(alloc, env, dirs);
/* Placeholder for --defaults-extra-file=<path> */
errors += add_directory(alloc, "", dirs);
#if !defined(__WIN__) && !defined(__NETWARE__) && \
!defined(__EMX__) && !defined(OS2)
errors += add_directory(alloc, "~/", dirs);
#endif
return (errors > 0 ? NULL : dirs);
}
......@@ -5013,6 +5013,9 @@ Item_bin_string::Item_bin_string(const char *str, uint str_length)
if (!ptr)
return;
str_value.set(ptr, max_length, &my_charset_bin);
if (max_length > 0)
{
ptr+= max_length - 1;
ptr[1]= 0; // Set end null for string
for (; end >= str; end--)
......@@ -5028,6 +5031,10 @@ Item_bin_string::Item_bin_string(const char *str, uint str_length)
power<<= 1;
}
*ptr= (char) bits;
}
else
ptr[0]= 0;
collation.set(&my_charset_bin, DERIVATION_COERCIBLE);
fixed= 1;
}
......
......@@ -4154,8 +4154,14 @@ int User_var_log_event::exec_event(struct st_relay_log_info* rli)
/*
Item_func_set_user_var can't substitute something else on its place =>
0 can be passed as last argument (reference on item)
Fix_fields() can fail, in which case a call of update_hash() might
crash the server, so if fix fields fails, we just return with an
error.
*/
e.fix_fields(thd, 0);
if (e.fix_fields(thd, 0))
return 1;
/*
A variable can just be considered as a table with
a single record and with a single column. Thus, like
......
......@@ -117,7 +117,6 @@ public:
create_field m_return_field_def; /* This is used for FUNCTIONs only. */
const char *m_tmp_query; // Temporary pointer to sub query string
uint m_old_cmq; // Old CLIENT_MULTI_QUERIES value
st_sp_chistics *m_chistics;
ulong m_sql_mode; // For SHOW CREATE and execution
LEX_STRING m_qname; // db.name
......
......@@ -1010,21 +1010,8 @@ int MYSQLlex(void *arg, void *yythd)
yySkip();
return (SET_VAR);
case MY_LEX_SEMICOLON: // optional line terminator
if (yyPeek())
{
if ((thd->client_capabilities & CLIENT_MULTI_STATEMENTS) &&
!lip->stmt_prepare_mode)
{
lex->safe_to_cache_query= 0;
lip->found_semicolon= lip->ptr;
thd->server_status|= SERVER_MORE_RESULTS_EXISTS;
lip->next_state= MY_LEX_END;
return (END_OF_INPUT);
}
state= MY_LEX_CHAR; // Return ';'
break;
}
/* fall true */
case MY_LEX_EOL:
if (lip->ptr >= lip->end_of_query)
{
......
......@@ -6169,6 +6169,11 @@ void mysql_parse(THD *thd, const char *inBuf, uint length,
(thd->query_length= (ulong)(lip.found_semicolon - thd->query)))
thd->query_length--;
/* Actually execute the query */
if (*found_semicolon)
{
lex->safe_to_cache_query= 0;
thd->server_status|= SERVER_MORE_RESULTS_EXISTS;
}
lex->set_trg_event_type_for_tables();
mysql_execute_command(thd);
query_cache_end_of_result(thd);
......
......@@ -1212,12 +1212,45 @@ query:
my_message(ER_EMPTY_QUERY, ER(ER_EMPTY_QUERY), MYF(0));
MYSQL_YYABORT;
}
thd->lex->sql_command= SQLCOM_EMPTY_QUERY;
thd->m_lip->found_semicolon= NULL;
}
| verb_clause
{
Lex_input_stream *lip = YYTHD->m_lip;
if ((YYTHD->client_capabilities & CLIENT_MULTI_QUERIES) &&
! lip->stmt_prepare_mode &&
! (lip->ptr >= lip->end_of_query))
{
/*
We found a well formed query, and multi queries are allowed:
- force the parser to stop after the ';'
- mark the start of the next query for the next invocation
of the parser.
*/
lip->next_state= MY_LEX_END;
lip->found_semicolon= lip->ptr;
}
else
{
thd->lex->sql_command= SQLCOM_EMPTY_QUERY;
/* Single query, terminated. */
lip->found_semicolon= NULL;
}
}
| verb_clause END_OF_INPUT {};
';'
opt_end_of_input
| verb_clause END_OF_INPUT
{
/* Single query, not terminated. */
YYTHD->m_lip->found_semicolon= NULL;
}
;
opt_end_of_input:
/* empty */
| END_OF_INPUT
;
verb_clause:
statement
......@@ -9867,13 +9900,6 @@ trigger_tail:
lex->sphead= sp;
lex->spname= $3;
/*
We have to turn of CLIENT_MULTI_QUERIES while parsing a
stored procedure, otherwise yylex will chop it into pieces
at each ';'.
*/
sp->m_old_cmq= thd->client_capabilities & CLIENT_MULTI_QUERIES;
thd->client_capabilities &= ~CLIENT_MULTI_QUERIES;
bzero((char *)&lex->sp_chistics, sizeof(st_sp_chistics));
lex->sphead->m_chistics= &lex->sp_chistics;
......@@ -9888,9 +9914,6 @@ trigger_tail:
lex->sql_command= SQLCOM_CREATE_TRIGGER;
sp->init_strings(YYTHD, lex);
/* Restore flag if it was cleared above */
if (sp->m_old_cmq)
YYTHD->client_capabilities |= CLIENT_MULTI_QUERIES;
sp->restore_thd_mem_root(YYTHD);
if (sp->is_not_allowed_in_function("trigger"))
......@@ -9968,13 +9991,6 @@ sf_tail:
sp->m_type= TYPE_ENUM_FUNCTION;
lex->sphead= sp;
/*
* We have to turn of CLIENT_MULTI_QUERIES while parsing a
* stored procedure, otherwise yylex will chop it into pieces
* at each ';'.
*/
sp->m_old_cmq= thd->client_capabilities & CLIENT_MULTI_QUERIES;
thd->client_capabilities &= ~CLIENT_MULTI_QUERIES;
lex->sphead->m_param_begin= lip->tok_start+1;
}
sp_fdparam_list /* $6 */
......@@ -10030,9 +10046,6 @@ sf_tail:
my_error(ER_SP_NORETURN, MYF(0), sp->m_qname.str);
MYSQL_YYABORT;
}
/* Restore flag if it was cleared above */
if (sp->m_old_cmq)
YYTHD->client_capabilities |= CLIENT_MULTI_QUERIES;
sp->restore_thd_mem_root(YYTHD);
}
;
......@@ -10062,13 +10075,6 @@ sp_tail:
sp->init_sp_name(YYTHD, $3);
lex->sphead= sp;
/*
* We have to turn of CLIENT_MULTI_QUERIES while parsing a
* stored procedure, otherwise yylex will chop it into pieces
* at each ';'.
*/
sp->m_old_cmq= YYTHD->client_capabilities & CLIENT_MULTI_QUERIES;
YYTHD->client_capabilities &= (~CLIENT_MULTI_QUERIES);
}
'('
{
......@@ -10104,9 +10110,6 @@ sp_tail:
sp->init_strings(YYTHD, lex);
lex->sql_command= SQLCOM_CREATE_PROCEDURE;
/* Restore flag if it was cleared above */
if (sp->m_old_cmq)
YYTHD->client_capabilities |= CLIENT_MULTI_QUERIES;
sp->restore_thd_mem_root(YYTHD);
}
;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment