Commit ed301641 authored by Georgi Kodinov's avatar Georgi Kodinov

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

parents 38ae5d10 a129837f
--require r/have_archive.require --require r/have_archive.require
--disable_query_log --disable_query_log
show variables like "have_archive"; show variables like 'have_archive';
--enable_query_log --enable_query_log
-- require r/have_bdb.require -- require r/have_bdb.require
disable_query_log; disable_query_log;
show variables like "have_bdb"; show variables like 'have_bdb';
enable_query_log; enable_query_log;
-- require r/have_big5.require -- require r/have_big5.require
disable_query_log; disable_query_log;
show collation like "big5_chinese_ci"; show collation like 'big5_chinese_ci';
enable_query_log; enable_query_log;
-- require r/have_blackhole.require -- require r/have_blackhole.require
disable_query_log; disable_query_log;
show variables like "have_blackhole_engine"; show variables like 'have_blackhole_engine';
enable_query_log; enable_query_log;
--require r/case_sensitive_file_system.require --require r/case_sensitive_file_system.require
--disable_query_log --disable_query_log
show variables like "lower_case_file_system"; show variables like 'lower_case_file_system';
--enable_query_log --enable_query_log
-- require r/have_compress.require -- require r/have_compress.require
disable_query_log; disable_query_log;
show variables like "have_compress"; show variables like 'have_compress';
enable_query_log; enable_query_log;
-- require r/have_cp1250_ch.require -- require r/have_cp1250_ch.require
disable_query_log; disable_query_log;
show collation like "cp1250_czech_cs"; show collation like 'cp1250_czech_cs';
enable_query_log; enable_query_log;
-- require r/have_cp932.require -- require r/have_cp932.require
disable_query_log; disable_query_log;
show collation like "cp932_japanese_ci"; show collation like 'cp932_japanese_ci';
enable_query_log; enable_query_log;
-- require r/have_crypt.require -- require r/have_crypt.require
disable_query_log; disable_query_log;
show variables like "have_crypt"; show variables like 'have_crypt';
enable_query_log; enable_query_log;
-- require r/have_csv.require -- require r/have_csv.require
disable_query_log; disable_query_log;
show variables like "have_csv"; show variables like 'have_csv';
enable_query_log; enable_query_log;
-- require r/have_eucjpms.require -- require r/have_eucjpms.require
disable_query_log; disable_query_log;
show collation like "eucjpms_japanese_ci"; show collation like 'eucjpms_japanese_ci';
enable_query_log; enable_query_log;
-- require r/have_euckr.require -- require r/have_euckr.require
disable_query_log; disable_query_log;
show collation like "euckr_korean_ci"; show collation like 'euckr_korean_ci';
enable_query_log; enable_query_log;
-- require r/have_exampledb.require -- require r/have_exampledb.require
disable_query_log; disable_query_log;
show variables like "have_example_engine"; show variables like 'have_example_engine';
enable_query_log; enable_query_log;
-- require r/have_federated_db.require -- require r/have_federated_db.require
disable_query_log; disable_query_log;
show variables like "have_federated_engine"; show variables like 'have_federated_engine';
enable_query_log; enable_query_log;
-- require r/have_gb2312.require -- require r/have_gb2312.require
disable_query_log; disable_query_log;
show collation like "gb2312_chinese_ci"; show collation like 'gb2312_chinese_ci';
enable_query_log; enable_query_log;
-- require r/have_gbk.require -- require r/have_gbk.require
disable_query_log; disable_query_log;
show collation like "gbk_chinese_ci"; show collation like 'gbk_chinese_ci';
enable_query_log; enable_query_log;
--require r/have_geometry.require --require r/have_geometry.require
--disable_query_log --disable_query_log
show variables like "have_geometry"; show variables like 'have_geometry';
--enable_query_log --enable_query_log
-- require r/have_innodb.require -- require r/have_innodb.require
disable_query_log; disable_query_log;
show variables like "have_innodb"; show variables like 'have_innodb';
enable_query_log; enable_query_log;
-- require r/have_latin2_ch.require -- require r/have_latin2_ch.require
disable_query_log; disable_query_log;
show collation like "latin2_czech_cs"; show collation like 'latin2_czech_cs';
enable_query_log; enable_query_log;
-- require r/have_log_bin.require -- require r/have_log_bin.require
disable_query_log; disable_query_log;
show variables like "log_bin"; show variables like 'log_bin';
enable_query_log; enable_query_log;
--require r/lowercase0.require --require r/lowercase0.require
--disable_query_log --disable_query_log
show variables like "lower_case_%"; show variables like 'lower_case_%';
--enable_query_log --enable_query_log
...@@ -10,7 +10,7 @@ drop table if exists t1, t2; ...@@ -10,7 +10,7 @@ drop table if exists t1, t2;
--enable_warnings --enable_warnings
flush tables; flush tables;
--require r/have_ndb.require --require r/have_ndb.require
show variables like "have_ndbcluster"; show variables like 'have_ndbcluster';
enable_query_log; enable_query_log;
# Check that server2 has NDB support # Check that server2 has NDB support
...@@ -21,7 +21,7 @@ drop table if exists t1, t2; ...@@ -21,7 +21,7 @@ drop table if exists t1, t2;
--enable_warnings --enable_warnings
flush tables; flush tables;
--require r/have_ndb.require --require r/have_ndb.require
show variables like "have_ndbcluster"; show variables like 'have_ndbcluster';
enable_query_log; enable_query_log;
# Set the default connection to 'server1' # Set the default connection to 'server1'
......
# Check that server is compiled and started with support for NDB # Check that server is compiled and started with support for NDB
-- require r/have_ndb.require -- require r/have_ndb.require
disable_query_log; disable_query_log;
show variables like "have_ndbcluster"; show variables like 'have_ndbcluster';
enable_query_log; enable_query_log;
# Check that NDB is installed and known to be working # Check that NDB is installed and known to be working
......
...@@ -3,5 +3,5 @@ ...@@ -3,5 +3,5 @@
# of query cache hits # of query cache hits
-- disable_ps_protocol -- disable_ps_protocol
disable_query_log; disable_query_log;
show variables like "have_query_cache"; show variables like 'have_query_cache';
enable_query_log; enable_query_log;
-- require r/have_sjis.require -- require r/have_sjis.require
disable_query_log; disable_query_log;
show collation like "sjis_japanese_ci"; show collation like 'sjis_japanese_ci';
enable_query_log; enable_query_log;
-- require r/have_ssl.require -- require r/have_ssl.require
disable_query_log; disable_query_log;
show variables like "have_ssl"; show variables like 'have_ssl';
enable_query_log; enable_query_log;
-- require r/have_tis620.require -- require r/have_tis620.require
disable_query_log; disable_query_log;
show collation like "tis620_thai_ci"; show collation like 'tis620_thai_ci';
enable_query_log; enable_query_log;
-- require r/have_ucs2.require -- require r/have_ucs2.require
disable_query_log; disable_query_log;
show collation like "ucs2_general_ci"; show collation like 'ucs2_general_ci';
enable_query_log; enable_query_log;
...@@ -4,7 +4,7 @@ ...@@ -4,7 +4,7 @@
# #
--require r/have_udf.require --require r/have_udf.require
disable_query_log; disable_query_log;
show variables like "have_dynamic_loading"; show variables like 'have_dynamic_loading';
enable_query_log; enable_query_log;
# #
......
-- require r/have_ujis.require -- require r/have_ujis.require
disable_query_log; disable_query_log;
show collation like "ujis_japanese_ci"; show collation like 'ujis_japanese_ci';
enable_query_log; enable_query_log;
...@@ -35,7 +35,7 @@ ERROR 42000: You have an error in your SQL syntax; check the manual that corresp ...@@ -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;"; 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/*! AND 2=2;*"; 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';"; 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 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';*"; 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 ...@@ -85,9 +85,9 @@ NULL
NULL NULL
NULL NULL
prepare stmt6 from 'select 1; select2'; 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'; 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'; 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 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 create table t2
......
...@@ -78,3 +78,34 @@ alter table t1 modify a varchar(255); ...@@ -78,3 +78,34 @@ alter table t1 modify a varchar(255);
select length(a) from t1; select length(a) from t1;
length(a) length(a)
6 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 @@ ...@@ -10,11 +10,6 @@
# 2008-06-06 mleich Create this this variant for the embedded server. # 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%'`) if (`SELECT VERSION() NOT LIKE '%embedded%'`)
{ {
--skip Test requires: embedded server --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; ...@@ -84,3 +84,31 @@ select length(a) from t1;
alter table t1 modify a varchar(255); alter table t1 modify a varchar(255);
select length(a) from t1; 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; ...@@ -48,13 +48,12 @@ char *my_defaults_extra_file=0;
/* Which directories are searched for options (and in which order) */ /* Which directories are searched for options (and in which order) */
#define MAX_DEFAULT_DIRS 6 #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__ #ifdef __WIN__
static const char *f_extensions[]= { ".ini", ".cnf", 0 }; static const char *f_extensions[]= { ".ini", ".cnf", 0 };
#define NEWLINE "\r\n" #define NEWLINE "\r\n"
static char system_dir[FN_REFLEN], shared_system_dir[FN_REFLEN],
config_dir[FN_REFLEN];
#else #else
static const char *f_extensions[]= { ".cnf", 0 }; static const char *f_extensions[]= { ".cnf", 0 };
#define NEWLINE "\n" #define NEWLINE "\n"
...@@ -85,19 +84,34 @@ static int search_default_file_with_ext(Process_option_func func, ...@@ -85,19 +84,34 @@ static int search_default_file_with_ext(Process_option_func func,
const char *config_file, int recursion_level); const char *config_file, int recursion_level);
/** /**
Create the list of default directories. Create the list of default directories.
@param alloc MEM_ROOT where the list of directories is stored
@details @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 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, to the end of the list. This avoids reading defaults files multiple times,
while ensuring the correct precedence. 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); static char *remove_end_comment(char *ptr);
...@@ -386,8 +400,9 @@ int load_defaults(const char *conf_file, const char **groups, ...@@ -386,8 +400,9 @@ int load_defaults(const char *conf_file, const char **groups,
struct handle_option_ctx ctx; struct handle_option_ctx ctx;
DBUG_ENTER("load_defaults"); DBUG_ENTER("load_defaults");
init_default_directories();
init_alloc_root(&alloc,512,0); 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 Check if the user doesn't want any default option processing
--no-defaults is always the first option --no-defaults is always the first option
...@@ -864,34 +879,49 @@ void my_print_default_files(const char *conf_file) ...@@ -864,34 +879,49 @@ void my_print_default_files(const char *conf_file)
my_bool have_ext= fn_ext(conf_file)[0] != 0; my_bool have_ext= fn_ext(conf_file)[0] != 0;
const char **exts_to_use= have_ext ? empty_list : f_extensions; const char **exts_to_use= have_ext ? empty_list : f_extensions;
char name[FN_REFLEN], **ext; char name[FN_REFLEN], **ext;
const char **dirs;
init_default_directories();
puts("\nDefault options are read from the following files in the given order:"); puts("\nDefault options are read from the following files in the given order:");
if (dirname_length(conf_file)) if (dirname_length(conf_file))
fputs(conf_file,stdout); fputs(conf_file,stdout);
else 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)
{ {
for (ext= (char**) exts_to_use; *ext; ext++) fputs("Internal error initializing default directories list", stdout);
}
else
{
for ( ; *dirs; dirs++)
{ {
const char *pos; for (ext= (char**) exts_to_use; *ext; ext++)
char *end; {
if (**dirs) const char *pos;
pos= *dirs; char *end;
else if (my_defaults_extra_file) if (**dirs)
pos= my_defaults_extra_file; pos= *dirs;
else else if (my_defaults_extra_file)
continue; pos= my_defaults_extra_file;
end= convert_dirname(name, pos, NullS); else
if (name[0] == FN_HOMELIB) /* Add . to filenames in home */ continue;
*end++='.'; end= convert_dirname(name, pos, NullS);
strxmov(end, conf_file, *ext, " ", NullS); if (name[0] == FN_HOMELIB) /* Add . to filenames in home */
fputs(name,stdout); *end++= '.';
strxmov(end, conf_file, *ext, " ", NullS);
fputs(name, stdout);
}
} }
} }
free_root(&alloc, MYF(0));
} }
puts(""); puts("");
} }
...@@ -928,32 +958,23 @@ void print_defaults(const char *conf_file, const char **groups) ...@@ -928,32 +958,23 @@ void print_defaults(const char *conf_file, const char **groups)
#include <help_end.h> #include <help_end.h>
/* static int add_directory(MEM_ROOT *alloc, const char *dir, const char **dirs)
This extra complexity is to avoid declaring 'rc' if it won't be {
used. char buf[FN_REFLEN];
*/ uint len;
#define ADD_DIRECTORY_INTERNAL(DIR) \ char *p;
array_append_string_unique((DIR), default_directories, \ my_bool err __attribute__((unused));
array_elements(default_directories))
#ifdef DBUG_OFF /* Normalize directory name */
# define ADD_DIRECTORY(DIR) (void) ADD_DIRECTORY_INTERNAL(DIR) len= unpack_dirname(buf, dir);
#else if (!(p= strmake_root(alloc, buf, len)))
#define ADD_DIRECTORY(DIR) \ return 1; /* Failure */
do { \ /* Should never fail if DEFAULT_DIRS_SIZE is correct size */
my_bool rc= ADD_DIRECTORY_INTERNAL(DIR); \ err= array_append_string_unique(p, dirs, DEFAULT_DIRS_SIZE);
DBUG_ASSERT(rc == FALSE); /* Success */ \ DBUG_ASSERT(err == FALSE);
} while (0)
#endif
#define ADD_COMMON_DIRECTORIES() \ return 0;
do { \ }
char *env; \
if ((env= getenv(STRINGIFY_ARG(DEFAULT_HOME_ENV)))) \
ADD_DIRECTORY(env); \
/* Placeholder for --defaults-extra-file=<path> */ \
ADD_DIRECTORY(""); \
} while (0)
#ifdef __WIN__ #ifdef __WIN__
...@@ -992,138 +1013,93 @@ static uint my_get_system_windows_directory(char *buffer, uint size) ...@@ -992,138 +1013,93 @@ static uint my_get_system_windows_directory(char *buffer, uint size)
} }
/** static const char *my_get_module_parent(char *buf, size_t 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()
{ {
bzero((char *) default_directories, sizeof(default_directories)); char *last= NULL;
char *end;
if (my_get_system_windows_directory(shared_system_dir, if (!GetModuleFileName(NULL, buf, size))
sizeof(shared_system_dir))) return NULL;
ADD_DIRECTORY(shared_system_dir); end= strend(buf);
if (GetWindowsDirectory(system_dir,sizeof(system_dir)))
ADD_DIRECTORY(system_dir);
ADD_DIRECTORY("C:/");
if (GetModuleFileName(NULL, config_dir, sizeof(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 > buf; end--)
{ {
char *last= NULL, *end= strend(config_dir); if (*end == FN_LIBCHAR)
/*
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--)
{ {
if (*end == FN_LIBCHAR) if (last)
{ {
if (last) /* Keep the last '\' as this works both with D:\ and a directory */
{ end[1]= 0;
if (end != config_dir) break;
{
/* 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;
} }
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 static const char **init_default_directories(MEM_ROOT *alloc)
1. sys:/etc/
2. getenv(DEFAULT_HOME_ENV)
3. --defaults-extra-file=<path> (run-time option)
*/
static void init_default_directories_netware()
{ {
bzero((char *) default_directories, sizeof(default_directories)); const char **dirs;
ADD_DIRECTORY("sys:/etc/"); char *env;
ADD_COMMON_DIRECTORIES(); 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 if (GetWindowsDirectory(fname_buffer, sizeof(fname_buffer)))
1. /etc/ errors += add_directory(alloc, fname_buffer, dirs);
2. getenv(ETC)
3. getenv(DEFAULT_HOME_ENV)
4. --defaults-extra-file=<path> (run-time option)
*/
static void init_default_directories_os2() errors += add_directory(alloc, "C:/", dirs);
{
const char *env;
bzero((char *) default_directories, sizeof(default_directories)); if (my_get_module_parent(fname_buffer, sizeof(fname_buffer)) != NULL)
ADD_DIRECTORY("/etc/"); errors += add_directory(alloc, fname_buffer, dirs);
if ((env= getenv("ETC"))) }
ADD_DIRECTORY(env);
ADD_COMMON_DIRECTORIES();
}
static void (*init_default_directories)()= init_default_directories_os2; #elif defined(__NETWARE__)
#else errors += add_directory(alloc, "sys:/etc/", dirs);
/** #else
Initialize default directories for Unix
@details errors += add_directory(alloc, "/etc/", dirs);
1. /etc/
2. --sysconfdir=<path> (compile-time option)
3. getenv(DEFAULT_HOME_ENV)
4. --defaults-extra-file=<path> (run-time option)
5. "~/"
*/
static void init_default_directories_unix() #if defined(__EMX__) || defined(OS2)
{ if ((env= getenv("ETC")))
bzero((char *) default_directories, sizeof(default_directories)); errors += add_directory(alloc, env, dirs);
ADD_DIRECTORY("/etc/"); #elif defined(DEFAULT_SYSCONFDIR)
#ifdef DEFAULT_SYSCONFDIR
if (DEFAULT_SYSCONFDIR != "") if (DEFAULT_SYSCONFDIR != "")
ADD_DIRECTORY(DEFAULT_SYSCONFDIR); errors += add_directory(alloc, DEFAULT_SYSCONFDIR, dirs);
#endif /* __EMX__ || __OS2__ */
#endif #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 #endif
return (errors > 0 ? NULL : dirs);
}
...@@ -5013,21 +5013,28 @@ Item_bin_string::Item_bin_string(const char *str, uint str_length) ...@@ -5013,21 +5013,28 @@ Item_bin_string::Item_bin_string(const char *str, uint str_length)
if (!ptr) if (!ptr)
return; return;
str_value.set(ptr, max_length, &my_charset_bin); str_value.set(ptr, max_length, &my_charset_bin);
ptr+= max_length - 1;
ptr[1]= 0; // Set end null for string if (max_length > 0)
for (; end >= str; end--)
{ {
if (power == 256) ptr+= max_length - 1;
ptr[1]= 0; // Set end null for string
for (; end >= str; end--)
{ {
power= 1; if (power == 256)
*ptr--= bits; {
bits= 0; power= 1;
*ptr--= bits;
bits= 0;
}
if (*end == '1')
bits|= power;
power<<= 1;
} }
if (*end == '1') *ptr= (char) bits;
bits|= power;
power<<= 1;
} }
*ptr= (char) bits; else
ptr[0]= 0;
collation.set(&my_charset_bin, DERIVATION_COERCIBLE); collation.set(&my_charset_bin, DERIVATION_COERCIBLE);
fixed= 1; fixed= 1;
} }
......
...@@ -4154,8 +4154,14 @@ int User_var_log_event::exec_event(struct st_relay_log_info* rli) ...@@ -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 => Item_func_set_user_var can't substitute something else on its place =>
0 can be passed as last argument (reference on item) 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 variable can just be considered as a table with
a single record and with a single column. Thus, like a single record and with a single column. Thus, like
......
...@@ -117,7 +117,6 @@ class sp_head :private Query_arena ...@@ -117,7 +117,6 @@ class sp_head :private Query_arena
create_field m_return_field_def; /* This is used for FUNCTIONs only. */ create_field m_return_field_def; /* This is used for FUNCTIONs only. */
const char *m_tmp_query; // Temporary pointer to sub query string 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; st_sp_chistics *m_chistics;
ulong m_sql_mode; // For SHOW CREATE and execution ulong m_sql_mode; // For SHOW CREATE and execution
LEX_STRING m_qname; // db.name LEX_STRING m_qname; // db.name
......
...@@ -1010,21 +1010,8 @@ int MYSQLlex(void *arg, void *yythd) ...@@ -1010,21 +1010,8 @@ int MYSQLlex(void *arg, void *yythd)
yySkip(); yySkip();
return (SET_VAR); return (SET_VAR);
case MY_LEX_SEMICOLON: // optional line terminator case MY_LEX_SEMICOLON: // optional line terminator
if (yyPeek()) state= MY_LEX_CHAR; // Return ';'
{ break;
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: case MY_LEX_EOL:
if (lip->ptr >= lip->end_of_query) if (lip->ptr >= lip->end_of_query)
{ {
...@@ -1039,7 +1026,7 @@ int MYSQLlex(void *arg, void *yythd) ...@@ -1039,7 +1026,7 @@ int MYSQLlex(void *arg, void *yythd)
case MY_LEX_END: case MY_LEX_END:
lip->next_state=MY_LEX_END; lip->next_state=MY_LEX_END;
return(0); // We found end of input last time return(0); // We found end of input last time
/* Actually real shouldn't start with . but allow them anyhow */ /* Actually real shouldn't start with . but allow them anyhow */
case MY_LEX_REAL_OR_POINT: case MY_LEX_REAL_OR_POINT:
if (my_isdigit(cs,yyPeek())) if (my_isdigit(cs,yyPeek()))
......
...@@ -6169,6 +6169,11 @@ void mysql_parse(THD *thd, const char *inBuf, uint length, ...@@ -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= (ulong)(lip.found_semicolon - thd->query)))
thd->query_length--; thd->query_length--;
/* Actually execute the query */ /* 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(); lex->set_trg_event_type_for_tables();
mysql_execute_command(thd); mysql_execute_command(thd);
query_cache_end_of_result(thd); query_cache_end_of_result(thd);
......
...@@ -1203,21 +1203,54 @@ END_OF_INPUT ...@@ -1203,21 +1203,54 @@ END_OF_INPUT
query: query:
END_OF_INPUT END_OF_INPUT
{ {
THD *thd= YYTHD; THD *thd= YYTHD;
if (!thd->bootstrap && if (!thd->bootstrap &&
(!(thd->lex->select_lex.options & OPTION_FOUND_COMMENT))) (!(thd->lex->select_lex.options & OPTION_FOUND_COMMENT)))
{ {
my_message(ER_EMPTY_QUERY, ER(ER_EMPTY_QUERY), MYF(0)); my_message(ER_EMPTY_QUERY, ER(ER_EMPTY_QUERY), MYF(0));
MYSQL_YYABORT; MYSQL_YYABORT;
} }
else thd->lex->sql_command= SQLCOM_EMPTY_QUERY;
{ thd->m_lip->found_semicolon= NULL;
thd->lex->sql_command= SQLCOM_EMPTY_QUERY; }
} | verb_clause
} {
| verb_clause END_OF_INPUT {}; 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
{
/* Single query, terminated. */
lip->found_semicolon= NULL;
}
}
';'
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: verb_clause:
statement statement
...@@ -9867,13 +9900,6 @@ trigger_tail: ...@@ -9867,13 +9900,6 @@ trigger_tail:
lex->sphead= sp; lex->sphead= sp;
lex->spname= $3; 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)); bzero((char *)&lex->sp_chistics, sizeof(st_sp_chistics));
lex->sphead->m_chistics= &lex->sp_chistics; lex->sphead->m_chistics= &lex->sp_chistics;
...@@ -9888,9 +9914,6 @@ trigger_tail: ...@@ -9888,9 +9914,6 @@ trigger_tail:
lex->sql_command= SQLCOM_CREATE_TRIGGER; lex->sql_command= SQLCOM_CREATE_TRIGGER;
sp->init_strings(YYTHD, lex); 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); sp->restore_thd_mem_root(YYTHD);
if (sp->is_not_allowed_in_function("trigger")) if (sp->is_not_allowed_in_function("trigger"))
...@@ -9968,13 +9991,6 @@ sf_tail: ...@@ -9968,13 +9991,6 @@ sf_tail:
sp->m_type= TYPE_ENUM_FUNCTION; sp->m_type= TYPE_ENUM_FUNCTION;
lex->sphead= sp; 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; lex->sphead->m_param_begin= lip->tok_start+1;
} }
sp_fdparam_list /* $6 */ sp_fdparam_list /* $6 */
...@@ -10030,9 +10046,6 @@ sf_tail: ...@@ -10030,9 +10046,6 @@ sf_tail:
my_error(ER_SP_NORETURN, MYF(0), sp->m_qname.str); my_error(ER_SP_NORETURN, MYF(0), sp->m_qname.str);
MYSQL_YYABORT; 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); sp->restore_thd_mem_root(YYTHD);
} }
; ;
...@@ -10062,13 +10075,6 @@ sp_tail: ...@@ -10062,13 +10075,6 @@ sp_tail:
sp->init_sp_name(YYTHD, $3); sp->init_sp_name(YYTHD, $3);
lex->sphead= sp; 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: ...@@ -10104,9 +10110,6 @@ sp_tail:
sp->init_strings(YYTHD, lex); sp->init_strings(YYTHD, lex);
lex->sql_command= SQLCOM_CREATE_PROCEDURE; 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); 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