summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/config-win.h4
-rw-r--r--include/my_pthread.h3
-rw-r--r--include/my_sys.h2
-rw-r--r--include/mysql.h2
-rw-r--r--include/mysql_com.h2
-rw-r--r--libmysql/libmysql.c22
-rw-r--r--mysql-test/r/limit.result23
-rw-r--r--mysql-test/r/select_found.result19
-rw-r--r--mysql-test/r/union.result6
-rw-r--r--mysql-test/t/limit.test22
-rw-r--r--mysql-test/t/select_found.test14
-rw-r--r--mysql-test/t/union.test9
-rw-r--r--mysys/mf_pack.c27
-rw-r--r--mysys/my_init.c20
-rw-r--r--mysys/my_lib.c6
-rw-r--r--mysys/my_thr_init.c26
-rw-r--r--sql/sql_base.cc7
-rw-r--r--sql/sql_delete.cc12
-rw-r--r--sql/sql_select.cc2
-rw-r--r--sql/sql_show.cc12
-rw-r--r--sql/sql_yacc.yy1
21 files changed, 194 insertions, 47 deletions
diff --git a/include/config-win.h b/include/config-win.h
index b30f50f0edb..e6f03a10afb 100644
--- a/include/config-win.h
+++ b/include/config-win.h
@@ -151,6 +151,10 @@ typedef uint rf_SetTimer;
#define USE_MB_IDENT 1
#define USE_STRCOLL 1
+/* All windows servers should support .sym files */
+#undef USE_SYMDIR
+#define USE_SYMDIR
+
/* If LOAD DATA LOCAL INFILE should be enabled by default */
#define ENABLED_LOCAL_INFILE 1
diff --git a/include/my_pthread.h b/include/my_pthread.h
index 16a14ac5038..59367ee903c 100644
--- a/include/my_pthread.h
+++ b/include/my_pthread.h
@@ -115,6 +115,7 @@ void pthread_exit(void *a); /* was #define pthread_exit(A) ExitThread(A)*/
#undef SAFE_MUTEX /* This will cause conflicts */
#define pthread_key(T,V) DWORD V
#define pthread_key_create(A,B) ((*A=TlsAlloc())==0xFFFFFFFF)
+#define pthread_key_delete(A) TlsFree(A)
#define pthread_getspecific(A) (TlsGetValue(A))
#define my_pthread_getspecific(T,A) ((T) TlsGetValue(A))
#define my_pthread_getspecific_ptr(T,V) ((T) TlsGetValue(V))
@@ -123,6 +124,7 @@ void pthread_exit(void *a); /* was #define pthread_exit(A) ExitThread(A)*/
#else
#define pthread_key(T,V) __declspec(thread) T V
#define pthread_key_create(A,B) pthread_dummy(0)
+#define pthread_key_delete(A) pthread_dummy(0)
#define pthread_getspecific(A) (&(A))
#define my_pthread_getspecific(T,A) (&(A))
#define my_pthread_getspecific_ptr(T,V) (V)
@@ -178,6 +180,7 @@ extern int pthread_mutex_destroy (pthread_mutex_t *);
typedef int pthread_attr_t; /* Needed by Unixware 7.0.0 */
#define pthread_key_create(A,B) thr_keycreate((A),(B))
+#define pthread_key_delete(A) thr_keydelete(A)
#define pthread_handler_decl(A,B) void *A(void *B)
#define pthread_key(T,V) pthread_key_t V
diff --git a/include/my_sys.h b/include/my_sys.h
index df8b9759e5d..acb4c01b4f1 100644
--- a/include/my_sys.h
+++ b/include/my_sys.h
@@ -577,7 +577,7 @@ extern int my_snprintf(char* to, size_t n, const char* fmt, ...);
extern int my_message(uint my_err, const char *str,myf MyFlags);
extern int my_message_no_curses(uint my_err, const char *str,myf MyFlags);
extern int my_message_curses(uint my_err, const char *str,myf MyFlags);
-extern void my_init(void);
+extern my_bool my_init(void);
extern void my_end(int infoflag);
extern int my_redel(const char *from, const char *to, int MyFlags);
extern int my_copystat(const char *from, const char *to, int MyFlags);
diff --git a/include/mysql.h b/include/mysql.h
index 0c91266e19c..3ffc014c449 100644
--- a/include/mysql.h
+++ b/include/mysql.h
@@ -426,7 +426,7 @@ int STDCALL mysql_drop_db(MYSQL *mysql, const char *DB);
int simple_command(MYSQL *mysql,enum enum_server_command command,
const char *arg, unsigned long length, my_bool skipp_check);
unsigned long net_safe_read(MYSQL* mysql);
-void mysql_once_init(void);
+int mysql_once_init(void);
extern my_bool server_inited;
diff --git a/include/mysql_com.h b/include/mysql_com.h
index a874034ba46..e183a0ed423 100644
--- a/include/mysql_com.h
+++ b/include/mysql_com.h
@@ -241,7 +241,7 @@ void hash_password(unsigned long *result, const char *password);
/* Some other useful functions */
-void my_init(void);
+my_bool my_init(void);
int load_defaults(const char *conf_file, const char **groups,
int *argc, char ***argv);
my_bool my_thread_init(void);
diff --git a/libmysql/libmysql.c b/libmysql/libmysql.c
index 5fcc3ba5ee0..607d8af6e50 100644
--- a/libmysql/libmysql.c
+++ b/libmysql/libmysql.c
@@ -102,8 +102,7 @@ int STDCALL mysql_server_init(int argc __attribute__((unused)),
char **argv __attribute__((unused)),
char **groups __attribute__((unused)))
{
- mysql_once_init();
- return 0;
+ return (int) mysql_once_init();
}
void STDCALL mysql_server_end()
@@ -1436,7 +1435,8 @@ STDCALL mysql_rpl_query_type(const char* q, int len)
MYSQL * STDCALL
mysql_init(MYSQL *mysql)
{
- mysql_once_init();
+ if (mysql_once_init())
+ return 0;
if (!mysql)
{
if (!(mysql=(MYSQL*) my_malloc(sizeof(*mysql),MYF(MY_WME | MY_ZEROFILL))))
@@ -1476,15 +1476,20 @@ mysql_init(MYSQL *mysql)
This function is called by mysql_init() and indirectly called
by mysql_query(), so one should never have to call this from an
outside program.
+
+ RETURN
+ 0 ok
+ 1 could not initialize environment (out of memory or thread keys)
*/
-void mysql_once_init(void)
+int mysql_once_init(void)
{
if (!mysql_client_init)
{
mysql_client_init=1;
org_my_init_done=my_init_done;
- my_init(); /* Will init threads */
+ if (my_init()) /* Will init threads */
+ return 1;
init_client_errs();
if (!mysql_port)
{
@@ -1518,10 +1523,15 @@ void mysql_once_init(void)
}
#ifdef THREAD
else
- my_thread_init(); /* Init if new thread */
+ {
+ if (my_thread_init()) /* Init if new thread */
+ return 1;
+ }
#endif
+ return 0;
}
+
/**************************************************************************
Fill in SSL part of MYSQL structure and set 'use_ssl' flag.
NB! Errors are not reported until you do mysql_real_connect.
diff --git a/mysql-test/r/limit.result b/mysql-test/r/limit.result
index 5a8edc99c12..c82105e6a49 100644
--- a/mysql-test/r/limit.result
+++ b/mysql-test/r/limit.result
@@ -36,9 +36,7 @@ a b
3 4
drop table t1;
create table t1 (i int);
-insert into t1 (i) values(1);
-insert into t1 (i) values(1);
-insert into t1 (i) values(1);
+insert into t1 (i) values(1),(1),(1);
delete from t1 limit 1;
update t1 set i=2 limit 1;
delete from t1 limit 0;
@@ -50,3 +48,22 @@ i
drop table t1;
select 0 limit 0;
0
+CREATE TABLE t1(id int auto_increment primary key, id2 int, index(id2));
+INSERT INTO t1 (id2) values (0),(0),(0);
+DELETE FROM t1 WHERE id=1;
+INSERT INTO t1 SET id2=0;
+SELECT * FROM t1;
+id id2
+4 0
+2 0
+3 0
+DELETE FROM t1 WHERE id2 = 0 ORDER BY id LIMIT 1;
+SELECT * FROM t1;
+id id2
+4 0
+3 0
+DELETE FROM t1 WHERE id2 = 0 ORDER BY id desc LIMIT 1;
+SELECT * FROM t1;
+id id2
+3 0
+DROP TABLE t1;
diff --git a/mysql-test/r/select_found.result b/mysql-test/r/select_found.result
index 0a7f464cf7b..419ffb73d59 100644
--- a/mysql-test/r/select_found.result
+++ b/mysql-test/r/select_found.result
@@ -169,3 +169,22 @@ SELECT FOUND_ROWS();
FOUND_ROWS()
2
drop table t1;
+create table t1 (id int, primary key (id));
+insert into t1 values (1), (2), (3), (4), (5);
+select SQL_CALC_FOUND_ROWS * from t1 where id > 3 limit 0, 1;
+id
+4
+select FOUND_ROWS();
+FOUND_ROWS()
+2
+select SQL_CALC_FOUND_ROWS * from t1 where id > 3 AND 1=2 limit 0, 1;
+id
+select FOUND_ROWS();
+FOUND_ROWS()
+0
+select SQL_CALC_FOUND_ROWS * from t1 where id > 6 limit 0, 1;
+id
+select FOUND_ROWS();
+FOUND_ROWS()
+0
+drop table t1;
diff --git a/mysql-test/r/union.result b/mysql-test/r/union.result
index cd5d600edf4..fc5aa1ad0cb 100644
--- a/mysql-test/r/union.result
+++ b/mysql-test/r/union.result
@@ -3,7 +3,7 @@ CREATE TABLE t1 (a int not null, b char (10) not null);
insert into t1 values(1,'a'),(2,'b'),(3,'c'),(3,'c');
CREATE TABLE t2 (a int not null, b char (10) not null);
insert into t2 values (3,'c'),(4,'d'),(5,'f'),(6,'e');
-select a,b from t1 union select a,b from t2;
+select a,b from t1 union distinct select a,b from t2;
a b
1 a
2 b
@@ -423,3 +423,7 @@ create temporary table t1 select a from t1 union select a from t2;
create table t1 select a from t1 union select a from t2;
INSERT TABLE 't1' isn't allowed in FROM table list
drop table t1,t2;
+select length(version()) > 1 as `*` UNION select 2;
+*
+1
+2
diff --git a/mysql-test/t/limit.test b/mysql-test/t/limit.test
index d4f6ce186cf..32962073eee 100644
--- a/mysql-test/t/limit.test
+++ b/mysql-test/t/limit.test
@@ -19,9 +19,7 @@ select * from t1;
drop table t1;
create table t1 (i int);
-insert into t1 (i) values(1);
-insert into t1 (i) values(1);
-insert into t1 (i) values(1);
+insert into t1 (i) values(1),(1),(1);
delete from t1 limit 1;
update t1 set i=2 limit 1;
delete from t1 limit 0;
@@ -29,4 +27,22 @@ update t1 set i=3 limit 0;
select * from t1;
drop table t1;
+# LIMIT 0
+
select 0 limit 0;
+
+#
+# Test with DELETE, ORDER BY and limit (bug #1024)
+#
+
+CREATE TABLE t1(id int auto_increment primary key, id2 int, index(id2));
+INSERT INTO t1 (id2) values (0),(0),(0);
+DELETE FROM t1 WHERE id=1;
+INSERT INTO t1 SET id2=0;
+SELECT * FROM t1;
+DELETE FROM t1 WHERE id2 = 0 ORDER BY id LIMIT 1;
+# should have deleted WHERE id=2
+SELECT * FROM t1;
+DELETE FROM t1 WHERE id2 = 0 ORDER BY id desc LIMIT 1;
+SELECT * FROM t1;
+DROP TABLE t1;
diff --git a/mysql-test/t/select_found.test b/mysql-test/t/select_found.test
index 0a483c860cb..f5ee4d5c010 100644
--- a/mysql-test/t/select_found.test
+++ b/mysql-test/t/select_found.test
@@ -85,3 +85,17 @@ INSERT INTO t1 (titre,maxnumrep) VALUES
SELECT SQL_CALC_FOUND_ROWS titre,numeropost,maxnumrep FROM t1 WHERE numeropost IN (1,2) ORDER BY maxnumrep DESC LIMIT 0, 1;
SELECT FOUND_ROWS();
drop table t1;
+
+#
+# Test problem with impossible WHERE (Bug #1468)
+#
+
+create table t1 (id int, primary key (id));
+insert into t1 values (1), (2), (3), (4), (5);
+select SQL_CALC_FOUND_ROWS * from t1 where id > 3 limit 0, 1;
+select FOUND_ROWS();
+select SQL_CALC_FOUND_ROWS * from t1 where id > 3 AND 1=2 limit 0, 1;
+select FOUND_ROWS();
+select SQL_CALC_FOUND_ROWS * from t1 where id > 6 limit 0, 1;
+select FOUND_ROWS();
+drop table t1;
diff --git a/mysql-test/t/union.test b/mysql-test/t/union.test
index ba4673e9a88..badfe4b9a3a 100644
--- a/mysql-test/t/union.test
+++ b/mysql-test/t/union.test
@@ -8,7 +8,7 @@ insert into t1 values(1,'a'),(2,'b'),(3,'c'),(3,'c');
CREATE TABLE t2 (a int not null, b char (10) not null);
insert into t2 values (3,'c'),(4,'d'),(5,'f'),(6,'e');
-select a,b from t1 union select a,b from t2;
+select a,b from t1 union distinct select a,b from t2;
select a,b from t1 union all select a,b from t2;
select a,b from t1 union all select a,b from t2 order by b;
select a,b from t1 union all select a,b from t2 union select 7,'g';
@@ -227,3 +227,10 @@ create temporary table t1 select a from t1 union select a from t2;
--error 1093
create table t1 select a from t1 union select a from t2;
drop table t1,t2;
+
+#
+# Problem with alias '*' (BUG #1249)
+#
+
+select length(version()) > 1 as `*` UNION select 2;
+
diff --git a/mysys/mf_pack.c b/mysys/mf_pack.c
index b3aa347006e..e2e811fe89a 100644
--- a/mysys/mf_pack.c
+++ b/mysys/mf_pack.c
@@ -210,13 +210,13 @@ uint cleanup_dirname(register my_string to, const char *from)
} /* cleanup_dirname */
- /*
- On system where you don't have symbolic links, the following
- code will allow you to create a file:
- directory-name.lnk that should contain the real path
- to the directory. This will be used if the directory name
- doesn't exists
- */
+/*
+ On system where you don't have symbolic links, the following
+ code will allow you to create a file:
+ directory-name.sym that should contain the real path
+ to the directory. This will be used if the directory name
+ doesn't exists
+*/
my_bool my_use_symdir=0; /* Set this if you want to use symdirs */
@@ -228,16 +228,17 @@ void symdirget(char *dir)
char *pos=strend(dir);
if (dir[0] && pos[-1] != FN_DEVCHAR && access(dir, F_OK))
{
- FILE *fp;
+ File file;
+ uint length;
char temp= *(--pos); /* May be "/" or "\" */
strmov(pos,".sym");
- fp = my_fopen(dir, O_RDONLY,MYF(0));
+ file= my_open(dir, O_RDONLY, MYF(0));
*pos++=temp; *pos=0; /* Restore old filename */
- if (fp)
+ if (file >= 0)
{
- if (fgets(buff, sizeof(buff)-1, fp))
+ if ((length= my_read(file, buff, sizeof(buff), MYF(0))) > 0)
{
- for (pos=strend(buff);
+ for (pos= buff + length ;
pos > buff && (iscntrl(pos[-1]) || isspace(pos[-1])) ;
pos --);
@@ -247,7 +248,7 @@ void symdirget(char *dir)
strmake(dir,buff, (uint) (pos-buff));
}
- my_fclose(fp,MYF(0));
+ my_close(file, MYF(0));
}
}
}
diff --git a/mysys/my_init.c b/mysys/my_init.c
index a8a184a2cb4..8d4ba2c97b6 100644
--- a/mysys/my_init.c
+++ b/mysys/my_init.c
@@ -62,13 +62,22 @@ static ulong atoi_octal(const char *str)
}
- /* Init my_sys functions and my_sys variabels */
+/*
+ Init my_sys functions and my_sys variabels
+
+ SYNOPSIS
+ my_init()
-void my_init(void)
+ RETURN
+ 0 ok
+ 1 Couldn't initialize environment
+*/
+
+my_bool my_init(void)
{
my_string str;
if (my_init_done)
- return;
+ return 0;
my_init_done=1;
#if defined(THREAD) && defined(SAFE_MUTEX)
safe_mutex_global_init(); /* Must be called early */
@@ -78,7 +87,8 @@ void my_init(void)
#if defined(HAVE_PTHREAD_INIT)
pthread_init(); /* Must be called before DBUG_ENTER */
#endif
- my_thread_global_init();
+ if (my_thread_global_init())
+ return 1;
#if !defined( __WIN__) && !defined(OS2) && !defined(__NETWARE__)
sigfillset(&my_signals); /* signals blocked by mf_brkhant */
#endif
@@ -110,7 +120,7 @@ void my_init(void)
#ifdef __WIN__
win32_init_tcp_ip();
#endif
- DBUG_VOID_RETURN;
+ DBUG_RETURN(0);
}
} /* my_init */
diff --git a/mysys/my_lib.c b/mysys/my_lib.c
index 035bafd07b9..426acedc646 100644
--- a/mysys/my_lib.c
+++ b/mysys/my_lib.c
@@ -602,9 +602,11 @@ MY_STAT *my_stat(const char *path, MY_STAT *stat_area, myf my_flags)
if ((m_used= (stat_area == NULL)))
if (!(stat_area = (MY_STAT *) my_malloc(sizeof(MY_STAT), my_flags)))
goto error;
- if ( ! stat((my_string) path, (struct stat *) stat_area) )
+ if (! stat((my_string) path, (struct stat *) stat_area) )
DBUG_RETURN(stat_area);
- my_errno=errno;
+
+ DBUG_PRINT("error",("Got errno: %d from stat", errno));
+ my_errno= errno;
if (m_used) /* Free if new area */
my_free((gptr) stat_area,MYF(0));
diff --git a/mysys/my_thr_init.c b/mysys/my_thr_init.c
index 9f64e9dcb60..3827b24ac32 100644
--- a/mysys/my_thr_init.c
+++ b/mysys/my_thr_init.c
@@ -44,12 +44,23 @@ pthread_mutexattr_t my_fast_mutexattr;
pthread_mutexattr_t my_errchk_mutexattr;
#endif
+/*
+ initialize thread environment
+
+ SYNOPSIS
+ my_thread_global_init()
+
+ RETURN
+ 0 ok
+ 1 error (Couldn't create THR_KEY_mysys)
+*/
+
my_bool my_thread_global_init(void)
{
- if (pthread_key_create(&THR_KEY_mysys,free))
+ if (pthread_key_create(&THR_KEY_mysys,0))
{
fprintf(stderr,"Can't initialize threads: error %d\n",errno);
- exit(1);
+ return 1;
}
#ifdef PTHREAD_ADAPTIVE_MUTEX_INITIALIZER_NP
pthread_mutexattr_init(&my_fast_mutexattr);
@@ -79,15 +90,18 @@ my_bool my_thread_global_init(void)
#ifndef HAVE_GETHOSTBYNAME_R
pthread_mutex_init(&LOCK_gethostbyname_r,MY_MUTEX_INIT_SLOW);
#endif
- return my_thread_init();
+ if (my_thread_init())
+ {
+ my_thread_global_end(); /* Clean up */
+ return 1;
+ }
+ return 0;
}
void my_thread_global_end(void)
{
-#if defined(USE_TLS)
- (void) TlsFree(THR_KEY_mysys);
-#endif
+ pthread_key_delete(THR_KEY_mysys);
#ifdef PTHREAD_ADAPTIVE_MUTEX_INITIALIZER_NP
pthread_mutexattr_destroy(&my_fast_mutexattr);
#endif
diff --git a/sql/sql_base.cc b/sql/sql_base.cc
index e4694adb9a2..dd80062d6e7 100644
--- a/sql/sql_base.cc
+++ b/sql/sql_base.cc
@@ -1868,8 +1868,13 @@ int setup_fields(THD *thd, TABLE_LIST *tables, List<Item> &fields,
while ((item=it++))
{
+ /*
+ Expand * to all fields if this is not the temporary table for an
+ a UNION result
+ */
if (item->type() == Item::FIELD_ITEM &&
- ((Item_field*) item)->field_name[0] == '*')
+ ((Item_field*) item)->field_name[0] == '*' &&
+ !((Item_field*) item)->field)
{
uint elem=fields.elements;
if (insert_fields(thd,tables,((Item_field*) item)->db_name,
diff --git a/sql/sql_delete.cc b/sql/sql_delete.cc
index 34a79ecd78d..ee2b720907d 100644
--- a/sql/sql_delete.cc
+++ b/sql/sql_delete.cc
@@ -78,7 +78,7 @@ int mysql_delete(THD *thd, TABLE_LIST *table_list, COND *conds, ORDER *order,
DBUG_RETURN(-1);
if ((select && select->check_quick(thd,
test(thd->options & OPTION_SAFE_UPDATES),
- limit)) ||
+ limit)) ||
!limit)
{
delete select;
@@ -117,13 +117,19 @@ int mysql_delete(THD *thd, TABLE_LIST *table_list, COND *conds, ORDER *order,
if (setup_order(thd, &tables, fields, all_fields, order) ||
!(sortorder=make_unireg_sortorder(order, &length)) ||
(table->found_records = filesort(table, sortorder, length,
- (SQL_SELECT *) 0, 0L, HA_POS_ERROR,
+ select, 0L, HA_POS_ERROR,
&examined_rows))
== HA_POS_ERROR)
{
delete select;
- DBUG_RETURN(-1); // This will force out message
+ DBUG_RETURN(-1); // This will force out message
}
+ /*
+ Filesort has already found and selected the rows we want to delete,
+ so we don't need the where clause
+ */
+ delete select;
+ select= 0;
}
init_read_record(&info,thd,table,select,1,1);
diff --git a/sql/sql_select.cc b/sql/sql_select.cc
index df4b0226ff6..892ad02bb5b 100644
--- a/sql/sql_select.cc
+++ b/sql/sql_select.cc
@@ -3273,6 +3273,8 @@ return_zero_rows(JOIN *join, select_result *result,TABLE_LIST *tables,
}
result->send_eof(); // Should be safe
}
+ /* Update results for FOUND_ROWS */
+ join->thd->limit_found_rows= join->thd->examined_row_count= 0;
DBUG_RETURN(0);
}
diff --git a/sql/sql_show.cc b/sql/sql_show.cc
index a7de04d0bfa..cb6cd18b7c8 100644
--- a/sql/sql_show.cc
+++ b/sql/sql_show.cc
@@ -197,7 +197,19 @@ mysql_find_files(THD *thd,List<char> *files, const char *db,const char *path,
#ifdef USE_SYMDIR
char *ext;
if (my_use_symdir && !strcmp(ext=fn_ext(file->name), ".sym"))
+ {
+ /* Only show the sym file if it points to a directory */
+ char buff[FN_REFLEN], *end;
+ MY_STAT status;
*ext=0; /* Remove extension */
+ unpack_dirname(buff, file->name);
+ end= strend(buff);
+ if (end != buff && end[-1] == FN_LIBCHAR)
+ end[-1]= 0; // Remove end FN_LIBCHAR
+ if (!my_stat(buff, &status, MYF(0)) ||
+ !MY_S_ISDIR(status.st_mode))
+ continue;
+ }
else
#endif
{
diff --git a/sql/sql_yacc.yy b/sql/sql_yacc.yy
index 03837300904..b5b9a4cdfb7 100644
--- a/sql/sql_yacc.yy
+++ b/sql/sql_yacc.yy
@@ -4014,5 +4014,6 @@ optional_order_or_limit:
union_option:
/* empty */ {}
+ | DISTINCT {}
| ALL { Lex->union_option=1; }
;