client/CMakeLists.txt | 16
client/mysql.cc | 8
client/mysqladmin.cc | 8
client/mysqlbinlog.cc | 8
client/mysqlcheck.c | 8
client/mysqldump.c | 8
client/mysqlimport.c | 6
client/mysqlshow.c | 8
client/mysqltest.cc | 174 ++++-
dbug/dbug.c | 5
include/config-win.h | 38 +
include/m_string.h | 4
include/my_base.h | 16
include/my_global.h | 24
include/my_pthread.h | 108 ++-
include/mysql.h | 11
include/mysql.h.pp | 47 -
include/mysql_com.h | 55 -
include/violite.h | 19
libmysql/manager.c | 5
libmysqld/CMakeLists.txt | 31
mysys/my_bitmap.c | 20
mysys/my_thr_init.c | 24
mysys/my_winthread.c | 72 +-
mysys/queues.c | 14
scripts/mysql_config.sh | 3
sql-common/client.c | 218 ++++--
sql/CMakeLists.txt | 9
sql/field.cc | 13
sql/field.h | 37 +
sql/ha_partition.cc | 124 +--
sql/ha_partition.h | 25
sql/handler.cc | 94 ++
sql/handler.h | 320 +++++++--
sql/hostname.cc | 195 ++---
sql/item_func.cc | 8
sql/lex.h | 5
sql/log.cc | 51 +
sql/log_event.cc | 53 +
sql/log_event.h | 58 +
sql/mysql_priv.h | 40 -
sql/mysqld.cc | 401 +++++++----
sql/net_serv.cc | 12
sql/rpl_mi.cc | 56 +
sql/rpl_mi.h | 6
sql/set_var.cc | 35 -
sql/slave.cc | 186 ++++-
sql/slave.h | 12
sql/sql_base.cc | 67 +
sql/sql_bitmap.h | 58 +
sql/sql_class.cc | 20
sql/sql_class.h | 10
sql/sql_connect.cc | 26
sql/sql_db.cc | 9
sql/sql_delete.cc | 38 -
sql/sql_lex.h | 69 +-
sql/sql_parse.cc | 8
sql/sql_partition.cc | 213 +++---
sql/sql_rename.cc | 8
sql/sql_repl.cc | 191 +++++
sql/sql_show.cc | 96 ++
sql/sql_table.cc | 1609 +++++++++++++++++++++++++++--------------------
sql/sql_update.cc | 45 +
sql/sql_yacc.yy | 251 +++++--
sql/structs.h | 8
sql/table.cc | 131 ++-
sql/table.h | 6
sql/unireg.cc | 50 +
sql/unireg.h | 7
strings/longlong2str.c | 10
strings/my_vsnprintf.c | 110 ++-
unittest/unit.pl | 15
vio/vio.c | 30
vio/viosocket.c | 136 ++-
vio/viossl.c | 18
win/configure.js | 8
zlib/inflate.h | 5
77 files changed, 4082 insertions(+), 1868 deletions(-)
--
Showing diff between 5.1.34 and 7.0
--- 5.1.34/mysys/my_bitmap.c 2009-06-03 23:17:32.000000000 +0200
+++ 7.0/mysys/my_bitmap.c 2009-06-04 10:35:49.000000000 +0200
@@ -763,7 +766,7 @@
return (rand() % bitsize);
}
-bool test_set_get_clear_bit(MY_BITMAP *map, uint bitsize)
+my_bool test_set_get_clear_bit(MY_BITMAP *map, uint bitsize)
{
uint i, test_bit;
uint no_loops= bitsize > 128 ? 128 : bitsize;
@@ -786,7 +789,7 @@
return TRUE;
}
-bool test_flip_bit(MY_BITMAP *map, uint bitsize)
+my_bool test_flip_bit(MY_BITMAP *map, uint bitsize)
{
uint i, test_bit;
uint no_loops= bitsize > 128 ? 128 : bitsize;
@@ -809,13 +812,13 @@
return TRUE;
}
-bool test_operators(MY_BITMAP *map __attribute__((unused)),
+my_bool test_operators(MY_BITMAP *map __attribute__((unused)),
uint bitsize __attribute__((unused)))
{
return FALSE;
}
-bool test_get_all_bits(MY_BITMAP *map, uint bitsize)
+my_bool test_get_all_bits(MY_BITMAP *map, uint bitsize)
{
uint i;
bitmap_set_all(map);
@@ -857,7 +860,7 @@
return TRUE;
}
-bool test_compare_operators(MY_BITMAP *map, uint bitsize)
+my_bool test_compare_operators(MY_BITMAP *map, uint bitsize)
{
uint i, j, test_bit1, test_bit2, test_bit3,test_bit4;
uint no_loops= bitsize > 128 ? 128 : bitsize;
@@ -963,7 +966,7 @@
return TRUE;
}
-bool test_count_bits_set(MY_BITMAP *map, uint bitsize)
+my_bool test_count_bits_set(MY_BITMAP *map, uint bitsize)
{
uint i, bit_count=0, test_bit;
uint no_loops= bitsize > 128 ? 128 : bitsize;
@@ -989,7 +992,7 @@
return TRUE;
}
-bool test_get_first_bit(MY_BITMAP *map, uint bitsize)
+my_bool test_get_first_bit(MY_BITMAP *map, uint bitsize)
{
uint i, test_bit;
uint no_loops= bitsize > 128 ? 128 : bitsize;
@@ -1014,7 +1017,7 @@
return TRUE;
}
-bool test_get_next_bit(MY_BITMAP *map, uint bitsize)
+my_bool test_get_next_bit(MY_BITMAP *map, uint bitsize)
{
uint i, j, test_bit;
uint no_loops= bitsize > 128 ? 128 : bitsize;
@@ -1033,7 +1036,7 @@
return TRUE;
}
-bool test_prefix(MY_BITMAP *map, uint bitsize)
+my_bool test_prefix(MY_BITMAP *map, uint bitsize)
{
uint i, j, test_bit;
uint no_loops= bitsize > 128 ? 128 : bitsize;
@@ -1068,7 +1071,7 @@
}
-bool do_test(uint bitsize)
+my_bool do_test(uint bitsize)
{
MY_BITMAP map;
my_bitmap_map buf[1024];
--- 5.1.34/mysys/my_thr_init.c 2009-06-03 23:17:32.000000000 +0200
+++ 7.0/mysys/my_thr_init.c 2009-06-04 10:35:49.000000000 +0200
@@ -23,11 +26,7 @@
#include <signal.h>
#ifdef THREAD
-#ifdef USE_TLS
pthread_key(struct st_my_thread_var*, THR_KEY_mysys);
-#else
-pthread_key(struct st_my_thread_var, THR_KEY_mysys);
-#endif /* USE_TLS */
pthread_mutex_t THR_LOCK_malloc,THR_LOCK_open,
THR_LOCK_lock,THR_LOCK_isam,THR_LOCK_myisam,THR_LOCK_heap,
THR_LOCK_net, THR_LOCK_charset, THR_LOCK_threads, THR_LOCK_time;
@@ -258,7 +257,6 @@
(ulong) pthread_self());
#endif
-#if !defined(__WIN__) || defined(USE_TLS)
if (my_pthread_getspecific(struct st_my_thread_var *,THR_KEY_mysys))
{
#ifdef EXTRA_DEBUG_THREADS
@@ -273,20 +271,7 @@
goto end;
}
pthread_setspecific(THR_KEY_mysys,tmp);
-
-#else /* defined(__WIN__) && !(defined(USE_TLS) */
- /*
- Skip initialization if the thread specific variable is already initialized
- */
- if (THR_KEY_mysys.id)
- goto end;
- tmp= &THR_KEY_mysys;
-#endif
-#if defined(__WIN__) && defined(EMBEDDED_LIBRARY)
- tmp->pthread_self= (pthread_t) getpid();
-#else
tmp->pthread_self= pthread_self();
-#endif
pthread_mutex_init(&tmp->mutex,MY_MUTEX_INIT_FAST);
pthread_cond_init(&tmp->suspend, NULL);
tmp->init= 1;
@@ -342,11 +327,7 @@
pthread_cond_destroy(&tmp->suspend);
#endif
pthread_mutex_destroy(&tmp->mutex);
-#if !defined(__WIN__) || defined(USE_TLS)
free(tmp);
-#else
- tmp->init= 0;
-#endif
/*
Decrement counter for number of running threads. We are using this
@@ -361,9 +342,7 @@
pthread_mutex_unlock(&THR_LOCK_threads);
}
/* The following free has to be done, even if my_thread_var() is 0 */
-#if !defined(__WIN__) || defined(USE_TLS)
pthread_setspecific(THR_KEY_mysys,0);
-#endif
}
struct st_my_thread_var *_my_thread_var(void)
--- 5.1.34/mysys/my_winthread.c 2009-06-03 23:17:32.000000000 +0200
+++ 7.0/mysys/my_winthread.c 2009-06-04 10:35:49.000000000 +0200
@@ -47,8 +50,7 @@
@retval 0 Mutex was acquired
@retval EBUSY Mutex was already locked by a thread
*/
-int
-win_pthread_mutex_trylock(pthread_mutex_t *mutex)
+int pthread_mutex_trylock(pthread_mutex_t *mutex)
{
if (TryEnterCriticalSection(mutex))
{
@@ -73,20 +75,37 @@
** in the new thread.
*/
-pthread_handler_t pthread_start(void *param)
+pthread_handler_t pstart(void *param);
+
+pthread_key_t detached;
+
+unsigned int __stdcall joinable_pstart(void*p)
+{
+ pthread_setspecific(detached,0);
+
+ return (unsigned int)pstart(p);
+}
+
+void __cdecl detached_pstart(void*p)
+{
+ pthread_setspecific(detached,(void*)1);
+
+ pstart(p);
+}
+
+pthread_handler_t pstart(void *param)
{
pthread_handler func=((struct pthread_map *) param)->func;
void *func_param=((struct pthread_map *) param)->param;
my_thread_init(); /* Will always succeed in windows */
pthread_mutex_lock(&THR_LOCK_thread); /* Wait for beginthread to return */
- win_pthread_self=((struct pthread_map *) param)->pthreadself;
+ my_thread_var->pthread_self=((struct pthread_map *) param)->pthreadself;
pthread_mutex_unlock(&THR_LOCK_thread);
free((char*) param); /* Free param from create */
pthread_exit((void*) (*func)(func_param));
return 0; /* Safety */
}
-
int pthread_create(pthread_t *thread_id, pthread_attr_t *attr,
pthread_handler func, void *param)
{
@@ -99,15 +118,19 @@
map->func=func;
map->param=param;
pthread_mutex_lock(&THR_LOCK_thread);
-#ifdef __BORLANDC__
- hThread=(HANDLE)_beginthread((void(_USERENTRY *)(void *)) pthread_start,
- attr->dwStackSize ? attr->dwStackSize :
- 65535, (void*) map);
+#ifdef __BORLANDC__
+#define BC_CAST (void(_USERENTRY *)(void *))
#else
- hThread=(HANDLE)_beginthread((void( __cdecl *)(void *)) pthread_start,
- attr->dwStackSize ? attr->dwStackSize :
- 65535, (void*) map);
+#define BC_CAST
#endif
+ {
+ unsigned ss=attr->dwStackSize ? attr->dwStackSize : 65535;
+ pthread_key_create(&detached,0);
+ if (attr->detached)
+ hThread=(HANDLE)_beginthread(BC_CAST detached_pstart,ss,(void*)map);
+ else
+ hThread=(HANDLE)_beginthreadex(NULL,ss,joinable_pstart,(void*)map,0,0);
+ }
DBUG_PRINT("info", ("hThread=%lu",(long) hThread));
*thread_id=map->pthreadself=hThread;
pthread_mutex_unlock(&THR_LOCK_thread);
@@ -126,15 +149,31 @@
void pthread_exit(void *a)
{
- _endthread();
+ if(pthread_getspecific(detached))
+ _endthread();
+ else
+ _endthreadex((unsigned)a);
}
-/* This is neaded to get the macro pthread_setspecific to work */
-
-int win_pthread_setspecific(void *a,void *b,uint length)
+int pthread_join(pthread_t thread, void **value_ptr)
{
- memcpy(a,b,length);
- return 0;
+ DWORD dw=0,
+ wfso=WaitForSingleObject(thread, INFINITE);
+ if(wfso == WAIT_OBJECT_0)
+ {
+ if(!GetExitCodeThread(thread, &dw))
+ {
+ DWORD e=GetLastError();
+ return -2;
+ }
+ else
+ {
+ if(value_ptr)*value_ptr=(void*)dw;
+ CloseHandle(thread);
+ return 0;
+ }
+ }
+ return -1;
}
#endif
--- 5.1.34/mysys/queues.c 2009-06-03 23:17:32.000000000 +0200
+++ 7.0/mysys/queues.c 2009-06-04 10:35:49.000000000 +0200
@@ -384,11 +387,11 @@
static uint tot_no_loops= 0;
static uint expected_part= 0;
static uint expected_num= 0;
-static bool max_ind= 0;
-static bool fix_used= 0;
+static my_bool max_ind= 0;
+static my_bool fix_used= 0;
static ulonglong start_time= 0;
-static bool is_divisible_by(uint num, uint divisor)
+static my_bool is_divisible_by(uint num, uint divisor)
{
uint quotient= num / divisor;
if (quotient * divisor == num)
@@ -495,7 +498,7 @@
return 0;
}
-bool check_num(uint num_part)
+my_bool check_num(uint num_part)
{
uint part= num_part >> 22;
uint num= num_part & 0x3FFFFF;
@@ -546,7 +549,7 @@
}
}
-bool perform_ins_del(QUEUE *queue, bool max_ind)
+my_bool perform_ins_del(QUEUE *queue, my_bool max_ind)
{
uint i= 0, no_loops= tot_no_loops, j= tot_no_parts;
do
@@ -574,10 +577,10 @@
return FALSE;
}
-bool do_test(uint no_parts, uint l_max_ind, bool l_fix_used)
+my_bool do_test(uint no_parts, uint l_max_ind, my_bool l_fix_used)
{
QUEUE queue;
- bool result;
+ my_bool result;
max_ind= l_max_ind;
fix_used= l_fix_used;
init_queue(&queue, no_parts, 0, max_ind, test_compare, NULL);
--- 5.1.34/include/config-win.h 2009-06-03 23:17:27.000000000 +0200
+++ 7.0/include/config-win.h 2009-06-04 10:35:22.000000000 +0200
@@ -33,6 +31,8 @@
#include <sys/locking.h>
#include <winsock2.h>
+#include <ws2tcpip.h>
+#include <math.h> /* Because of rint() */
#include <fcntl.h>
#include <io.h>
#include <malloc.h>
@@ -92,6 +92,12 @@
#define S_IROTH S_IREAD /* for my_lib */
+/* Winsock2 constant (Vista SDK and later)*/
+#define IPPROTO_IPV6 41
+#ifndef IPV6_V6ONLY
+#define IPV6_V6ONLY 27
+#endif
+
#ifdef __BORLANDC__
#define FILE_BINARY O_BINARY /* my_fopen in binary mode */
#define O_TEMPORARY 0
@@ -155,8 +161,14 @@
typedef uint rf_SetTimer;
#endif
+#define ssize_t SSIZE_T
+
#define Socket_defined
-#define my_socket SOCKET
+#ifndef __cplusplus
+#define bool BOOL
+#define true ((BOOL)1)
+#define false ((BOOL)0)
+#endif
#define SIGPIPE SIGINT
#define RETQSORTTYPE void
#define QSORT_TYPE_IS_VOID
@@ -280,6 +292,7 @@
#define HAVE_ALLOCA
#define HAVE_STRPBRK
#define HAVE_STRSTR
+#define HAVE_STRDUP
#define HAVE_COMPRESS
#define HAVE_CREATESEMAPHORE
#define HAVE_ISNAN
@@ -307,12 +320,23 @@
#define _snprintf snprintf
#endif
+#if _MSC_VER >= 1500 /* VS9 (2008) has vsnprintf */
+#ifndef HAVE_VSNPRINTF
+#define HAVE_VSNPRINTF
+#endif
+#endif
+#ifndef HAVE_STRTOUL
+#define HAVE_STRTOUL
+#endif
+
#ifdef _MSC_VER
#define HAVE_LDIV /* The optimizer breaks in zortech for ldiv */
#define HAVE_ANSI_INCLUDE
#define HAVE_SYS_UTIME_H
+#ifndef HAVE_STRTOUL
#define HAVE_STRTOUL
#endif
+#endif
#define my_reinterpret_cast(A) reinterpret_cast <A>
#define my_const_cast(A) const_cast<A>
@@ -417,3 +441,13 @@
#define HAVE_UCA_COLLATIONS 1
#define HAVE_BOOL 1
+
+/* Windows doesn't define ENOTSUP, define it as the same as Solaris */
+#ifndef ENOTSUP
+#define ENOTSUP 48
+#endif
+
+#if _MSC_VER >= 1400 /* strtok_s is like strtok_r, but is new */
+#define HAVE_STRTOK_R
+#define strtok_r(A, B, C) strtok_s((A), (B), (C))
+#endif
--- 5.1.34/include/m_string.h 2009-06-03 23:17:27.000000000 +0200
+++ 7.0/include/m_string.h 2009-06-04 10:35:22.000000000 +0200
@@ -215,6 +218,7 @@
long *val);
longlong my_strtoll10(const char *nptr, char **endptr, int *error);
#if SIZEOF_LONG == SIZEOF_LONG_LONG
+#define ll2str(A,B,C,D) int2str((A),(B),(C),(D))
#define longlong2str(A,B,C) int2str((A),(B),(C),1)
#define longlong10_to_str(A,B,C) int10_to_str((A),(B),(C))
#undef strtoll
@@ -228,7 +232,8 @@
#endif
#else
#ifdef HAVE_LONG_LONG
-extern char *longlong2str(longlong val,char *dst,int radix);
+extern char *ll2str(longlong val,char *dst,int radix, int upcase);
+#define longlong2str(A,B,C) ll2str((A),(B),(C),1)
extern char *longlong10_to_str(longlong val,char *dst,int radix);
#if (!defined(HAVE_STRTOULL) || defined(NO_STRTOLL_PROTO))
extern longlong strtoll(const char *str, char **ptr, int base);
--- 5.1.34/include/my_base.h 2009-06-03 23:17:27.000000000 +0200
+++ 7.0/include/my_base.h 2009-06-04 10:35:22.000000000 +0200
@@ -98,6 +101,14 @@
HA_KEY_ALG_FULLTEXT= 4 /* FULLTEXT (MyISAM tables) */
};
+ /* Index and table build methods */
+
+enum ha_build_method {
+ HA_BUILD_DEFAULT,
+ HA_BUILD_ONLINE,
+ HA_BUILD_OFFLINE
+};
+
/* Storage media types */
enum ha_storage_media {
@@ -363,7 +374,11 @@
update handler::auto_increment_value
*/
#define HA_STATUS_AUTO 64
-
+/*
+ update the number of rows updated and deleted since last reset call.
+ handler::rows_updated, rows_deleted
+*/
+#define HA_STATUS_WRITTEN_ROWS 128
/*
Errorcodes given by handler functions
@@ -521,6 +536,8 @@
#define NULL_RANGE 64
#define GEOM_FLAG 128
#define SKIP_RANGE 256
+#define READ_KEY_FROM_RANGE 512
+#define EMPTY_RANGE 1024
typedef struct st_key_range
{
--- 5.1.34/include/my_global.h 2009-06-03 23:17:47.000000000 +0200
+++ 7.0/include/my_global.h 2009-06-04 10:35:22.000000000 +0200
@@ -156,9 +159,17 @@
#define __builtin_expect(x, expected_value) (x)
#endif
+#if defined(NDEBUG)
#define likely(x) __builtin_expect((x),1)
#define unlikely(x) __builtin_expect((x),0)
-
+#else
+/*
+ No branch hinting in DEBUG as this enables warning in case
+ of malformed predicates: ie. use of '=' instead of '=='
+*/
+#define likely(x) x
+#define unlikely(x) x
+#endif
/*
The macros below are useful in optimising places where it has been
@@ -678,9 +689,9 @@
/* Some types that is different between systems */
typedef int File; /* File descriptor */
+#include <my_socket.h>
#ifndef Socket_defined
-typedef int my_socket; /* File descriptor for sockets */
-#define INVALID_SOCKET -1
+#define INVALID_SOCKET MY_INVALID_SOCKET
#endif
/* Type for fuctions that handles signals */
#define sig_handler RETSIGTYPE
@@ -816,7 +827,7 @@
#undef remove /* Crashes MySQL on SCO 5.0.0 */
#ifndef __WIN__
-#define closesocket(A) close(A)
+#define closesocket(A) my_socket_close(A)
#ifndef ulonglong2double
#define ulonglong2double(A) ((double) (ulonglong) (A))
#define my_off_t2double(A) ((double) (my_off_t) (A))
@@ -1082,22 +1093,24 @@
#endif
#if defined(__WIN__)
-#define socket_errno WSAGetLastError()
+#define socket_errno my_socket_errno()
#define SOCKET_EINTR WSAEINTR
#define SOCKET_EAGAIN WSAEINPROGRESS
#define SOCKET_ETIMEDOUT WSAETIMEDOUT
#define SOCKET_EWOULDBLOCK WSAEWOULDBLOCK
#define SOCKET_EADDRINUSE WSAEADDRINUSE
+#define SOCKET_ECONNREFUSED WSAECONNREFUSED
#define SOCKET_ENFILE ENFILE
#define SOCKET_EMFILE EMFILE
#else /* Unix */
-#define socket_errno errno
-#define closesocket(A) close(A)
+#define socket_errno my_socket_errno()
+#define closesocket(A) my_socket_close(A)
#define SOCKET_EINTR EINTR
#define SOCKET_EAGAIN EAGAIN
#define SOCKET_ETIMEDOUT SOCKET_EINTR
#define SOCKET_EWOULDBLOCK EWOULDBLOCK
#define SOCKET_EADDRINUSE EADDRINUSE
+#define SOCKET_ECONNREFUSED ECONNREFUSED
#define SOCKET_ENFILE ENFILE
#define SOCKET_EMFILE EMFILE
#endif
--- 5.1.34/include/my_pthread.h 2009-06-03 23:17:27.000000000 +0200
+++ 7.0/include/my_pthread.h 2009-06-04 10:35:22.000000000 +0200
@@ -36,6 +39,7 @@
DWORD dwStackSize ;
DWORD dwCreatingFlag ;
int priority ;
+ BOOL detached;
} pthread_attr_t ;
typedef struct { int dummy; } pthread_condattr_t;
@@ -100,8 +104,6 @@
}
void win_pthread_init(void);
-int win_pthread_setspecific(void *A,void *B,uint length);
-int win_pthread_mutex_trylock(pthread_mutex_t *mutex);
int pthread_create(pthread_t *,pthread_attr_t *,pthread_handler,void *);
int pthread_cond_init(pthread_cond_t *cond, const pthread_condattr_t *attr);
int pthread_cond_wait(pthread_cond_t *cond, pthread_mutex_t *mutex);
@@ -113,7 +115,12 @@
int pthread_attr_init(pthread_attr_t *connect_att);
int pthread_attr_setstacksize(pthread_attr_t *connect_att,DWORD stack);
int pthread_attr_setprio(pthread_attr_t *connect_att,int priority);
+#define PTHREAD_CREATE_JOINABLE 1
+#define PTHREAD_CREATE_DETACHED 2
+int pthread_attr_setdetachstate(pthread_attr_t *connect_att,int state);
+int pthread_attr_getdetachstate(pthread_attr_t *connect_att,int*state);
int pthread_attr_destroy(pthread_attr_t *connect_att);
+int pthread_join(pthread_t thread, void **value_ptr);
struct tm *localtime_r(const time_t *timep,struct tm *tmp);
struct tm *gmtime_r(const time_t *timep,struct tm *tmp);
@@ -126,47 +133,79 @@
#define _REENTRANT 1
#define HAVE_PTHREAD_ATTR_SETSTACKSIZE 1
-/*
- Windows has two ways to use thread local storage. The most efficient
- is using __declspec(thread), but that does not work properly when
- used in a .dll that is loaded at runtime, after program load. So for
- libmysql.dll and libmysqld.dll we define USE_TLS in order to use the
- TlsXxx() API instead, which works in all cases.
-*/
-#ifdef USE_TLS /* For LIBMYSQL.DLL */
+
#undef SAFE_MUTEX /* This will cause conflicts */
+typedef DWORD pthread_key_t;
#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))
-#define my_pthread_setspecific_ptr(T,V) (!TlsSetValue((T),(V)))
-#define pthread_setspecific(A,B) (!TlsSetValue((A),(B)))
-#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)
-#define my_pthread_setspecific_ptr(T,V) ((T)=(V),0)
-#define pthread_setspecific(A,B) win_pthread_setspecific(&(A),(B),sizeof(A))
-#endif /* USE_TLS */
-#define pthread_equal(A,B) ((A) == (B))
-#define pthread_mutex_init(A,B) (InitializeCriticalSection(A),0)
-#define pthread_mutex_lock(A) (EnterCriticalSection(A),0)
-#define pthread_mutex_trylock(A) win_pthread_mutex_trylock((A))
-#define pthread_mutex_unlock(A) LeaveCriticalSection(A)
-#define pthread_mutex_destroy(A) DeleteCriticalSection(A)
+static inline int pthread_key_create(pthread_key_t *key, void (*destr_function)(void*))
+{
+ *key= TlsAlloc();
+ if(*key == TLS_OUT_OF_INDEXES)
+ return EAGAIN;
+ return 0;
+}
+
+static inline int pthread_key_delete(pthread_key_t key)
+{
+ if(TlsFree(key))
+ return 0;
+ return 1;
+}
+
+#define my_pthread_setspecific_ptr(T,V) pthread_setspecific(T,V)
+
+static inline int pthread_setspecific(pthread_key_t key, const void *pointer)
+{
+ if(TlsSetValue(key, (void*)pointer))
+ return 0;
+ return 1;
+}
+
+static inline void* pthread_getspecific(pthread_key_t key)
+{
+ return TlsGetValue(key);
+}
+
+#define my_pthread_getspecific(T,A) ((T) pthread_getspecific(A))
+#define my_pthread_getspecific_ptr(T,V) ((T) pthread_getspecific(V))
+
+static inline int pthread_equal(pthread_t thread1, pthread_t thread2)
+{
+ return thread1 == thread2;
+}
+
+typedef void pthread_mutex_attr_t;
+static inline int pthread_mutex_init(pthread_mutex_t *mutex, const pthread_mutex_attr_t *mutex_attr)
+{
+ InitializeCriticalSection(mutex);
+ return 0;
+}
+
+static inline int pthread_mutex_lock(pthread_mutex_t *mutex)
+{
+ EnterCriticalSection(mutex);
+ return 0;
+}
+
+int pthread_mutex_trylock(pthread_mutex_t *mutex);
+
+static inline int pthread_mutex_unlock(pthread_mutex_t *mutex)
+{
+ LeaveCriticalSection(mutex);
+ return 0;
+}
+
+static inline int pthread_mutex_destroy(pthread_mutex_t *mutex)
+{
+ DeleteCriticalSection(mutex);
+ return 0;
+}
+
#define my_pthread_setprio(A,B) SetThreadPriority(GetCurrentThread(), (B))
#define pthread_kill(A,B) pthread_dummy((A) ? 0 : ESRCH)
-#define pthread_join(A,B) (WaitForSingleObject((A), INFINITE) != WAIT_OBJECT_0)
-
/* Dummy defines for easier code */
-#define pthread_attr_setdetachstate(A,B) pthread_dummy(0)
#define my_pthread_attr_setprio(A,B) pthread_attr_setprio(A,B)
#define pthread_attr_setscope(A,B)
#define pthread_detach_this_thread()
--- 5.1.34/include/mysql.h 2009-06-03 23:17:27.000000000 +0200
+++ 7.0/include/mysql.h 2009-06-04 10:35:22.000000000 +0200
@@ -58,13 +61,6 @@
#define STDCALL __stdcall
#endif
-#ifndef my_socket_defined
-#ifdef __WIN__
-#define my_socket SOCKET
-#else
-typedef int my_socket;
-#endif /* __WIN__ */
-#endif /* my_socket_defined */
#endif /* _global_h */
#include "mysql_version.h"
@@ -166,7 +162,7 @@
MYSQL_OPT_WRITE_TIMEOUT, MYSQL_OPT_USE_RESULT,
MYSQL_OPT_USE_REMOTE_CONNECTION, MYSQL_OPT_USE_EMBEDDED_CONNECTION,
MYSQL_OPT_GUESS_CONNECTION, MYSQL_SET_CLIENT_IP, MYSQL_SECURE_AUTH,
- MYSQL_REPORT_DATA_TRUNCATION, MYSQL_OPT_RECONNECT,
+ MYSQL_REPORT_DATA_TRUNCATION, MYSQL_OPT_RECONNECT, MYSQL_OPT_BIND,
MYSQL_OPT_SSL_VERIFY_SERVER_CERT
};
@@ -206,6 +202,8 @@
#endif
enum mysql_option methods_to_use;
char *client_ip;
+ char *bind_name;
+
/* Refuse client connecting to server if it uses old (pre-4.1.1) protocol */
my_bool secure_auth;
/* 0 - never report, 1 - always report (default) */
--- 5.1.34/include/mysql.h.pp 2009-06-03 23:17:27.000000000 +0200
+++ 7.0/include/mysql.h.pp 2009-06-04 10:35:22.000000000 +0200
@@ -1,6 +1,5 @@
#include <sys/types.h>
typedef char my_bool;
-typedef int my_socket;
#include "mysql_version.h"
#include "mysql_com.h"
enum enum_server_command
@@ -19,7 +18,7 @@
typedef struct st_net {
Vio *vio;
unsigned char *buff,*buff_end,*write_pos,*read_pos;
- my_socket fd;
+ int fd;
unsigned long remain_in_buf,length, buf_length, where_b;
unsigned long max_packet,max_packet_size;
unsigned int pkt_nr,compress_pkt_nr;
@@ -42,24 +41,25 @@
void *extension;
} NET;
enum enum_field_types { MYSQL_TYPE_DECIMAL, MYSQL_TYPE_TINY,
- MYSQL_TYPE_SHORT, MYSQL_TYPE_LONG,
- MYSQL_TYPE_FLOAT, MYSQL_TYPE_DOUBLE,
- MYSQL_TYPE_NULL, MYSQL_TYPE_TIMESTAMP,
- MYSQL_TYPE_LONGLONG,MYSQL_TYPE_INT24,
- MYSQL_TYPE_DATE, MYSQL_TYPE_TIME,
- MYSQL_TYPE_DATETIME, MYSQL_TYPE_YEAR,
- MYSQL_TYPE_NEWDATE, MYSQL_TYPE_VARCHAR,
- MYSQL_TYPE_BIT,
+ MYSQL_TYPE_SHORT, MYSQL_TYPE_LONG,
+ MYSQL_TYPE_FLOAT, MYSQL_TYPE_DOUBLE,
+ MYSQL_TYPE_NULL, MYSQL_TYPE_TIMESTAMP,
+ MYSQL_TYPE_LONGLONG,MYSQL_TYPE_INT24,
+ MYSQL_TYPE_DATE, MYSQL_TYPE_TIME,
+ MYSQL_TYPE_DATETIME, MYSQL_TYPE_YEAR,
+ MYSQL_TYPE_NEWDATE, MYSQL_TYPE_VARCHAR,
+ MYSQL_TYPE_BIT,
MYSQL_TYPE_NEWDECIMAL=246,
- MYSQL_TYPE_ENUM=247,
- MYSQL_TYPE_SET=248,
- MYSQL_TYPE_TINY_BLOB=249,
- MYSQL_TYPE_MEDIUM_BLOB=250,
- MYSQL_TYPE_LONG_BLOB=251,
- MYSQL_TYPE_BLOB=252,
- MYSQL_TYPE_VAR_STRING=253,
- MYSQL_TYPE_STRING=254,
- MYSQL_TYPE_GEOMETRY=255
+ MYSQL_TYPE_ENUM=247,
+ MYSQL_TYPE_SET=248,
+ MYSQL_TYPE_TINY_BLOB=249,
+ MYSQL_TYPE_MEDIUM_BLOB=250,
+ MYSQL_TYPE_LONG_BLOB=251,
+ MYSQL_TYPE_BLOB=252,
+ MYSQL_TYPE_VAR_STRING=253,
+ MYSQL_TYPE_STRING=254,
+ MYSQL_TYPE_GEOMETRY=255,
+ MAX_NO_FIELD_TYPES
};
enum mysql_enum_shutdown_level {
SHUTDOWN_DEFAULT = 0,
@@ -96,14 +96,16 @@
int net_real_write(NET *net,const unsigned char *packet, size_t len);
unsigned long my_net_read(NET *net);
struct sockaddr;
-int my_connect(my_socket s, const struct sockaddr *name, unsigned int namelen,
+int my_connect(int s, const struct sockaddr *name, unsigned int namelen,
unsigned int timeout);
struct rand_struct {
unsigned long seed1,seed2,max_value;
double max_value_dbl;
};
enum Item_result {STRING_RESULT=0, REAL_RESULT, INT_RESULT, ROW_RESULT,
- DECIMAL_RESULT};
+ DECIMAL_RESULT,
+ MAX_NO_ITEM_RESULTS
+};
typedef struct st_udf_args
{
unsigned int arg_count;
@@ -258,7 +260,7 @@
MYSQL_OPT_WRITE_TIMEOUT, MYSQL_OPT_USE_RESULT,
MYSQL_OPT_USE_REMOTE_CONNECTION, MYSQL_OPT_USE_EMBEDDED_CONNECTION,
MYSQL_OPT_GUESS_CONNECTION, MYSQL_SET_CLIENT_IP, MYSQL_SECURE_AUTH,
- MYSQL_REPORT_DATA_TRUNCATION, MYSQL_OPT_RECONNECT,
+ MYSQL_REPORT_DATA_TRUNCATION, MYSQL_OPT_RECONNECT, MYSQL_OPT_BIND,
MYSQL_OPT_SSL_VERIFY_SERVER_CERT
};
struct st_mysql_options {
@@ -283,6 +285,7 @@
my_bool separate_thread;
enum mysql_option methods_to_use;
char *client_ip;
+ char *bind_name;
my_bool secure_auth;
my_bool report_data_truncation;
int (*local_infile_init)(void **, const char *, void *);
--- 5.1.34/include/mysql_com.h 2009-06-03 23:17:27.000000000 +0200
+++ 7.0/include/mysql_com.h 2009-06-04 10:35:22.000000000 +0200
@@ -104,6 +107,8 @@
#define FIELD_IN_PART_FUNC_FLAG (1 << 19)/* Field part of partition func */
#define FIELD_IN_ADD_INDEX (1<< 20) /* Intern: Field used in ADD INDEX */
#define FIELD_IS_RENAMED (1<< 21) /* Intern: Field is being renamed */
+#define FIELD_STORAGE_FLAGS 22 /* Storage type: bit 22, 23 and 24 */
+#define COLUMN_FORMAT_FLAGS 25 /* Column format: bit 25, 26 and 27 */
#define REFRESH_GRANT 1 /* Refresh grant tables */
#define REFRESH_LOG 2 /* Start on new log file */
@@ -240,7 +245,11 @@
#if !defined(CHECK_EMBEDDED_DIFFERENCES) || !defined(EMBEDDED_LIBRARY)
Vio *vio;
unsigned char *buff,*buff_end,*write_pos,*read_pos;
- my_socket fd; /* For Perl DBI/dbd */
+#ifdef __WIN__
+ SOCKET fd;
+#else
+ int fd; /* For Perl DBI/dbd */
+#endif
/*
The following variable is set if we are doing several queries in one
command ( as in LOAD TABLE ... FROM MASTER ),
@@ -283,25 +292,25 @@
#define packet_error (~(unsigned long) 0)
enum enum_field_types { MYSQL_TYPE_DECIMAL, MYSQL_TYPE_TINY,
- MYSQL_TYPE_SHORT, MYSQL_TYPE_LONG,
- MYSQL_TYPE_FLOAT, MYSQL_TYPE_DOUBLE,
- MYSQL_TYPE_NULL, MYSQL_TYPE_TIMESTAMP,
- MYSQL_TYPE_LONGLONG,MYSQL_TYPE_INT24,
- MYSQL_TYPE_DATE, MYSQL_TYPE_TIME,
- MYSQL_TYPE_DATETIME, MYSQL_TYPE_YEAR,
- MYSQL_TYPE_NEWDATE, MYSQL_TYPE_VARCHAR,
- MYSQL_TYPE_BIT,
+ MYSQL_TYPE_SHORT, MYSQL_TYPE_LONG,
+ MYSQL_TYPE_FLOAT, MYSQL_TYPE_DOUBLE,
+ MYSQL_TYPE_NULL, MYSQL_TYPE_TIMESTAMP,
+ MYSQL_TYPE_LONGLONG,MYSQL_TYPE_INT24,
+ MYSQL_TYPE_DATE, MYSQL_TYPE_TIME,
+ MYSQL_TYPE_DATETIME, MYSQL_TYPE_YEAR,
+ MYSQL_TYPE_NEWDATE, MYSQL_TYPE_VARCHAR,
+ MYSQL_TYPE_BIT,
MYSQL_TYPE_NEWDECIMAL=246,
- MYSQL_TYPE_ENUM=247,
- MYSQL_TYPE_SET=248,
- MYSQL_TYPE_TINY_BLOB=249,
- MYSQL_TYPE_MEDIUM_BLOB=250,
- MYSQL_TYPE_LONG_BLOB=251,
- MYSQL_TYPE_BLOB=252,
- MYSQL_TYPE_VAR_STRING=253,
- MYSQL_TYPE_STRING=254,
- MYSQL_TYPE_GEOMETRY=255
-
+ MYSQL_TYPE_ENUM=247,
+ MYSQL_TYPE_SET=248,
+ MYSQL_TYPE_TINY_BLOB=249,
+ MYSQL_TYPE_MEDIUM_BLOB=250,
+ MYSQL_TYPE_LONG_BLOB=251,
+ MYSQL_TYPE_BLOB=252,
+ MYSQL_TYPE_VAR_STRING=253,
+ MYSQL_TYPE_STRING=254,
+ MYSQL_TYPE_GEOMETRY=255,
+ MAX_NO_FIELD_TYPES /* Should always be last */
};
/* For backward compatibility */
@@ -414,8 +423,13 @@
Currently it's used internally by manager.c
*/
struct sockaddr;
-int my_connect(my_socket s, const struct sockaddr *name, unsigned int namelen,
+#ifdef __WIN__
+int my_connect(SOCKET s, const struct sockaddr *name, unsigned int namelen,
unsigned int timeout);
+#else
+int my_connect(int s, const struct sockaddr *name, unsigned int namelen,
+ unsigned int timeout);
+#endif
struct rand_struct {
unsigned long seed1,seed2,max_value;
@@ -429,7 +443,9 @@
/* The following is for user defined functions */
enum Item_result {STRING_RESULT=0, REAL_RESULT, INT_RESULT, ROW_RESULT,
- DECIMAL_RESULT};
+ DECIMAL_RESULT,
+ MAX_NO_ITEM_RESULTS /* Should always be last */
+};
typedef struct st_udf_args
{
--- 5.1.34/include/violite.h 2009-06-03 23:17:27.000000000 +0200
+++ 7.0/include/violite.h 2009-06-04 10:35:22.000000000 +0200
@@ -84,9 +87,7 @@
/* Get socket number */
my_socket vio_fd(Vio*vio);
/* Remote peer's address and name in text form */
-my_bool vio_peer_addr(Vio* vio, char *buf, uint16 *port);
-/* Remotes in_addr */
-void vio_in_addr(Vio *vio, struct in_addr *in);
+my_bool vio_peer_addr(Vio* vio, char *buf, uint16 *port, size_t buflen);
my_bool vio_poll_read(Vio *vio,uint timeout);
#ifdef HAVE_OPENSSL
@@ -103,9 +104,6 @@
#ifndef YASSL_PREFIX
#define YASSL_PREFIX
#endif
-/* Set yaSSL to use same type as MySQL do for socket handles */
-typedef my_socket YASSL_SOCKET_T;
-#define YASSL_SOCKET_T_DEFINED
#include <openssl/ssl.h>
#include <openssl/err.h>
@@ -153,8 +151,7 @@
#define vio_should_retry(vio) (vio)->should_retry(vio)
#define vio_was_interrupted(vio) (vio)->was_interrupted(vio)
#define vio_close(vio) ((vio)->vioclose)(vio)
-#define vio_peer_addr(vio, buf, prt) (vio)->peer_addr(vio, buf, prt)
-#define vio_in_addr(vio, in) (vio)->in_addr(vio, in)
+#define vio_peer_addr(vio, buf, prt, buflen) (vio)->peer_addr(vio, buf, prt, buflen)
#define vio_timeout(vio, which, seconds) (vio)->timeout(vio, which, seconds)
#endif /* !defined(DONT_MAP_VIO) */
@@ -177,8 +174,9 @@
HANDLE hPipe;
my_bool localhost; /* Are we from localhost? */
int fcntl_mode; /* Buffered fcntl(sd,F_GETFL) */
- struct sockaddr_in local; /* Local internet address */
- struct sockaddr_in remote; /* Remote internet address */
+ struct sockaddr_storage local; /* Local internet address */
+ struct sockaddr_storage remote; /* Remote internet address */
+ int addrLen; /* Length of remote address */
enum enum_vio_type type; /* Type of connection */
char desc[30]; /* String description */
char *read_buffer; /* buffer for vio_read_buff */
@@ -194,8 +192,8 @@
my_bool (*is_blocking)(Vio*);
int (*viokeepalive)(Vio*, my_bool);
int (*fastsend)(Vio*);
- my_bool (*peer_addr)(Vio*, char *, uint16*);
- void (*in_addr)(Vio*, struct in_addr*);
+ my_bool (*peer_addr)(Vio*, char *, uint16*, size_t);
+ void (*in_addr)(Vio*, struct sockaddr_storage*);
my_bool (*should_retry)(Vio*);
my_bool (*was_interrupted)(Vio*);
int (*vioclose)(Vio*);
--- 5.1.34/client/CMakeLists.txt 2009-06-03 23:17:27.000000000 +0200
+++ 7.0/client/CMakeLists.txt 2009-06-04 10:35:19.000000000 +0200
@@ -30,27 +27,27 @@
${CMAKE_SOURCE_DIR}/strings)
ADD_EXECUTABLE(mysql completion_hash.cc mysql.cc readline.cc sql_string.cc ../mysys/my_conio.c)
-TARGET_LINK_LIBRARIES(mysql mysqlclient_notls wsock32)
+TARGET_LINK_LIBRARIES(mysql mysqlclient wsock32)
ADD_EXECUTABLE(mysqltest mysqltest.cc)
SET_SOURCE_FILES_PROPERTIES(mysqltest.cc PROPERTIES COMPILE_FLAGS "-DTHREADS")
TARGET_LINK_LIBRARIES(mysqltest mysqlclient mysys regex wsock32 dbug)
ADD_EXECUTABLE(mysqlcheck mysqlcheck.c)
-TARGET_LINK_LIBRARIES(mysqlcheck mysqlclient_notls wsock32)
+TARGET_LINK_LIBRARIES(mysqlcheck mysqlclient wsock32)
ADD_EXECUTABLE(mysqldump mysqldump.c ../sql-common/my_user.c ../mysys/mf_getdate.c)
-TARGET_LINK_LIBRARIES(mysqldump mysqlclient_notls wsock32)
+TARGET_LINK_LIBRARIES(mysqldump mysqlclient wsock32)
ADD_EXECUTABLE(mysqlimport mysqlimport.c)
-TARGET_LINK_LIBRARIES(mysqlimport mysqlclient_notls wsock32)
+TARGET_LINK_LIBRARIES(mysqlimport mysqlclient wsock32)
ADD_EXECUTABLE(mysql_upgrade mysql_upgrade.c ../mysys/my_getpagesize.c)
-TARGET_LINK_LIBRARIES(mysql_upgrade mysqlclient_notls wsock32)
+TARGET_LINK_LIBRARIES(mysql_upgrade mysqlclient wsock32)
ADD_DEPENDENCIES(mysql_upgrade GenFixPrivs)
ADD_EXECUTABLE(mysqlshow mysqlshow.c)
-TARGET_LINK_LIBRARIES(mysqlshow mysqlclient_notls wsock32)
+TARGET_LINK_LIBRARIES(mysqlshow mysqlclient wsock32)
ADD_EXECUTABLE(mysqlbinlog mysqlbinlog.cc
../mysys/mf_tempdir.c
@@ -59,10 +56,10 @@
../mysys/my_bitmap.c
../mysys/my_vle.c
../mysys/base64.c)
-TARGET_LINK_LIBRARIES(mysqlbinlog mysqlclient_notls wsock32)
+TARGET_LINK_LIBRARIES(mysqlbinlog mysqlclient wsock32)
ADD_EXECUTABLE(mysqladmin mysqladmin.cc)
-TARGET_LINK_LIBRARIES(mysqladmin mysqlclient_notls wsock32)
+TARGET_LINK_LIBRARIES(mysqladmin mysqlclient wsock32)
ADD_EXECUTABLE(mysqlslap mysqlslap.c)
SET_SOURCE_FILES_PROPERTIES(mysqlslap.c PROPERTIES COMPILE_FLAGS "-DTHREADS")
--- 5.1.34/client/mysql.cc 2009-06-03 23:17:47.000000000 +0200
+++ 7.0/client/mysql.cc 2009-06-04 10:35:19.000000000 +0200
@@ -151,6 +154,7 @@
static uint verbose=0,opt_silent=0,opt_mysql_port=0, opt_local_infile=0;
static uint my_end_arg;
static char * opt_mysql_unix_port=0;
+static char *opt_bind_addr = NULL;
static int connect_flag=CLIENT_INTERACTIVE;
static char *current_host,*current_db,*current_user=0,*opt_password=0,
*current_prompt=0, *delimiter_str= 0,
@@ -1324,6 +1328,9 @@
0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
{"batch", 'B',
"Don't use history file. Disable interactive behavior. (Enables --silent)", 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
+ {"bind-address", OPT_BIND_ADDRESS, "IP address to bind to.",
+ (uchar**) &opt_bind_addr, (uchar**) &opt_bind_addr, 0, GET_STR,
+ REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
{"character-sets-dir", OPT_CHARSETS_DIR,
"Directory where character sets are.", (uchar**) &charsets_dir,
(uchar**) &charsets_dir, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
@@ -4148,6 +4155,10 @@
mysql_options(&mysql,MYSQL_OPT_CONNECT_TIMEOUT,
(char*) &timeout);
}
+ if (opt_bind_addr)
+ {
+ mysql_options(&mysql, MYSQL_OPT_BIND, opt_bind_addr);
+ }
if (opt_compress)
mysql_options(&mysql,MYSQL_OPT_COMPRESS,NullS);
if (opt_secure_auth)
--- 5.1.34/client/mysqladmin.cc 2009-06-03 23:17:47.000000000 +0200
+++ 7.0/client/mysqladmin.cc 2009-06-04 10:35:19.000000000 +0200
@@ -40,6 +43,7 @@
static my_bool debug_info_flag= 0, debug_check_flag= 0;
static uint tcp_port = 0, option_wait = 0, option_silent=0, nr_iterations;
static uint opt_count_iterations= 0, my_end_arg;
+static char *opt_bind_addr = NULL;
static ulong opt_connect_timeout, opt_shutdown_timeout;
static char * unix_port=0;
@@ -119,6 +123,9 @@
{"autoclose", OPT_AUTO_CLOSE, "Auto close the screen on exit for Netware.",
0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
#endif
+ {"bind-address", OPT_BIND_ADDRESS, "IP address to bind to.",
+ (uchar**) &opt_bind_addr, (uchar**) &opt_bind_addr, 0, GET_STR,
+ REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
{"count", 'c',
"Number of iterations to make. This works with -i (--sleep) only.",
(uchar**) &nr_iterations, (uchar**) &nr_iterations, 0, GET_UINT,
@@ -325,6 +332,10 @@
VOID(signal(SIGINT,endprog)); /* Here if abort */
VOID(signal(SIGTERM,endprog)); /* Here if abort */
+ if (opt_bind_addr)
+ {
+ mysql_options(&mysql,MYSQL_OPT_BIND,opt_bind_addr);
+ }
if (opt_compress)
mysql_options(&mysql,MYSQL_OPT_COMPRESS,NullS);
if (opt_connect_timeout)
--- 5.1.34/client/mysqlbinlog.cc 2009-06-03 23:17:47.000000000 +0200
+++ 7.0/client/mysqlbinlog.cc 2009-06-04 10:35:19.000000000 +0200
@@ -82,6 +85,7 @@
static const char* sock= 0;
static const char* user = 0;
static char* pass = 0;
+static char *opt_bind_addr = NULL;
static char *charset= 0;
static uint verbose= 0;
@@ -944,6 +948,9 @@
,(uchar**) &opt_base64_output_mode_str,
(uchar**) &opt_base64_output_mode_str,
0, GET_STR, OPT_ARG, 0, 0, 0, 0, 0, 0},
+ {"bind-address", OPT_BIND_ADDRESS, "IP address to bind to.",
+ (uchar**) &opt_bind_addr, (uchar**) &opt_bind_addr, 0, GET_STR,
+ REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
/*
mysqlbinlog needs charsets knowledge, to be able to convert a charset
number found in binlog to a charset name (to be able to print things
@@ -1319,6 +1326,10 @@
if (opt_protocol)
mysql_options(mysql, MYSQL_OPT_PROTOCOL, (char*) &opt_protocol);
+ if (opt_bind_addr)
+ {
+ mysql_options(mysql, MYSQL_OPT_BIND, opt_bind_addr);
+ }
if (!mysql_real_connect(mysql, host, user, pass, 0, port, sock, 0))
{
error("Failed on connect: %s", mysql_error(mysql));
--- 5.1.34/client/mysqlcheck.c 2009-06-03 23:17:47.000000000 +0200
+++ 7.0/client/mysqlcheck.c 2009-06-04 10:35:19.000000000 +0200
@@ -47,6 +50,7 @@
static char *shared_memory_base_name=0;
#endif
static uint opt_protocol=0;
+static char *opt_bind_addr = NULL;
enum operations { DO_CHECK, DO_REPAIR, DO_ANALYZE, DO_OPTIMIZE, DO_UPGRADE };
@@ -70,6 +74,9 @@
"If a checked table is corrupted, automatically fix it. Repairing will be done after all tables have been checked, if corrupted ones were found.",
(uchar**) &opt_auto_repair, (uchar**) &opt_auto_repair, 0, GET_BOOL, NO_ARG, 0,
0, 0, 0, 0, 0},
+ {"bind-address", OPT_BIND_ADDRESS, "IP address to bind to.",
+ (uchar**) &opt_bind_addr, (uchar**) &opt_bind_addr, 0, GET_STR,
+ REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
{"character-sets-dir", OPT_CHARSETS_DIR,
"Directory where character sets are.", (uchar**) &charsets_dir,
(uchar**) &charsets_dir, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
@@ -781,6 +788,10 @@
#endif
if (opt_protocol)
mysql_options(&mysql_connection,MYSQL_OPT_PROTOCOL,(char*)&opt_protocol);
+ if (opt_bind_addr)
+ {
+ mysql_options(&mysql_connection,MYSQL_OPT_BIND,opt_bind_addr);
+ }
#ifdef HAVE_SMEM
if (shared_memory_base_name)
mysql_options(&mysql_connection,MYSQL_SHARED_MEMORY_BASE_NAME,shared_memory_base_name);
--- 5.1.34/client/mysqldump.c 2009-06-03 23:17:47.000000000 +0200
+++ 7.0/client/mysqldump.c 2009-06-04 10:35:19.000000000 +0200
@@ -119,6 +122,7 @@
#define MYSQL_OPT_MASTER_DATA_EFFECTIVE_SQL 1
#define MYSQL_OPT_MASTER_DATA_COMMENTED_SQL 2
static uint opt_mysql_port= 0, opt_master_data;
+static char *opt_bind_addr = NULL;
static uint my_end_arg;
static char * opt_mysql_unix_port=0;
static int first_error=0;
@@ -210,6 +214,9 @@
{"autoclose", OPT_AUTO_CLOSE, "Auto close the screen on exit for Netware.",
0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
#endif
+ {"bind-address", OPT_BIND_ADDRESS, "IP address to bind to.",
+ (uchar**) &opt_bind_addr, (uchar**) &opt_bind_addr, 0, GET_STR,
+ REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
{"character-sets-dir", OPT_CHARSETS_DIR,
"Directory where character sets are.", (uchar**) &charsets_dir,
(uchar**) &charsets_dir, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
@@ -1463,6 +1470,10 @@
#endif
if (opt_protocol)
mysql_options(&mysql_connection,MYSQL_OPT_PROTOCOL,(char*)&opt_protocol);
+ if (opt_bind_addr)
+ {
+ mysql_options(&mysql_connection,MYSQL_OPT_BIND,opt_bind_addr);
+ }
#ifdef HAVE_SMEM
if (shared_memory_base_name)
mysql_options(&mysql_connection,MYSQL_SHARED_MEMORY_BASE_NAME,shared_memory_base_name);
--- 5.1.34/client/mysqlimport.c 2009-06-03 23:17:47.000000000 +0200
+++ 7.0/client/mysqlimport.c 2009-06-04 10:35:19.000000000 +0200
@@ -57,6 +60,7 @@
*escaped=0, *opt_columns=0,
*default_charset= (char*) MYSQL_DEFAULT_CHARSET_NAME;
static uint opt_mysql_port= 0, opt_protocol= 0;
+static char *opt_bind_addr = NULL;
static char * opt_mysql_unix_port=0;
static longlong opt_ignore_lines= -1;
static CHARSET_INFO *charset_info= &my_charset_latin1;
@@ -72,6 +76,9 @@
{"autoclose", OPT_AUTO_CLOSE, "Auto close the screen on exit for Netware.",
0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
#endif
+ {"bind-address", OPT_BIND_ADDRESS, "IP address to bind to.",
+ (uchar**) &opt_bind_addr, (uchar**) &opt_bind_addr, 0, GET_STR,
+ REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
{"character-sets-dir", OPT_CHARSETS_DIR,
"Directory where character sets are.", (uchar**) &charsets_dir,
(uchar**) &charsets_dir, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
@@ -423,6 +430,8 @@
#endif
if (opt_protocol)
mysql_options(mysql,MYSQL_OPT_PROTOCOL,(char*)&opt_protocol);
+ if (opt_bind_addr)
+ mysql_options(mysql,MYSQL_OPT_BIND,opt_bind_addr);
#ifdef HAVE_SMEM
if (shared_memory_base_name)
mysql_options(mysql,MYSQL_SHARED_MEMORY_BASE_NAME,shared_memory_base_name);
--- 5.1.34/client/mysqlshow.c 2009-06-03 23:17:47.000000000 +0200
+++ 7.0/client/mysqlshow.c 2009-06-04 10:35:19.000000000 +0200
@@ -38,6 +41,7 @@
static char *shared_memory_base_name=0;
#endif
static uint opt_protocol=0;
+static char *opt_bind_addr = NULL;
static void get_options(int *argc,char ***argv);
static uint opt_mysql_port=0;
@@ -115,6 +119,10 @@
#endif
if (opt_protocol)
mysql_options(&mysql,MYSQL_OPT_PROTOCOL,(char*)&opt_protocol);
+ if (opt_bind_addr)
+ {
+ mysql_options(&mysql,MYSQL_OPT_BIND,opt_bind_addr);
+ }
#ifdef HAVE_SMEM
if (shared_memory_base_name)
mysql_options(&mysql,MYSQL_SHARED_MEMORY_BASE_NAME,shared_memory_base_name);
@@ -163,6 +171,9 @@
{"autoclose", OPT_AUTO_CLOSE, "Auto close the screen on exit for Netware.",
0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
#endif
+ {"bind-address", OPT_BIND_ADDRESS, "IP address to bind to.",
+ (uchar**) &opt_bind_addr, (uchar**) &opt_bind_addr, 0, GET_STR,
+ REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
{"character-sets-dir", 'c', "Directory where character sets are.",
(uchar**) &charsets_dir, (uchar**) &charsets_dir, 0, GET_STR, REQUIRED_ARG, 0,
0, 0, 0, 0, 0},
--- 5.1.34/client/mysqltest.cc 2009-06-03 23:17:46.000000000 +0200
+++ 7.0/client/mysqltest.cc 2009-06-04 10:35:19.000000000 +0200
@@ -75,7 +78,8 @@
enum {
OPT_SKIP_SAFEMALLOC=OPT_MAX_CLIENT_OPTION,
OPT_PS_PROTOCOL, OPT_SP_PROTOCOL, OPT_CURSOR_PROTOCOL, OPT_VIEW_PROTOCOL,
- OPT_MAX_CONNECT_RETRIES, OPT_MARK_PROGRESS, OPT_LOG_DIR, OPT_TAIL_LINES
+ OPT_MAX_CONNECT_RETRIES, OPT_MARK_PROGRESS, OPT_LOG_DIR, OPT_TAIL_LINES,
+ OPT_RESULT_FORMAT_VERSION
};
static int record= 0, opt_sleep= -1;
@@ -85,6 +89,7 @@
const char *opt_include= 0, *opt_charsets_dir;
static int opt_port= 0;
static int opt_max_connect_retries;
+static int opt_result_format_version;
static my_bool opt_compress= 0, silent= 0, verbose= 0;
static my_bool debug_info_flag= 0, debug_check_flag= 0;
static my_bool tty_password= 0;
@@ -280,10 +285,12 @@
Q_SEND_QUIT, Q_CHANGE_USER, Q_MKDIR, Q_RMDIR,
Q_LIST_FILES, Q_LIST_FILES_WRITE_FILE, Q_LIST_FILES_APPEND_FILE,
Q_SEND_SHUTDOWN, Q_SHUTDOWN_SERVER,
+ Q_RESULT_FORMAT_VERSION,
Q_UNKNOWN, /* Unknown command. */
Q_COMMENT, /* Comments, ignored. */
- Q_COMMENT_WITH_COMMAND
+ Q_COMMENT_WITH_COMMAND,
+ Q_EMPTY_LINE
};
@@ -376,6 +383,7 @@
"list_files_append_file",
"send_shutdown",
"shutdown_server",
+ "result_format",
0
};
@@ -2175,6 +2183,59 @@
}
+static void
+set_result_format_version(ulong new_version)
+{
+ switch (new_version){
+ case 1:
+ /* The first format */
+ break;
+ case 2:
+ /* New format that also writes comments and empty lines
+ from test file to result */
+ break;
+ default:
+ die("Version format %lu has not yet been implemented", new_version);
+ break;
+ }
+ opt_result_format_version= new_version;
+}
+
+
+/*
+ Set the result format version to use when generating
+ the .result file
+*/
+
+static void
+do_result_format_version(struct st_command *command)
+{
+ long version;
+ static DYNAMIC_STRING ds_version;
+ const struct command_arg result_format_args[] = {
+ "version", ARG_STRING, TRUE, &ds_version, "Version to use",
+ };
+
+ DBUG_ENTER("do_result_format_version");
+
+ check_command_args(command, command->first_argument,
+ result_format_args,
+ sizeof(result_format_args)/sizeof(struct command_arg),
+ ',');
+
+ /* Convert version number to int */
+ if (!str2int(ds_version.str, 10, (long) 0, (long) INT_MAX, &version))
+ die("Invalid version number: '%s'", ds_version.str);
+
+ set_result_format_version(version);
+
+ dynstr_append(&ds_res, "result_format: ");
+ dynstr_append_mem(&ds_res, ds_version.str, ds_version.length);
+ dynstr_append(&ds_res, "\n");
+ dynstr_free(&ds_version);
+}
+
+
/*
Set variable from the result of a field in a query
@@ -2568,6 +2629,9 @@
}
+/* where to put this declaration in the file? */
+int regex_replace(DYNAMIC_STRING *ds, char *expr);
+
/*
Execute given command.
@@ -2619,12 +2683,18 @@
#ifdef __WIN__
#ifndef USE_CYGWIN
- /* Replace /dev/null with NUL */
- while(replace(&ds_cmd, "/dev/null", 9, "NUL", 3) == 0)
- ;
- /* Replace "closed stdout" with non existing output fd */
- while(replace(&ds_cmd, ">&-", 3, ">&4", 3) == 0)
- ;
+ {
+ char *replaces[]= {
+ /* Replace /dev/null with NUL */
+ "/\\/dev\\/null/NUL/",
+ /* Replace "closed stdout" with non existing output fd */
+ "/>&-/>&4/",
+ 0
+ };
+ int i= 0;
+ for(;replaces[i];i++)
+ regex_replace(&ds_cmd, replaces[i]);
+ }
#endif
#endif
@@ -5185,7 +5255,7 @@
int read_line(char *buf, int size)
{
- char c, last_quote;
+ char c, last_quote, last_char= 0;
char *p= buf, *buf_end= buf + size - 1;
int skip_char= 0;
enum {R_NORMAL, R_Q, R_SLASH_IN_Q,
@@ -5284,14 +5354,24 @@
}
else if (my_isspace(charset_info, c))
{
- /* Skip all space at begining of line */
if (c == '\n')
{
+ if (last_char == '\n')
+ {
+ /* Two new lines in a row, return empty line */
+ DBUG_PRINT("info", ("Found two new lines in a row"));
+ *p++= c;
+ *p= 0;
+ DBUG_RETURN(0);
+ }
+
/* Query hasn't started yet */
start_lineno= cur_file->lineno;
DBUG_PRINT("info", ("Query hasn't started yet, start_lineno: %d",
start_lineno));
}
+
+ /* Skip all space at begining of line */
skip_char= 1;
}
else if (end_of_query(c))
@@ -5332,6 +5412,8 @@
}
+ last_char= c;
+
if (!skip_char)
{
/* Could be a multibyte character */
@@ -5541,9 +5623,10 @@
DBUG_RETURN(1);
}
- convert_to_format_v1(read_command_buf);
+ if (opt_result_format_version == 1)
+ convert_to_format_v1(read_command_buf);
- DBUG_PRINT("info", ("query: %s", read_command_buf));
+ DBUG_PRINT("info", ("query: '%s'", read_command_buf));
if (*p == '#')
{
command->type= Q_COMMENT;
@@ -5553,6 +5636,10 @@
command->type= Q_COMMENT_WITH_COMMAND;
p+= 2; /* Skip past -- */
}
+ else if (*p == '\n')
+ {
+ command->type= Q_EMPTY_LINE;
+ }
/* Skip leading spaces */
while (*p && my_isspace(charset_info, *p))
@@ -5647,6 +5734,11 @@
{"result-file", 'R', "Read/Store result from/in this file.",
(uchar**) &result_file_name, (uchar**) &result_file_name, 0,
GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
+ {"result-format-version", OPT_RESULT_FORMAT_VERSION,
+ "Version of the result file format to use",
+ (uchar**) &opt_result_format_version,
+ (uchar**) &opt_result_format_version, 0,
+ GET_INT, REQUIRED_ARG, 1, 1, 2, 0, 0, 0},
{"server-arg", 'A', "Send option value to embedded server as a parameter.",
0, 0, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
{"server-file", 'F', "Read embedded server arguments from file.",
@@ -5843,6 +5935,9 @@
sf_malloc_quick=1;
#endif
break;
+ case OPT_RESULT_FORMAT_VERSION:
+ set_result_format_version(opt_result_format_version);
+ break;
case 'V':
print_version();
exit(0);
@@ -7680,6 +7775,7 @@
case Q_COPY_FILE: do_copy_file(command); break;
case Q_CHMOD_FILE: do_chmod_file(command); break;
case Q_PERL: do_perl(command); break;
+ case Q_RESULT_FORMAT_VERSION: do_result_format_version(command); break;
case Q_DELIMITER:
do_delimiter(command);
break;
@@ -7796,9 +7892,38 @@
do_sync_with_master2(command, 0);
break;
}
- case Q_COMMENT: /* Ignore row */
+ case Q_COMMENT:
+ {
+ const char* p= command->query;
command->last_argument= command->end;
+
+ /* Don't output comments in v1 */
+ if (opt_result_format_version == 1)
+ break;
+
+ /* Don't output comments if query logging is off */
+ if (disable_query_log)
+ break;
+
+ /* Write comment's with two starting #'s to result file */
+ if (p && *p == '#' && *(p+1) == '#')
+ {
+ dynstr_append_mem(&ds_res, command->query, command->query_len);
+ dynstr_append(&ds_res, "\n");
+ }
break;
+ }
+ case Q_EMPTY_LINE:
+ /* Don't output newline in v1 */
+ if (opt_result_format_version == 1)
+ break;
+
+ /* Don't output newline if query logging is off */
+ if (disable_query_log)
+ break;
+
+ dynstr_append(&ds_res, "\n");
+ break;
case Q_PING:
handle_command_error(command, mysql_ping(&cur_con->mysql));
break;
@@ -8475,15 +8600,31 @@
command->last_argument= command->end;
}
+/* where to put these functions in the file? */
+void free_regex(struct st_replace_regex* r)
+{
+ delete_dynamic(&r->regex_arr);
+ my_free(r->even_buf,MYF(MY_ALLOW_ZERO_PTR));
+ my_free(r->odd_buf,MYF(MY_ALLOW_ZERO_PTR));
+ my_free(r,MYF(0));
+}
+
+/* where to put these functions in the file? */
+int regex_replace(DYNAMIC_STRING *ds, char *expr)
+{
+ struct st_replace_regex* r= init_replace_regex(expr);
+ int rv= multi_reg_replace(r, ds->str);
+ dynstr_set(ds, r->buf);
+ free_regex(r);
+ return rv;
+}
+
void free_replace_regex()
{
if (glob_replace_regex)
{
- delete_dynamic(&glob_replace_regex->regex_arr);
- my_free(glob_replace_regex->even_buf,MYF(MY_ALLOW_ZERO_PTR));
- my_free(glob_replace_regex->odd_buf,MYF(MY_ALLOW_ZERO_PTR));
- my_free(glob_replace_regex,MYF(0));
- glob_replace_regex=0;
+ free_regex(glob_replace_regex);
+ glob_replace_regex= 0;
}
}
--- 5.1.34/sql/CMakeLists.txt 2009-06-03 23:17:32.000000000 +0200
+++ 7.0/sql/CMakeLists.txt 2009-06-04 10:35:50.000000000 +0200
@@ -39,11 +40,16 @@
ADD_DEFINITIONS(-DMYSQL_SERVER -D_CONSOLE -DHAVE_DLOPEN -DHAVE_EVENT_SCHEDULER)
+IF(WITH_NDBCLUSTER_STORAGE_ENGINE)
+ INCLUDE_DIRECTORIES(${NDB_CLIENT_INCLUDES})
+ENDIF(WITH_NDBCLUSTER_STORAGE_ENGINE)
+
ADD_EXECUTABLE(mysqld
../sql-common/client.c derror.cc des_key_file.cc
discover.cc ../libmysql/errmsg.c field.cc field_conv.cc
filesort.cc gstream.cc
ha_partition.cc
+ ${NDB_HANDLER_SRC}
handler.cc hash_filo.cc hash_filo.h
hostname.cc init.cc item.cc item_buff.cc item_cmpfunc.cc
item_create.cc item_func.cc item_geofunc.cc item_row.cc
@@ -119,6 +125,10 @@
IF(WITH_INNOBASE_STORAGE_ENGINE)
TARGET_LINK_LIBRARIES(mysqld innobase)
ENDIF(WITH_INNOBASE_STORAGE_ENGINE)
+IF(WITH_NDBCLUSTER_STORAGE_ENGINE)
+ TARGET_LINK_LIBRARIES(mysqld ndbclient)
+ENDIF(WITH_NDBCLUSTER_STORAGE_ENGINE)
+
ADD_DEPENDENCIES(mysqld GenError)
--- 5.1.34/sql/field.cc 2009-06-03 23:17:47.000000000 +0200
+++ 7.0/sql/field.cc 2009-06-04 10:35:50.000000000 +0200
@@ -7231,6 +7234,11 @@
return length_bytes == 1 ? (uint32) *ptr : uint2korr(ptr);
}
+uint32 Field_varstring::used_length()
+{
+ return length_bytes == 1 ? 1 + (uint32) (uchar) *ptr : 2 + uint2korr(ptr);
+}
+
/*
Functions to create a packed row.
Here the number of length bytes are depending on the given max_length
@@ -9519,7 +9527,9 @@
uint fld_type_modifier, Item *fld_default_value,
Item *fld_on_update_value, LEX_STRING *fld_comment,
char *fld_change, List<String> *fld_interval_list,
- CHARSET_INFO *fld_charset, uint fld_geom_type)
+ CHARSET_INFO *fld_charset, uint fld_geom_type,
+ enum ha_storage_media storage_type,
+ enum column_format_type column_format)
{
uint sign_len, allowed_type_modifier= 0;
ulong max_field_charlength= MAX_FIELD_CHARLENGTH;
@@ -9530,6 +9540,8 @@
field_name= fld_name;
def= fld_default_value;
flags= fld_type_modifier;
+ flags|= (((uint)storage_type & STORAGE_TYPE_MASK) << FIELD_STORAGE_FLAGS);
+ flags|= (((uint)column_format & COLUMN_FORMAT_MASK) << COLUMN_FORMAT_FLAGS);
unireg_check= (fld_type_modifier & AUTO_INCREMENT_FLAG ?
Field::NEXT_NUMBER : Field::NONE);
decimals= fld_decimals ? (uint)atoi(fld_decimals) : 0;
@@ -9841,6 +9853,8 @@
}
case MYSQL_TYPE_DECIMAL:
DBUG_ASSERT(0); /* Was obsolete */
+ default:
+ break;
}
/* Remember the value of length */
char_length= length;
--- 5.1.34/sql/field.h 2009-06-03 23:17:32.000000000 +0200
+++ 7.0/sql/field.h 2009-06-04 10:35:50.000000000 +0200
@@ -186,8 +189,15 @@
/*
data_length() return the "real size" of the data in memory.
+ For varstrings, this does _not_ include the length bytes.
*/
virtual uint32 data_length() { return pack_length(); }
+ /*
+ used_length() returns the number of bytes actually used to store the data
+ of the field. So for a varstring it includes both lenght byte(s) and
+ string data, and anything after data_length() bytes are unused.
+ */
+ virtual uint32 used_length() { return pack_length(); }
virtual uint32 sort_length() const { return pack_length(); }
/**
@@ -488,6 +498,19 @@
DBUG_ASSERT(0);
return GEOM_GEOMETRY;
}
+
+ inline enum ha_storage_media field_storage_type() const
+ {
+ return (enum ha_storage_media)
+ ((flags >> FIELD_STORAGE_FLAGS) & STORAGE_TYPE_MASK);
+ }
+
+ inline enum column_format_type column_format() const
+ {
+ return (enum column_format_type)
+ ((flags >> COLUMN_FORMAT_FLAGS) & COLUMN_FORMAT_MASK);
+ }
+
/* Hash value */
virtual void hash(ulong *nr, ulong *nr2);
friend bool reopen_table(THD *,struct st_table *,bool);
@@ -1580,6 +1603,7 @@
uint packed_col_length(const uchar *to, uint length);
uint max_packed_col_length(uint max_length);
uint32 data_length();
+ uint32 used_length();
uint size_of() const { return sizeof(*this); }
enum_field_types real_type() const { return MYSQL_TYPE_VARCHAR; }
bool has_charset(void) const
@@ -2051,6 +2075,18 @@
{ return new (mem_root) Create_field(*this); }
void create_length_to_internal_length(void);
+ inline enum ha_storage_media field_storage_type() const
+ {
+ return (enum ha_storage_media)
+ ((flags >> FIELD_STORAGE_FLAGS) & STORAGE_TYPE_MASK);
+ }
+
+ inline enum column_format_type column_format() const
+ {
+ return (enum column_format_type)
+ ((flags >> COLUMN_FORMAT_FLAGS) & COLUMN_FORMAT_MASK);
+ }
+
/* Init for a tmp table field. To be extended if need be. */
void init_for_tmp_table(enum_field_types sql_type_arg,
uint32 max_length, uint32 decimals,
@@ -2060,7 +2096,9 @@
char *decimals, uint type_modifier, Item *default_value,
Item *on_update_value, LEX_STRING *comment, char *change,
List<String> *interval_list, CHARSET_INFO *cs,
- uint uint_geom_type);
+ uint uint_geom_type,
+ enum ha_storage_media storage_type,
+ enum column_format_type column_format);
};
--- 5.1.34/sql/ha_partition.cc 2009-06-03 23:17:32.000000000 +0200
+++ 7.0/sql/ha_partition.cc 2009-06-04 10:35:50.000000000 +0200
@@ -72,7 +75,7 @@
TABLE_SHARE *share,
MEM_ROOT *mem_root);
static uint partition_flags();
-static uint alter_table_flags(uint flags);
+static uint alter_partition_flags();
static int partition_initialize(void *p)
@@ -85,7 +88,7 @@
partition_hton->db_type= DB_TYPE_PARTITION_DB;
partition_hton->create= partition_create_handler;
partition_hton->partition_flags= partition_flags;
- partition_hton->alter_table_flags= alter_table_flags;
+ partition_hton->alter_partition_flags= alter_partition_flags;
partition_hton->flags= HTON_NOT_USER_SELECTABLE | HTON_HIDDEN;
return 0;
@@ -139,7 +142,7 @@
return HA_CAN_PARTITION;
}
-static uint alter_table_flags(uint flags __attribute__((unused)))
+static uint alter_partition_flags()
{
return (HA_PARTITION_FUNCTION_SUPPORTED |
HA_FAST_CHANGE_PARTITION);
@@ -3556,10 +3559,10 @@
}
-void ha_partition::column_bitmaps_signal()
+void ha_partition::column_bitmaps_signal(uint sig_type)
{
- handler::column_bitmaps_signal();
- bitmap_union(table->read_set, &m_part_info->full_part_field_set);
+ handler::column_bitmaps_signal(sig_type);
+ bitmap_union(table->read_set, &m_part_info->full_part_field_set);
}
@@ -5805,6 +5808,35 @@
}
+/*
+ Calculate hash value for KEY partitioning using an array of fields.
+
+ SYNOPSIS
+ calculate_key_hash_value()
+ field_array An array of the fields in KEY partitioning
+
+ RETURN VALUE
+ hash_value calculated
+
+ DESCRIPTION
+ Uses the hash function on the character set of the field. Integer and
+ floating point fields use the binary character set by default.
+*/
+
+uint32 ha_partition::calculate_key_hash_value(Field **field_array)
+{
+ ulong nr1= 1;
+ ulong nr2= 4;
+
+ do
+ {
+ Field *field= *field_array;
+ field->hash(&nr1, &nr2);
+ } while (*(++field_array));
+ return (uint32) nr1;
+}
+
+
/****************************************************************************
MODULE print messages
****************************************************************************/
@@ -5860,89 +5892,6 @@
/****************************************************************************
MODULE handler characteristics
****************************************************************************/
-/**
- alter_table_flags must be on handler/table level, not on hton level
- due to the ha_partition hton does not know what the underlying hton is.
-*/
-uint ha_partition::alter_table_flags(uint flags)
-{
- DBUG_ENTER("ha_partition::alter_table_flags");
- DBUG_RETURN(ht->alter_table_flags(flags) |
- m_file[0]->alter_table_flags(flags));
-}
-
-
-/**
- check if copy of data is needed in alter table.
-*/
-bool ha_partition::check_if_incompatible_data(HA_CREATE_INFO *create_info,
- uint table_changes)
-{
- handler **file;
- bool ret= COMPATIBLE_DATA_YES;
-
- /*
- The check for any partitioning related changes have already been done
- in mysql_alter_table (by fix_partition_func), so it is only up to
- the underlying handlers.
- */
- for (file= m_file; *file; file++)
- if ((ret= (*file)->check_if_incompatible_data(create_info,
- table_changes)) !=
- COMPATIBLE_DATA_YES)
- break;
- return ret;
-}
-
-
-/**
- Support of fast or online add/drop index
-*/
-int ha_partition::add_index(TABLE *table_arg, KEY *key_info, uint num_of_keys)
-{
- handler **file;
- int ret= 0;
-
- /*
- There has already been a check in fix_partition_func in mysql_alter_table
- before this call, which checks for unique/primary key violations of the
- partitioning function. So no need for extra check here.
- */
- for (file= m_file; *file; file++)
- if ((ret= (*file)->add_index(table_arg, key_info, num_of_keys)))
- break;
- return ret;
-}
-
-
-int ha_partition::prepare_drop_index(TABLE *table_arg, uint *key_num,
- uint num_of_keys)
-{
- handler **file;
- int ret= 0;
-
- /*
- DROP INDEX does not affect partitioning.
- */
- for (file= m_file; *file; file++)
- if ((ret= (*file)->prepare_drop_index(table_arg, key_num, num_of_keys)))
- break;
- return ret;
-}
-
-
-int ha_partition::final_drop_index(TABLE *table_arg)
-{
- handler **file;
- int ret= HA_ERR_WRONG_COMMAND;
-
- for (file= m_file; *file; file++)
- if ((ret= (*file)->final_drop_index(table_arg)))
- break;
- return ret;
-}
-
-
/*
If frm_error() is called then we will use this to to find out what file
extensions exist for the storage engine. This is also used by the default
--- 5.1.34/sql/ha_partition.h 2009-06-03 23:17:32.000000000 +0200
+++ 7.0/sql/ha_partition.h 2009-06-04 10:35:50.000000000 +0200
@@ -178,7 +181,7 @@
bool auto_increment_safe_stmt_log_lock;
public:
handler *clone(MEM_ROOT *mem_root);
- virtual void set_part_info(partition_info *part_info)
+ virtual void set_part_info(partition_info *part_info, bool early)
{
m_part_info= part_info;
m_is_sub_partitioned= part_info->is_sub_partitioned();
@@ -245,8 +248,6 @@
DBUG_RETURN(0);
}
virtual void change_table_ptr(TABLE *table_arg, TABLE_SHARE *share);
- virtual bool check_if_incompatible_data(HA_CREATE_INFO *create_info,
- uint table_changes);
private:
int prepare_for_rename();
int copy_partitions(ulonglong * const copied, ulonglong * const deleted);
@@ -493,7 +494,7 @@
int handle_ordered_next(uchar * buf, bool next_same);
int handle_ordered_prev(uchar * buf);
void return_top_record(uchar * buf);
- void column_bitmaps_signal();
+ void column_bitmaps_signal(uint sig_type);
public:
/*
-------------------------------------------------------------------------
@@ -574,6 +575,8 @@
underlying handlers must have the same implementation for it to work.
*/
virtual uint8 table_cache_type();
+ /* Calculate hash value for PARTITION BY KEY tables. */
+ uint32 calculate_key_hash_value(Field **field_array);
virtual ha_rows records();
/*
@@ -831,11 +834,6 @@
return m_file[0]->index_flags(inx, part, all_parts);
}
- /**
- wrapper function for handlerton alter_table_flags, since
- the ha_partition_hton cannot know all its capabilities
- */
- virtual uint alter_table_flags(uint flags);
/*
extensions of table handler files
*/
@@ -1011,14 +1009,14 @@
-------------------------------------------------------------------------
MODULE on-line ALTER TABLE
-------------------------------------------------------------------------
- These methods are in the handler interface. (used by innodb-plugin)
- They are used for on-line/fast alter table add/drop index:
+ These methods are in the handler interface but never used (yet)
+ They are to be used by on-line alter table add/drop index:
+ -------------------------------------------------------------------------
+ virtual ulong index_ddl_flags(KEY *wanted_index) const
+ virtual int add_index(TABLE *table_arg,KEY *key_info,uint num_of_keys);
+ virtual int drop_index(TABLE *table_arg,uint *key_num,uint num_of_keys);
-------------------------------------------------------------------------
*/
- virtual int add_index(TABLE *table_arg, KEY *key_info, uint num_of_keys);
- virtual int prepare_drop_index(TABLE *table_arg, uint *key_num,
- uint num_of_keys);
- virtual int final_drop_index(TABLE *table_arg);
/*
-------------------------------------------------------------------------
--- 5.1.34/sql/handler.cc 2009-06-03 23:17:47.000000000 +0200
+++ 7.0/sql/handler.cc 2009-06-04 10:35:50.000000000 +0200
@@ -2013,6 +2016,17 @@
}
+/**
+ Get tablespace name from handler
+ Returns the tablespace name associated
+ with the table or NULL if not defined
+*/
+const
+char* handler::get_tablespace_name()
+{
+ return table->s->tablespace;
+}
+
/** @brief
Open database-handler.
@@ -2431,7 +2445,7 @@
rnd_init() call is made as after this, MySQL will not use the bitmap
for any program logic checking.
*/
-void handler::column_bitmaps_signal()
+void handler::column_bitmaps_signal(uint sig_type)
{
DBUG_ENTER("column_bitmaps_signal");
DBUG_PRINT("info", ("read_set: 0x%lx write_set: 0x%lx", (long) table->read_set,
@@ -2468,7 +2482,7 @@
(void) extra(HA_EXTRA_KEYREAD);
table->mark_columns_used_by_index_no_reset(table->s->next_number_index,
table->read_set);
- column_bitmaps_signal();
+ column_bitmaps_signal(HA_CHANGE_TABLE_READ_BITMAP);
index_init(table->s->next_number_index, 1);
if (table->s->next_number_keypart == 0)
{ // Autoincrement at key-start
@@ -2928,6 +2942,8 @@
uint handler::get_dup_key(int error)
{
DBUG_ENTER("handler::get_dup_key");
+ if (!table || !table->file)
+ DBUG_RETURN((uint) -1);
table->file->errkey = (uint) -1;
if (error == HA_ERR_FOUND_DUPP_KEY || error == HA_ERR_FOREIGN_DUPLICATE_KEY ||
error == HA_ERR_FOUND_DUPP_UNIQUE || error == HA_ERR_NULL_IN_SPATIAL ||
@@ -3526,7 +3542,7 @@
init_tmp_table_share(thd, &share, db, 0, table_name, path);
if (open_table_def(thd, &share, 0) ||
open_table_from_share(thd, &share, "", 0, (uint) READ_ALL, 0, &table,
- TRUE))
+ OTM_CREATE))
goto err;
if (update_create_info)
@@ -3595,7 +3611,7 @@
{
DBUG_RETURN(3);
}
- if (open_table_from_share(thd, &share, "" ,0, 0, 0, &table, FALSE))
+ if (open_table_from_share(thd, &share, "" ,0, 0, 0, &table, OTM_OPEN))
{
free_table_share(&share);
DBUG_RETURN(3);
@@ -3854,7 +3870,7 @@
DBUG_RETURN(args.err);
}
-#ifdef HAVE_NDB_BINLOG
+#ifdef WITH_NDBCLUSTER_STORAGE_ENGINE
/*
TODO: change this into a dynamic struct
List<handlerton> does not work as
@@ -3899,27 +3915,34 @@
{
hton_list_st hton_list;
uint i, sz;
+ int res= 0;
hton_list.sz= 0;
plugin_foreach(thd, binlog_func_list,
MYSQL_STORAGE_ENGINE_PLUGIN, &hton_list);
for (i= 0, sz= hton_list.sz; i < sz ; i++)
- hton_list.hton[i]->binlog_func(hton_list.hton[i], thd, bfn->fn, bfn->arg);
- return FALSE;
+ res|= hton_list.hton[i]->binlog_func(hton_list.hton[i], thd, bfn->fn, bfn->arg);
+ return res != 0;
}
+#ifdef HAVE_NDB_BINLOG
int ha_reset_logs(THD *thd)
{
binlog_func_st bfn= {BFN_RESET_LOGS, 0};
binlog_func_foreach(thd, &bfn);
+ if (thd->main_da.is_error())
+ return 1;
return 0;
}
-void ha_reset_slave(THD* thd)
+int ha_reset_slave(THD* thd)
{
binlog_func_st bfn= {BFN_RESET_SLAVE, 0};
binlog_func_foreach(thd, &bfn);
+ if (thd->main_da.is_error())
+ return 1;
+ return 0;
}
void ha_binlog_wait(THD* thd)
@@ -3939,9 +3962,48 @@
{
binlog_func_st bfn= {BFN_BINLOG_PURGE_FILE, (void *)file};
binlog_func_foreach(thd, &bfn);
+ if (thd->main_da.is_error())
+ return 1;
+ return 0;
+}
+#endif
+
+static int ha_global_schema_lock(THD *thd, int no_queue)
+{
+ binlog_func_st bfn= {BFN_GLOBAL_SCHEMA_LOCK, (void *)&no_queue};
+ int res= binlog_func_foreach(thd, &bfn);
+ if (res || thd->main_da.is_error())
+ return 1;
+ return 0;
+}
+
+static int ha_global_schema_unlock(THD *thd)
+{
+ binlog_func_st bfn= {BFN_GLOBAL_SCHEMA_UNLOCK, 0};
+ binlog_func_foreach(thd, &bfn);
+ if (thd->main_da.is_error())
+ return 1;
return 0;
}
+Ha_global_schema_lock_guard::Ha_global_schema_lock_guard(THD *thd)
+ : m_thd(thd), m_lock(0)
+{
+}
+
+Ha_global_schema_lock_guard::~Ha_global_schema_lock_guard()
+{
+ if (m_lock)
+ ha_global_schema_unlock(m_thd);
+}
+
+int Ha_global_schema_lock_guard::lock(int no_queue)
+{
+ DBUG_ASSERT(m_lock == 0);
+ m_lock= 1;
+ return ha_global_schema_lock(m_thd, no_queue);
+}
+
struct binlog_log_query_st
{
enum_binlog_command binlog_command;
@@ -4578,9 +4640,9 @@
mark_trx_read_write();
- if (unlikely(error= write_row(buf)))
+ if (unlikely((error= write_row(buf)) != 0))
DBUG_RETURN(error);
- if (unlikely(error= binlog_log_row(table, 0, buf, log_func)))
+ if (unlikely((error= binlog_log_row(table, 0, buf, log_func)) != 0))
DBUG_RETURN(error); /* purecov: inspected */
DBUG_RETURN(0);
}
@@ -4599,23 +4661,28 @@
mark_trx_read_write();
- if (unlikely(error= update_row(old_data, new_data)))
+ if (unlikely((error= update_row(old_data, new_data)) != 0))
return error;
- if (unlikely(error= binlog_log_row(table, old_data, new_data, log_func)))
+ if (unlikely((error= binlog_log_row(table, old_data, new_data, log_func))!=0))
return error;
return 0;
}
-int handler::ha_delete_row(const uchar *buf)
+int handler::ha_delete_row(const uchar *buf, bool will_batch)
{
int error;
Log_func *log_func= Delete_rows_log_event::binlog_row_logging_function;
mark_trx_read_write();
- if (unlikely(error= delete_row(buf)))
+ if (will_batch)
+ {
+ if (unlikely((error= bulk_delete_row(buf)) != 0))
+ return error;
+ }
+ else if (unlikely((error= delete_row(buf)) != 0))
return error;
- if (unlikely(error= binlog_log_row(table, buf, 0, log_func)))
+ if (unlikely((error= binlog_log_row(table, buf, 0, log_func)) != 0))
return error;
return 0;
}
--- 5.1.34/sql/handler.h 2009-06-03 23:17:47.000000000 +0200
+++ 7.0/sql/handler.h 2009-06-04 10:35:50.000000000 +0200
@@ -47,6 +50,61 @@
#define HA_ADMIN_NEEDS_ALTER -11
#define HA_ADMIN_NEEDS_CHECK -12
+/* Bits to show what an alter table will do */
+#include <sql_bitmap.h>
+
+#define HA_MAX_ALTER_FLAGS 40
+typedef Bitmap<HA_MAX_ALTER_FLAGS> HA_ALTER_FLAGS;
+
+#define HA_ADD_INDEX (0)
+#define HA_DROP_INDEX (1)
+#define HA_ALTER_INDEX (2)
+#define HA_RENAME_INDEX (3)
+#define HA_ADD_UNIQUE_INDEX (4)
+#define HA_DROP_UNIQUE_INDEX (5)
+#define HA_ALTER_UNIQUE_INDEX (6)
+#define HA_RENAME_UNIQUE_INDEX (7)
+#define HA_ADD_PK_INDEX (8)
+#define HA_DROP_PK_INDEX (9)
+#define HA_ALTER_PK_INDEX (10)
+#define HA_ADD_COLUMN (11)
+#define HA_DROP_COLUMN (12)
+#define HA_CHANGE_COLUMN (13)
+#define HA_ALTER_COLUMN_NAME (14)
+#define HA_ALTER_COLUMN_TYPE (15)
+#define HA_ALTER_COLUMN_ORDER (16)
+#define HA_ALTER_COLUMN_NULLABLE (17)
+#define HA_COLUMN_DEFAULT_VALUE (18)
+#define HA_COLUMN_STORAGE (19)
+#define HA_COLUMN_FORMAT (20)
+#define HA_ADD_FOREIGN_KEY (21)
+#define HA_DROP_FOREIGN_KEY (22)
+#define HA_ALTER_FOREIGN_KEY (23)
+#define HA_ADD_CONSTRAINT (24)
+#define HA_ADD_PARTITION (25)
+#define HA_DROP_PARTITION (26)
+#define HA_ALTER_PARTITION (27)
+#define HA_COALESCE_PARTITION (28)
+#define HA_REORGANIZE_PARTITION (29)
+#define HA_CHANGE_CHARACTER_SET (30)
+#define HA_SET_DEFAULT_CHARACTER_SET (31)
+#define HA_CHANGE_AUTOINCREMENT_VALUE (32)
+#define HA_ALTER_STORAGE (33)
+#define HA_ALTER_TABLESPACE (34)
+#define HA_ALTER_ROW_FORMAT (35)
+#define HA_RENAME_TABLE (36)
+#define HA_ALTER_STORAGE_ENGINE (37)
+#define HA_RECREATE (38)
+#define HA_ALTER_TABLE_REORG (39)
+/* Remember to increase HA_MAX_ALTER_FLAGS when adding more flags! */
+
+/* Return values for check_if_supported_alter */
+
+#define HA_ALTER_ERROR -1
+#define HA_ALTER_SUPPORTED_WAIT_LOCK 0
+#define HA_ALTER_SUPPORTED_NO_LOCK 1
+#define HA_ALTER_NOT_SUPPORTED 2
+
/* Bits in table_flags() to show what database can do */
#define HA_NO_TRANSACTIONS (1 << 0) /* Doesn't support transactions */
@@ -125,6 +183,8 @@
#define HA_BINLOG_ROW_CAPABLE (LL(1) << 34)
#define HA_BINLOG_STMT_CAPABLE (LL(1) << 35)
+#define HA_ONLINE_ALTER (LL(1) << 36)
+
/*
Set of all binlog flags. Currently only contain the capabilities
flags.
@@ -140,30 +200,6 @@
#define HA_KEYREAD_ONLY 64 /* Support HA_EXTRA_KEYREAD */
/*
- bits in alter_table_flags:
-*/
-/*
- These bits are set if different kinds of indexes can be created
- off-line without re-create of the table (but with a table lock).
-*/
-#define HA_ONLINE_ADD_INDEX_NO_WRITES (1L << 0) /*add index w/lock*/
-#define HA_ONLINE_DROP_INDEX_NO_WRITES (1L << 1) /*drop index w/lock*/
-#define HA_ONLINE_ADD_UNIQUE_INDEX_NO_WRITES (1L << 2) /*add unique w/lock*/
-#define HA_ONLINE_DROP_UNIQUE_INDEX_NO_WRITES (1L << 3) /*drop uniq. w/lock*/
-#define HA_ONLINE_ADD_PK_INDEX_NO_WRITES (1L << 4) /*add prim. w/lock*/
-#define HA_ONLINE_DROP_PK_INDEX_NO_WRITES (1L << 5) /*drop prim. w/lock*/
-/*
- These are set if different kinds of indexes can be created on-line
- (without a table lock). If a handler is capable of one or more of
- these, it should also set the corresponding *_NO_WRITES bit(s).
-*/
-#define HA_ONLINE_ADD_INDEX (1L << 6) /*add index online*/
-#define HA_ONLINE_DROP_INDEX (1L << 7) /*drop index online*/
-#define HA_ONLINE_ADD_UNIQUE_INDEX (1L << 8) /*add unique online*/
-#define HA_ONLINE_DROP_UNIQUE_INDEX (1L << 9) /*drop uniq. online*/
-#define HA_ONLINE_ADD_PK_INDEX (1L << 10)/*add prim. online*/
-#define HA_ONLINE_DROP_PK_INDEX (1L << 11)/*drop prim. online*/
-/*
HA_PARTITION_FUNCTION_SUPPORTED indicates that the function is
supported at all.
HA_FAST_CHANGE_PARTITION means that optimised variants of the changes
@@ -188,9 +224,9 @@
the storage engine. A typical engine to support this is NDB (through
WL #2498).
*/
-#define HA_PARTITION_FUNCTION_SUPPORTED (1L << 12)
-#define HA_FAST_CHANGE_PARTITION (1L << 13)
-#define HA_PARTITION_ONE_PHASE (1L << 14)
+#define HA_PARTITION_FUNCTION_SUPPORTED (1L << 1)
+#define HA_FAST_CHANGE_PARTITION (1L << 2)
+#define HA_PARTITION_ONE_PHASE (1L << 3)
/*
Index scan will not return records in rowid order. Not guaranteed to be
@@ -230,7 +266,7 @@
#define HA_BLOCK_LOCK 256 /* unlock when reading some records */
#define HA_OPEN_TEMPORARY 512
- /* Some key definitions */
+/* Some key definitions */
#define HA_KEY_NULL_LENGTH 1
#define HA_KEY_BLOB_LENGTH 2
@@ -282,12 +318,19 @@
ROW_TYPE_DYNAMIC, ROW_TYPE_COMPRESSED,
ROW_TYPE_REDUNDANT, ROW_TYPE_COMPACT, ROW_TYPE_PAGE };
+enum column_format_type { COLUMN_FORMAT_TYPE_NOT_USED= -1,
+ COLUMN_FORMAT_TYPE_DEFAULT= 0,
+ COLUMN_FORMAT_TYPE_FIXED= 1,
+ COLUMN_FORMAT_TYPE_DYNAMIC= 2 };
+
enum enum_binlog_func {
BFN_RESET_LOGS= 1,
BFN_RESET_SLAVE= 2,
BFN_BINLOG_WAIT= 3,
BFN_BINLOG_END= 4,
- BFN_BINLOG_PURGE_FILE= 5
+ BFN_BINLOG_PURGE_FILE= 5,
+ BFN_GLOBAL_SCHEMA_LOCK= 6,
+ BFN_GLOBAL_SCHEMA_UNLOCK=7
};
enum enum_binlog_command {
@@ -664,7 +707,7 @@
bool (*flush_logs)(handlerton *hton);
bool (*show_status)(handlerton *hton, THD *thd, stat_print_fn *print, enum ha_stat_type stat);
uint (*partition_flags)();
- uint (*alter_table_flags)(uint flags);
+ uint (*alter_partition_flags)();
int (*alter_tablespace)(handlerton *hton, THD *thd, st_alter_tablespace *ts_info);
int (*fill_files_table)(handlerton *hton, THD *thd,
TABLE_LIST *tables,
@@ -863,7 +906,7 @@
enum enum_tx_isolation { ISO_READ_UNCOMMITTED, ISO_READ_COMMITTED,
- ISO_REPEATABLE_READ, ISO_SERIALIZABLE};
+ ISO_REPEATABLE_READ, ISO_SERIALIZABLE};
enum ndb_distribution { ND_KEYHASH= 0, ND_LINHASH= 1 };
@@ -919,10 +962,21 @@
bool table_existed; /* 1 in create if table existed */
bool frm_only; /* 1 if no ha_create_table() */
bool varchar; /* 1 if table has a VARCHAR */
- enum ha_storage_media storage_media; /* DEFAULT, DISK or MEMORY */
+ enum ha_storage_media default_storage_media; /* DEFAULT, DISK or MEMORY */
enum ha_choice page_checksum; /* If we have page_checksums */
} HA_CREATE_INFO;
+typedef struct st_ha_alter_information
+{
+ KEY *key_info_buffer;
+ uint key_count;
+ uint index_drop_count;
+ uint *index_drop_buffer;
+ uint index_add_count;
+ uint *index_add_buffer;
+ void *data;
+} HA_ALTER_INFO;
+
typedef struct st_key_create_information
{
@@ -1026,6 +1080,7 @@
ulonglong max_index_file_length;
ulonglong delete_length; /* Free bytes */
ulonglong auto_increment_value;
+ ha_rows rows_updated, rows_deleted;
/*
The number of records in the table.
0 - means the table has exactly 0 rows
@@ -1211,7 +1266,7 @@
int ha_external_lock(THD *thd, int lock_type);
int ha_write_row(uchar * buf);
int ha_update_row(const uchar * old_data, uchar * new_data);
- int ha_delete_row(const uchar * buf);
+ int ha_delete_row(const uchar * buf, bool will_batch= FALSE);
void ha_release_auto_increment();
int check_collation_compatibility();
@@ -1330,7 +1385,15 @@
a ha_rnd_init() or ha_index_init(), write_row(), update_row or delete_row()
as there may be several calls to this routine.
*/
- virtual void column_bitmaps_signal();
+
+#define HA_CHANGE_TABLE_READ_BITMAP 1
+#define HA_CHANGE_TABLE_WRITE_BITMAP 2
+#define HA_CHANGE_TABLE_BOTH_BITMAPS 2+1
+
+#define HA_COMPLETE_TABLE_READ_BITMAP 4
+#define HA_COMPLETE_TABLE_WRITE_BITMAP 8
+#define HA_COMPLETE_TABLE_BOTH_BITMAPS 4+8
+ virtual void column_bitmaps_signal(uint sig_type);
uint get_index(void) const { return active_index; }
virtual int close(void)=0;
@@ -1460,10 +1523,20 @@
virtual int info(uint)=0; // see my_base.h for full description
virtual void get_dynamic_partition_info(PARTITION_INFO *stat_info,
uint part_id);
+ virtual uint32 calculate_key_hash_value(Field **field_array)
+ { DBUG_ASSERT(0); return 0; }
virtual int extra(enum ha_extra_function operation)
{ return 0; }
virtual int extra_opt(enum ha_extra_function operation, ulong cache_size)
{ return extra(operation); }
+ /*
+ Informs handler that it is possible to optimise away the real read
+ operation from the handler and instead use a generated read to
+ optimise simple UPDATE's and DELETE's.
+ */
+ virtual bool read_before_write_removal_possible(List<Item> *fields,
+ List<Item> *values)
+ { return FALSE; }
/**
In an UPDATE or DELETE, if the row under the cursor was locked by another
@@ -1540,8 +1613,8 @@
{ return FALSE; }
virtual char* get_foreign_key_create_info()
{ return(NULL);} /* gets foreign key create string from InnoDB */
- virtual char* get_tablespace_name(THD *thd, char *name, uint name_len)
- { return(NULL);} /* gets tablespace name from handler */
+ /* gets tablespace name from handler */
+ const char* get_tablespace_name();
/** used in ALTER TABLE; 1 if changing storage engine is allowed */
virtual bool can_switch_engines() { return 1; }
/** used in REPLACE; is > 0 if table is referred by a FOREIGN KEY */
@@ -1574,7 +1647,9 @@
*no_parts= 0;
return 0;
}
- virtual void set_part_info(partition_info *part_info) {return;}
+ virtual void set_part_info(partition_info *part_info,
+ bool early)
+ {return;}
virtual ulong index_flags(uint idx, uint part, bool all_parts) const =0;
@@ -1613,7 +1688,6 @@
#define CHF_CREATE_FLAG 0
#define CHF_DELETE_FLAG 1
#define CHF_RENAME_FLAG 2
-#define CHF_INDEX_FLAG 3
/**
@@ -1634,8 +1708,8 @@
are not attached when this is called from another thread.
*/
virtual THR_LOCK_DATA **store_lock(THD *thd,
- THR_LOCK_DATA **to,
- enum thr_lock_type lock_type)=0;
+ THR_LOCK_DATA **to,
+ enum thr_lock_type lock_type)=0;
/** Type of table for caching query */
virtual uint8 table_cache_type() { return HA_CACHE_TBL_NONTRANSACT; }
@@ -1726,22 +1800,115 @@
Pops the top if condition stack, if stack is not empty.
*/
virtual void cond_pop() { return; };
+ /*
+ Part of old fast alter table, to be depricated
+ */
virtual bool check_if_incompatible_data(HA_CREATE_INFO *create_info,
- uint table_changes)
+ uint table_changes)
{ return COMPATIBLE_DATA_NO; }
+ /* On-line ALTER TABLE interface */
+
+ /**
+ Check if a storage engine supports a particular alter table on-line
+
+ @param altered_table A temporary table show what table is to
+ change to
+ @param create_info Information from the parsing phase about new
+ table properties.
+ @param alter_flags Bitmask that shows what will be changed
+ @param table_changes Shows if table layout has changed (for
+ backwards compatibility with
+ check_if_incompatible_data
+
+ @retval HA_ALTER_ERROR Unexpected error
+ @retval HA_ALTER_SUPPORTED_WAIT_LOCK Supported, but requires DDL lock
+ @retval HA_ALTER_SUPPORTED_NO_LOCK Supported
+ @retval HA_ALTER_NOT_SUPPORTED Not supported
+
+ @note
+ The default implementation is implemented to support fast
+ alter table (storage engines that support some changes by
+ just changing the frm file) without any change in the handler
+ implementation.
+ */
+ virtual int check_if_supported_alter(TABLE *altered_table,
+ HA_CREATE_INFO *create_info,
+ HA_ALTER_FLAGS *alter_flags,
+ uint table_changes)
+ {
+ DBUG_ENTER("check_if_supported_alter");
+ if (this->check_if_incompatible_data(create_info, table_changes)
+ == COMPATIBLE_DATA_NO)
+ DBUG_RETURN(HA_ALTER_NOT_SUPPORTED);
+ else
+ DBUG_RETURN(HA_ALTER_SUPPORTED_WAIT_LOCK);
+ }
+ /**
+ Tell storage engine to prepare for the on-line alter table (pre-alter)
+
+ @param thd The thread handle
+ @param altered_table A temporary table show what table is to
+ change to
+ @param alter_info Storage place for data used during phase1
+ and phase2
+ @param alter_flags Bitmask that shows what will be changed
+
+ @retval 0 OK
+ @retval error error code passed from storage engine
+ */
+ virtual int alter_table_phase1(THD *thd,
+ TABLE *altered_table,
+ HA_CREATE_INFO *create_info,
+ HA_ALTER_INFO *alter_info,
+ HA_ALTER_FLAGS *alter_flags)
+ {
+ return HA_ERR_UNSUPPORTED;
+ }
+ /**
+ Tell storage engine to perform the on-line alter table (alter)
+
+ @param thd The thread handle
+ @param altered_table A temporary table show what table is to
+ change to
+ @param alter_info Storage place for data used during phase1
+ and phase2
+ @param alter_flags Bitmask that shows what will be changed
+
+ @retval 0 OK
+ @retval error error code passed from storage engine
+
+ @note
+ If check_if_supported_alter returns HA_ALTER_SUPPORTED_WAIT_LOCK
+ this call is to be wrapped with a DDL lock. This is currently NOT
+ supported.
+ */
+ virtual int alter_table_phase2(THD *thd,
+ TABLE *altered_table,
+ HA_CREATE_INFO *create_info,
+ HA_ALTER_INFO *alter_info,
+ HA_ALTER_FLAGS *alter_flags)
+ {
+ return HA_ERR_UNSUPPORTED;
+ }
+ /**
+ Tell storage engine that changed frm file is now on disk and table
+ has been re-opened (post-alter)
+
+ @param thd The thread handle
+ @param table The altered table, re-opened
+ */
+ virtual int alter_table_phase3(THD *thd, TABLE *table)
+ {
+ return HA_ERR_UNSUPPORTED;
+ }
+
/**
use_hidden_primary_key() is called in case of an update/delete when
(table_flags() and HA_PRIMARY_KEY_REQUIRED_FOR_DELETE) is defined
but we don't have a primary key
*/
virtual void use_hidden_primary_key();
- virtual uint alter_table_flags(uint flags)
- {
- if (ht->alter_table_flags)
- return ht->alter_table_flags(flags);
- return 0;
- }
protected:
/* Service methods for use by storage engines. */
@@ -1873,6 +2040,22 @@
DBUG_ASSERT(FALSE);
return HA_ERR_WRONG_COMMAND;
}
+ /*
+ This method is similar to delete_row, however the handler doesn't need
+ to execute the delete at this point in time. The handler can be certain
+ that another call to bulk_delete_row will occur OR a call to
+ end_bulk_delete before the set of deletes in this query is concluded.
+
+ @param record Record to delete
+
+ @retval 0 Success
+ @retval !=0 Error code
+ */
+ virtual int bulk_delete_row(const uchar *record)
+ {
+ DBUG_ASSERT(FALSE);
+ return HA_ERR_WRONG_COMMAND;
+ }
/**
This is called to delete all rows in a table
If the handler don't support this, then this function will
@@ -1928,9 +2111,6 @@
{ return HA_ERR_WRONG_COMMAND; }
};
-
- /* Some extern variables used with handlers */
-
extern const char *ha_row_type[];
extern const char *tx_isolation_names[];
extern const char *binlog_format_names[];
@@ -1938,7 +2118,7 @@
extern TYPELIB myisam_stats_method_typelib;
extern ulong total_ha, total_ha_2pc;
- /* Wrapper functions */
+/* Wrapper functions */
#define ha_commit(thd) (ha_commit_trans((thd), TRUE))
#define ha_rollback(thd) (ha_rollback_trans((thd), TRUE))
@@ -1989,7 +2169,7 @@
int ha_create_table(THD *thd, const char *path,
const char *db, const char *table_name,
HA_CREATE_INFO *create_info,
- bool update_create_info);
+ bool update_create_info);
int ha_delete_table(THD *thd, handlerton *db_type, const char *path,
const char *db, const char *alias, bool generate_warning);
@@ -2043,21 +2223,48 @@
#define trans_need_2pc(thd, all) ((total_ha_2pc > 1) && \
!((all ? &thd->transaction.all : &thd->transaction.stmt)->no_2pc))
+#ifdef WITH_NDBCLUSTER_STORAGE_ENGINE
#ifdef HAVE_NDB_BINLOG
int ha_reset_logs(THD *thd);
int ha_binlog_index_purge_file(THD *thd, const char *file);
-void ha_reset_slave(THD *thd);
+int ha_reset_slave(THD *thd);
+void ha_binlog_wait(THD *thd);
+int ha_binlog_end(THD *thd);
+#else
+inline int ha_int_dummy() { return 0; }
+#define ha_reset_logs(a) ha_int_dummy()
+#define ha_binlog_index_purge_file(a,b) ha_int_dummy()
+#define ha_reset_slave(a) ha_int_dummy()
+#define ha_binlog_wait(a) do {} while (0)
+#define ha_binlog_end(a) do {} while (0)
+#endif
void ha_binlog_log_query(THD *thd, handlerton *db_type,
enum_binlog_command binlog_command,
const char *query, uint query_length,
const char *db, const char *table_name);
-void ha_binlog_wait(THD *thd);
-int ha_binlog_end(THD *thd);
+class Ha_global_schema_lock_guard
+{
+public:
+ Ha_global_schema_lock_guard(THD *thd);
+ ~Ha_global_schema_lock_guard();
+ int lock(int no_queue= 0);
+private:
+ THD *m_thd;
+ int m_lock;
+};
#else
-#define ha_reset_logs(a) do {} while (0)
-#define ha_binlog_index_purge_file(a,b) do {} while (0)
-#define ha_reset_slave(a) do {} while (0)
+inline int ha_int_dummy() { return 0; }
+#define ha_reset_logs(a) ha_int_dummy()
+#define ha_binlog_index_purge_file(a,b) ha_int_dummy()
+#define ha_reset_slave(a) ha_int_dummy()
#define ha_binlog_log_query(a,b,c,d,e,f,g) do {} while (0)
#define ha_binlog_wait(a) do {} while (0)
#define ha_binlog_end(a) do {} while (0)
+class Ha_global_schema_lock_guard
+{
+public:
+ Ha_global_schema_lock_guard(THD *thd) {}
+ ~Ha_global_schema_lock_guard() {}
+ int lock(int no_queue= 0) { return 0; }
+};
#endif
--- 5.1.34/sql/hostname.cc 2009-06-03 23:17:32.000000000 +0200
+++ 7.0/sql/hostname.cc 2009-06-04 10:35:50.000000000 +0200
@@ -34,7 +37,6 @@
#ifdef HAVE_SYS_UN_H
#include <sys/un.h>
#endif
-#include <netdb.h>
#include <sys/utsname.h>
#endif // __WIN__
#ifdef __cplusplus
@@ -45,7 +47,7 @@
class host_entry :public hash_filo_element
{
public:
- char ip[sizeof(((struct in_addr *) 0)->s_addr)];
+ char ip[sizeof(struct sockaddr_storage)];
uint errors;
char *hostname;
};
@@ -63,7 +65,7 @@
host_entry tmp;
uint offset= (uint) ((char*) (&tmp.ip) - (char*) &tmp);
if (!(hostname_cache=new hash_filo(HOST_CACHE_SIZE, offset,
- sizeof(struct in_addr),NULL,
+ sizeof(struct sockaddr_storage),NULL,
(hash_free_key) free,
&my_charset_bin)))
return 1;
@@ -83,20 +85,20 @@
}
-static void add_hostname(struct in_addr *in,const char *name)
+static void add_hostname(struct sockaddr_storage *in,const char *name)
{
if (!(specialflag & SPECIAL_NO_HOST_CACHE))
{
VOID(pthread_mutex_lock(&hostname_cache->lock));
host_entry *entry;
- if (!(entry=(host_entry*) hostname_cache->search((uchar*) &in->s_addr,0)))
+ if (!(entry=(host_entry*) hostname_cache->search((uchar*) in,0)))
{
uint length=name ? (uint) strlen(name) : 0;
if ((entry=(host_entry*) malloc(sizeof(host_entry)+length+1)))
{
char *new_name;
- memcpy_fixed(&entry->ip, &in->s_addr, sizeof(in->s_addr));
+ memcpy_fixed(&entry->ip, in, sizeof(struct sockaddr_storage));
if (length)
memcpy(new_name= (char *) (entry+1), name, length+1);
else
@@ -111,56 +113,79 @@
}
-inline void add_wrong_ip(struct in_addr *in)
+inline void add_wrong_ip(struct sockaddr_storage *in)
{
- add_hostname(in,NullS);
+ add_hostname(in, NullS);
}
-void inc_host_errors(struct in_addr *in)
+void inc_host_errors(struct sockaddr_storage *in)
{
VOID(pthread_mutex_lock(&hostname_cache->lock));
host_entry *entry;
- if ((entry=(host_entry*) hostname_cache->search((uchar*) &in->s_addr,0)))
+ if ((entry=(host_entry*) hostname_cache->search((uchar*) in,0)))
entry->errors++;
VOID(pthread_mutex_unlock(&hostname_cache->lock));
}
-void reset_host_errors(struct in_addr *in)
+void reset_host_errors(struct sockaddr_storage *in)
{
VOID(pthread_mutex_lock(&hostname_cache->lock));
host_entry *entry;
- if ((entry=(host_entry*) hostname_cache->search((uchar*) &in->s_addr,0)))
+ if ((entry=(host_entry*) hostname_cache->search((uchar*) in,0)))
entry->errors=0;
VOID(pthread_mutex_unlock(&hostname_cache->lock));
}
-/* Deal with systems that don't defined INADDR_LOOPBACK */
-#ifndef INADDR_LOOPBACK
-#define INADDR_LOOPBACK 0x7f000001UL
-#endif
-char * ip_to_hostname(struct in_addr *in, uint *errors)
+char * ip_to_hostname(struct sockaddr_storage *in, int addrLen, uint *errors)
{
- uint i;
+ char *name= NULL;
+
+ struct addrinfo hints,*res_lst= NULL,*t_res;
+ int gxi_error;
+ char hostname_buff[NI_MAXHOST];
+
host_entry *entry;
DBUG_ENTER("ip_to_hostname");
*errors=0;
- /* We always treat the loopback address as "localhost". */
- if (in->s_addr == htonl(INADDR_LOOPBACK)) // is expanded inline by gcc
+ /* Historical comparison for 127.0.0.1 */
+ gxi_error= getnameinfo((struct sockaddr *)in, addrLen,
+ hostname_buff, NI_MAXHOST,
+ NULL, 0, NI_NUMERICHOST);
+ if (gxi_error)
+ {
+ DBUG_PRINT("error",("getnameinfo returned %d", gxi_error));
+ DBUG_RETURN(0);
+ }
+ DBUG_PRINT("info",("resolved: %s", hostname_buff));
+
+ /* The next three compares are to solve historical solutions with localhost */
+ if (!memcmp(hostname_buff, "127.0.0.1", sizeof("127.0.0.1")))
+ {
DBUG_RETURN((char *)my_localhost);
-
+ }
+ if (!memcmp(hostname_buff, "::ffff:127.0.0.1", sizeof("::ffff:127.0.0.1")))
+ {
+ DBUG_RETURN((char *)my_localhost);
+ }
+ if (!memcmp(hostname_buff, "::1", sizeof("::1")))
+ {
+ DBUG_RETURN((char *)my_localhost);
+ }
+
/* Check first if we have name in cache */
if (!(specialflag & SPECIAL_NO_HOST_CACHE))
{
VOID(pthread_mutex_lock(&hostname_cache->lock));
- if ((entry=(host_entry*) hostname_cache->search((uchar*) &in->s_addr,0)))
+ if ((entry=(host_entry*) hostname_cache->search((uchar*) in,0)))
{
- char *name;
- if (!entry->hostname)
- name=0; // Don't allow connection
- else
+ if (entry->hostname)
name=my_strdup(entry->hostname,MYF(0));
+ else
+ name= NULL;
+
+ DBUG_PRINT("info",("cached data %s", name ? name : "null" ));
*errors= entry->errors;
VOID(pthread_mutex_unlock(&hostname_cache->lock));
DBUG_RETURN(name);
@@ -168,83 +193,11 @@
VOID(pthread_mutex_unlock(&hostname_cache->lock));
}
- struct hostent *hp, *check;
- char *name;
- LINT_INIT(check);
-#if defined(HAVE_GETHOSTBYADDR_R) && defined(HAVE_SOLARIS_STYLE_GETHOST)
- char buff[GETHOSTBYADDR_BUFF_SIZE],buff2[GETHOSTBYNAME_BUFF_SIZE];
- int tmp_errno;
- struct hostent tmp_hostent, tmp_hostent2;
-#ifdef HAVE_purify
- bzero(buff,sizeof(buff)); // Bug in purify
-#endif
- if (!(hp=gethostbyaddr_r((char*) in,sizeof(*in),
- AF_INET,
- &tmp_hostent,buff,sizeof(buff),&tmp_errno)))
- {
- DBUG_PRINT("error",("gethostbyaddr_r returned %d",tmp_errno));
- return 0;
- }
- if (!(check=my_gethostbyname_r(hp->h_name,&tmp_hostent2,buff2,sizeof(buff2),
- &tmp_errno)))
- {
- DBUG_PRINT("error",("gethostbyname_r returned %d",tmp_errno));
- /*
- Don't cache responses when the DSN server is down, as otherwise
- transient DNS failure may leave any number of clients (those
- that attempted to connect during the outage) unable to connect
- indefinitely.
- */
- if (tmp_errno == HOST_NOT_FOUND || tmp_errno == NO_DATA)
- add_wrong_ip(in);
- my_gethostbyname_r_free();
- DBUG_RETURN(0);
- }
- if (!hp->h_name[0])
- {
- DBUG_PRINT("error",("Got an empty hostname"));
- add_wrong_ip(in);
- my_gethostbyname_r_free();
- DBUG_RETURN(0); // Don't allow empty hostnames
- }
- if (!(name=my_strdup(hp->h_name,MYF(0))))
- {
- my_gethostbyname_r_free();
- DBUG_RETURN(0); // out of memory
- }
- my_gethostbyname_r_free();
-#else
- VOID(pthread_mutex_lock(&LOCK_hostname));
- if (!(hp=gethostbyaddr((char*) in,sizeof(*in), AF_INET)))
- {
- VOID(pthread_mutex_unlock(&LOCK_hostname));
- DBUG_PRINT("error",("gethostbyaddr returned %d",errno));
-
- if (errno == HOST_NOT_FOUND || errno == NO_DATA)
- goto add_wrong_ip_and_return;
- /* Failure, don't cache responce */
- DBUG_RETURN(0);
- }
- if (!hp->h_name[0]) // Don't allow empty hostnames
- {
- VOID(pthread_mutex_unlock(&LOCK_hostname));
- DBUG_PRINT("error",("Got an empty hostname"));
- goto add_wrong_ip_and_return;
- }
- if (!(name=my_strdup(hp->h_name,MYF(0))))
+ if (!(name= my_strdup(hostname_buff,MYF(0))))
{
- VOID(pthread_mutex_unlock(&LOCK_hostname));
- DBUG_RETURN(0); // out of memory
- }
- check=gethostbyname(name);
- VOID(pthread_mutex_unlock(&LOCK_hostname));
- if (!check)
- {
- DBUG_PRINT("error",("gethostbyname returned %d",errno));
- my_free(name,MYF(0));
+ DBUG_PRINT("error",("out of memory"));
DBUG_RETURN(0);
}
-#endif
/* Don't accept hostnames that starts with digits because they may be
false ip:s */
@@ -255,24 +208,57 @@
if (*pos == '.')
{
DBUG_PRINT("error",("mysqld doesn't accept hostnames that starts with a number followed by a '.'"));
- my_free(name,MYF(0));
goto add_wrong_ip_and_return;
}
}
+ DBUG_PRINT("info",("resolved: %s",name));
+
+ bzero(&hints, sizeof (struct addrinfo));
+ hints.ai_flags= AI_PASSIVE;
+ hints.ai_socktype= SOCK_STREAM;
+ hints.ai_family= AF_UNSPEC;
- /* Check that 'gethostbyname' returned the used ip */
- for (i=0; check->h_addr_list[i]; i++)
+ gxi_error= getaddrinfo(hostname_buff, NULL, &hints, &res_lst);
+ if (gxi_error != 0)
{
- if (*(uint32*)(check->h_addr_list)[i] == in->s_addr)
+ /*
+ Don't cache responses when the DNS server is down, as otherwise
+ transient DNS failure may leave any number of clients (those
+ that attempted to connect during the outage) unable to connect
+ indefinitely.
+ */
+ DBUG_PRINT("error",("getaddrinfo returned %d", gxi_error));
+#ifdef EAI_NODATA
+ if (gxi_error == EAI_NODATA )
+#else
+ if (gxi_error == EAI_NONAME )
+#endif
+ add_wrong_ip(in);
+
+ if (res_lst)
+ freeaddrinfo(res_lst);
+
+ my_free(name, MYF(0));
+ DBUG_RETURN(0);
+ }
+
+ /* Check that 'getaddrinfo' returned the used ip */
+ for (t_res= res_lst; t_res; t_res=t_res->ai_next)
+ {
+ if (!memcmp(&(t_res->ai_addr), in,
+ sizeof(struct sockaddr_storage) ) )
{
add_hostname(in,name);
+ freeaddrinfo(res_lst);
DBUG_RETURN(name);
}
}
- DBUG_PRINT("error",("Couldn't verify hostname with gethostbyname"));
- my_free(name,MYF(0));
+
+ freeaddrinfo(res_lst);
+ DBUG_PRINT("error",("Couldn't verify hostname with getaddrinfo"));
add_wrong_ip_and_return:
+ my_free(name,MYF(0));
add_wrong_ip(in);
DBUG_RETURN(0);
}
--- 5.1.34/sql/item_func.cc 2009-06-03 23:17:47.000000000 +0200
+++ 7.0/sql/item_func.cc 2009-06-04 10:35:50.000000000 +0200
@@ -4024,6 +4027,8 @@
case ROW_RESULT:
DBUG_ASSERT(1); // Impossible
break;
+ default:
+ break;
}
return 0.0; // Impossible
}
@@ -4055,6 +4060,8 @@
case ROW_RESULT:
DBUG_ASSERT(1); // Impossible
break;
+ default:
+ break;
}
return LL(0); // Impossible
}
@@ -4087,6 +4094,8 @@
case ROW_RESULT:
DBUG_ASSERT(1); // Impossible
break;
+ default:
+ break;
}
return(str);
}
@@ -4114,6 +4123,8 @@
case ROW_RESULT:
DBUG_ASSERT(1); // Impossible
break;
+ default:
+ break;
}
return(val);
}
--- 5.1.34/sql/lex.h 2009-06-03 23:17:32.000000000 +0200
+++ 7.0/sql/lex.h 2009-06-04 10:35:50.000000000 +0200
@@ -203,6 +206,7 @@
{ "FAST", SYM(FAST_SYM)},
{ "FAULTS", SYM(FAULTS_SYM)},
{ "FETCH", SYM(FETCH_SYM)},
+ { "COLUMN_FORMAT", SYM(COLUMN_FORMAT_SYM)},
{ "FIELDS", SYM(COLUMNS)},
{ "FILE", SYM(FILE_SYM)},
{ "FIRST", SYM(FIRST_SYM)},
@@ -307,6 +311,7 @@
{ "MASTER", SYM(MASTER_SYM)},
{ "MASTER_CONNECT_RETRY", SYM(MASTER_CONNECT_RETRY_SYM)},
{ "MASTER_HOST", SYM(MASTER_HOST_SYM)},
+ { "MASTER_BIND", SYM(MASTER_BIND_SYM)},
{ "MASTER_LOG_FILE", SYM(MASTER_LOG_FILE_SYM)},
{ "MASTER_LOG_POS", SYM(MASTER_LOG_POS_SYM)},
{ "MASTER_PASSWORD", SYM(MASTER_PASSWORD_SYM)},
@@ -320,6 +325,7 @@
{ "MASTER_SSL_KEY", SYM(MASTER_SSL_KEY_SYM)},
{ "MASTER_SSL_VERIFY_SERVER_CERT", SYM(MASTER_SSL_VERIFY_SERVER_CERT_SYM)},
{ "MASTER_USER", SYM(MASTER_USER_SYM)},
+ { "MASTER_HEARTBEAT_PERIOD", SYM(MASTER_HEARTBEAT_PERIOD_SYM)},
{ "MATCH", SYM(MATCH)},
{ "MAX_CONNECTIONS_PER_HOUR", SYM(MAX_CONNECTIONS_PER_HOUR)},
{ "MAX_QUERIES_PER_HOUR", SYM(MAX_QUERIES_PER_HOUR)},
@@ -368,10 +374,12 @@
{ "NULL", SYM(NULL_SYM)},
{ "NUMERIC", SYM(NUMERIC_SYM)},
{ "NVARCHAR", SYM(NVARCHAR_SYM)},
+ { "OFFLINE", SYM(OFFLINE_SYM)},
{ "OFFSET", SYM(OFFSET_SYM)},
{ "OLD_PASSWORD", SYM(OLD_PASSWORD)},
{ "ON", SYM(ON)},
{ "ONE", SYM(ONE_SYM)},
+ { "ONLINE", SYM(ONLINE_SYM)},
{ "ONE_SHOT", SYM(ONE_SHOT_SYM)},
{ "OPEN", SYM(OPEN_SYM)},
{ "OPTIMIZE", SYM(OPTIMIZE)},
--- 5.1.34/sql/log.cc 2009-06-03 23:17:47.000000000 +0200
+++ 7.0/sql/log.cc 2009-06-04 10:35:50.000000000 +0200
@@ -2765,7 +2768,11 @@
const char* save_name;
DBUG_ENTER("reset_logs");
- ha_reset_logs(thd);
+ if (ha_reset_logs(thd))
+ {
+ DBUG_RETURN(1);
+ }
+
/*
We need to get both locks to be sure that no one is trying to
write to the index log file.
@@ -4461,17 +4468,14 @@
THD::enter_cond() (see NOTES in sql_class.h).
*/
-void MYSQL_BIN_LOG::wait_for_update(THD* thd, bool is_slave)
+void MYSQL_BIN_LOG::wait_for_update_relay_log(THD* thd)
{
const char *old_msg;
DBUG_ENTER("wait_for_update");
-
old_msg= thd->enter_cond(&update_cond, &LOCK_log,
- is_slave ?
- "Has read all relay log; waiting for the slave I/O "
- "thread to update it" :
- "Has sent all binlog to slave; waiting for binlog "
- "to be updated");
+ "Slave has read all relay log; "
+ "waiting for the slave I/O "
+ "thread to update it" );
pthread_cond_wait(&update_cond, &LOCK_log);
thd->exit_cond(old_msg);
DBUG_VOID_RETURN;
@@ -4479,6 +4483,40 @@
/**
+ Wait until we get a signal that the binary log has been updated.
+ Applies to master only.
+
+ NOTES
+ @param[in] thd a THD struct
+ @param[in] timeout a pointer to a timespec;
+ NULL means to wait w/o timeout.
+ @retval 0 if got signalled on update
+ @retval non-0 if wait timeout elapsed
+ @note
+ LOCK_log must be taken before calling this function.
+ LOCK_log is being released while the thread is waiting.
+ LOCK_log is released by the caller.
+*/
+
+int MYSQL_BIN_LOG::wait_for_update_bin_log(THD* thd,
+ const struct timespec *timeout)
+{
+ int ret= 0;
+ const char* old_msg = thd->proc_info;
+ DBUG_ENTER("wait_for_update_bin_log");
+ old_msg= thd->enter_cond(&update_cond, &LOCK_log,
+ "Master has sent all binlog to slave; "
+ "waiting for binlog to be updated");
+ if (!timeout)
+ pthread_cond_wait(&update_cond, &LOCK_log);
+ else
+ ret= pthread_cond_timedwait(&update_cond, &LOCK_log,
+ const_cast<struct timespec *>(timeout));
+ DBUG_RETURN(ret);
+}
+
+
+/**
Close the log file.
@param exiting Bitmask for one or more of the following bits:
--- 5.1.34/sql/log_event.cc 2009-06-03 23:17:46.000000000 +0200
+++ 7.0/sql/log_event.cc 2009-06-04 10:35:50.000000000 +0200
@@ -3516,6 +3519,7 @@
post_header_len[UPDATE_ROWS_EVENT-1]=
post_header_len[DELETE_ROWS_EVENT-1]= 6;);
post_header_len[INCIDENT_EVENT-1]= INCIDENT_HEADER_LEN;
+ post_header_len[HEARTBEAT_LOG_EVENT-1]= 0;
// Sanity-check that all post header lengths are initialized.
IF_DBUG({
@@ -7239,6 +7243,28 @@
So we call set_time(), like in SBR. Presently it changes nothing.
*/
thd->set_time((time_t)when);
+ /*
+ There are a few flags that are replicated with each row event.
+ Make sure to set/clear them before executing the main body of
+ the event.
+ */
+ if (get_flags(NO_FOREIGN_KEY_CHECKS_F))
+ thd->options|= OPTION_NO_FOREIGN_KEY_CHECKS;
+ else
+ thd->options&= ~OPTION_NO_FOREIGN_KEY_CHECKS;
+
+ if (get_flags(RELAXED_UNIQUE_CHECKS_F))
+ thd->options|= OPTION_RELAXED_UNIQUE_CHECKS;
+ else
+ thd->options&= ~OPTION_RELAXED_UNIQUE_CHECKS;
+
+ if (slave_allow_batching)
+ thd->options|= OPTION_ALLOW_BATCH;
+ else
+ thd->options&= ~OPTION_ALLOW_BATCH;
+
+ /* A small test to verify that objects have consistent types */
+ DBUG_ASSERT(sizeof(thd->options) == sizeof(OPTION_RELAXED_UNIQUE_CHECKS));
/*
Now we are in a statement and will stay in a statement until we
@@ -7373,6 +7399,8 @@
*/
if (rli->tables_to_lock && get_flags(STMT_END_F))
const_cast<Relay_log_info*>(rli)->clear_tables_to_lock();
+ /* reset OPTION_ALLOW_BATCH as not affect later events */
+ thd->options&= ~OPTION_ALLOW_BATCH;
if (error)
{ /* error has occured during the transaction */
@@ -8699,6 +8727,22 @@
table->s->reclength) == 0);
*/
+
+ /*
+ Ndb does not need read before delete/update (and no updates are sent)
+ if primary key specified
+
+ (Actually uniquekey will also do, but pk will be in each
+ row if table has pk)
+
+ Also set ignore no key, as we don't really know if row exists...
+ */
+ if (table->file->ht->db_type == DB_TYPE_NDBCLUSTER)
+ {
+ table->file->extra(HA_EXTRA_IGNORE_NO_KEY);
+ DBUG_RETURN(0);
+ }
+
DBUG_PRINT("info",("locating record using primary key (position)"));
int error= table->file->rnd_pos_by_record(table->record[0]);
if (error)
@@ -9282,6 +9326,18 @@
DBUG_RETURN(write_str(file, m_message.str, (uint) m_message.length));
}
+#if defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT)
+Heartbeat_log_event::Heartbeat_log_event(const char* buf, uint event_len,
+ const Format_description_log_event* description_event)
+ :Log_event(buf, description_event)
+{
+ uint8 header_size= description_event->common_header_len;
+ ident_len = event_len - header_size;
+ set_if_smaller(ident_len,FN_REFLEN-1);
+ log_ident= buf + header_size;
+}
+#endif
+
#ifdef MYSQL_CLIENT
/**
--- 5.1.34/sql/log_event.h 2009-06-03 23:17:32.000000000 +0200
+++ 7.0/sql/log_event.h 2009-06-04 10:35:50.000000000 +0200
@@ -250,6 +253,7 @@
#define EXECUTE_LOAD_QUERY_EXTRA_HEADER_LEN (4 + 4 + 4 + 1)
#define EXECUTE_LOAD_QUERY_HEADER_LEN (QUERY_HEADER_LEN + EXECUTE_LOAD_QUERY_EXTRA_HEADER_LEN)
#define INCIDENT_HEADER_LEN 2
+#define HEARTBEAT_HEADER_LEN 0
/*
Max number of possible extra bytes in a replication event compared to a
packet (i.e. a query) sent from client to master;
@@ -575,6 +579,12 @@
INCIDENT_EVENT= 26,
/*
+ Heartbeat event to be send by master at its idle time
+ to ensure master's online status to slave
+ */
+ HEARTBEAT_LOG_EVENT= 27,
+
+ /*
Add new events here - right above this comment!
Existing events (except ENUM_END_EVENT) should never change their numbers
*/
@@ -688,6 +698,20 @@
} PRINT_EVENT_INFO;
#endif
+/**
+ the struct aggregates two paramenters that identify an event
+ uniquely in scope of communication of a particular master and slave couple.
+ I.e there can not be 2 events from the same staying connected master which
+ have the same coordinates.
+ @note
+ Such identifier is not yet unique generally as the event originating master
+ is resetable. Also the crashed master can be replaced with some other.
+*/
+struct event_coordinates
+{
+ char * file_name; // binlog file name (directories stripped)
+ my_off_t pos; // event's position in the binlog file
+};
/**
@class Log_event
@@ -1732,6 +1756,7 @@
int master_host_len;
int master_log_len;
uint16 master_port;
+ /* TODO add mysql_bind_addr here ? */
#ifndef MYSQL_CLIENT
Slave_log_event(THD* thd_arg, Relay_log_info* rli);
@@ -3917,6 +3942,42 @@
reinit_io_cache(cache, WRITE_CACHE, 0, FALSE, TRUE);
}
+#ifndef MYSQL_CLIENT
+/*****************************************************************************
+
+ Heartbeat Log Event class
+
+ Replication event to ensure to slave that master is alive.
+ The event is originated by master's dump thread and sent straight to
+ slave without being logged. Slave itself does not store it in relay log
+ but rather uses a data for immediate checks and throws away the event.
+
+ Two members of the class log_ident and Log_event::log_pos comprise
+ @see the event_coordinates instance. The coordinates that a heartbeat
+ instance carries correspond to the last event master has sent from
+ its binlog.
+
+ ****************************************************************************/
+class Heartbeat_log_event: public Log_event
+{
+public:
+ Heartbeat_log_event(const char* buf, uint event_len,
+ const Format_description_log_event* description_event);
+ Log_event_type get_type_code() { return HEARTBEAT_LOG_EVENT; }
+ bool is_valid() const
+ {
+ return (log_ident != NULL &&
+ log_pos >= BIN_LOG_HEADER_SIZE);
+ }
+ const char * get_log_ident() { return log_ident; }
+ uint get_ident_len() { return ident_len; }
+
+private:
+ const char* log_ident;
+ uint ident_len;
+};
+#endif
+
/**
@} (end of group Replication)
*/
--- 5.1.34/sql/mysql_priv.h 2009-06-03 23:17:47.000000000 +0200
+++ 7.0/sql/mysql_priv.h 2009-06-04 10:35:50.000000000 +0200
@@ -254,6 +257,18 @@
CHARSET_INFO *m_connection_cl;
};
+
+/**
+ Opening modes for open_temporary_table and open_table_from_share
+*/
+
+enum open_table_mode
+{
+ OTM_OPEN= 0,
+ OTM_CREATE= 1,
+ OTM_ALTER= 2
+};
+
/***************************************************************************
Configuration parameters
****************************************************************************/
@@ -478,7 +493,11 @@
#define TMP_TABLE_FORCE_MYISAM (ULL(1) << 32)
#define OPTION_PROFILING (ULL(1) << 33)
-
+/*
+ Dont report errors for individual rows,
+ But just report error on commit (or read ofcourse)
+*/
+#define OPTION_ALLOW_BATCH (ULL(1) << 33) // THD, intern (slave)
/**
Maximum length of time zone name that we support
@@ -1143,6 +1162,9 @@
void set_key_field_ptr(KEY *key_info, const uchar *new_buf,
const uchar *old_buf);
+void include_partition_fields_in_used_fields(Field **ptr,
+ MY_BITMAP *read_set);
+
bool mysql_backup_table(THD* thd, TABLE_LIST* table_list);
bool mysql_restore_table(THD* thd, TABLE_LIST* table_list);
@@ -1434,6 +1456,8 @@
bool add_field_to_list(THD *thd, LEX_STRING *field_name, enum enum_field_types type,
char *length, char *decimal,
uint type_modifier,
+ enum ha_storage_media storage_type,
+ enum column_format_type column_format,
Item *default_value, Item *on_update_value,
LEX_STRING *comment,
char *change, List<String> *interval_list,
@@ -1556,8 +1580,9 @@
int lock_tables(THD *thd, TABLE_LIST *tables, uint counter, bool *need_reopen);
int decide_logging_format(THD *thd, TABLE_LIST *tables);
TABLE *open_temporary_table(THD *thd, const char *path, const char *db,
- const char *table_name, bool link_in_list);
-bool rm_temporary_table(handlerton *base, char *path);
+ const char *table_name, bool link_in_list,
+ open_table_mode open_mode);
+bool rm_temporary_table(handlerton *base, char *path, bool frm_only);
void free_io_cache(TABLE *entry);
void intern_close_table(TABLE *entry);
bool close_thread_table(THD *thd, TABLE **table_ptr);
@@ -1742,6 +1767,7 @@
LEX_STRING *connect_string,
bool have_lock = FALSE);
void copy_field_from_tmp_record(Field *field,int offset);
+bool check_constant_expressions(List<Item> *values);
bool fill_record(THD *thd, Field **field, List<Item> &values,
bool ignore_errors);
bool fill_record_n_invoke_before_triggers(THD *thd, List<Item> &fields,
@@ -1804,7 +1830,7 @@
int find_ref_key(KEY *key, uint key_count, uchar *record, Field *field,
uint *key_length, uint *keypart);
void key_copy(uchar *to_key, uchar *from_record, KEY *key_info, uint key_length);
-void key_restore(uchar *to_record, uchar *from_key, KEY *key_info,
+void key_restore(uchar *to_record, uchar *from_key, const KEY *key_info,
uint key_length);
bool key_cmp_if_same(TABLE *form,const uchar *key,uint index,uint key_length);
void key_unpack(String *to,TABLE *form,uint index);
@@ -1925,6 +1951,7 @@
extern ulong slow_launch_threads, slow_launch_time;
extern ulong table_cache_size, table_def_size;
extern ulong max_connections,max_connect_errors, connect_timeout;
+extern my_bool slave_allow_batching;
extern ulong slave_net_timeout, slave_trans_retries;
extern uint max_user_connections;
extern ulong what_to_log,flush_time;
@@ -2153,7 +2180,7 @@
void open_table_error(TABLE_SHARE *share, int error, int db_errno, int errarg);
int open_table_from_share(THD *thd, TABLE_SHARE *share, const char *alias,
uint db_stat, uint prgflag, uint ha_open_flags,
- TABLE *outparam, bool is_create_table);
+ TABLE *outparam, open_table_mode open_mode);
int readfrm(const char *name, uchar **data, size_t *length);
int writefrm(const char* name, const uchar* data, size_t len);
int closefrm(TABLE *table, bool free_share);
@@ -2272,9 +2299,9 @@
/* from hostname.cc */
struct in_addr;
-char * ip_to_hostname(struct in_addr *in,uint *errors);
-void inc_host_errors(struct in_addr *in);
-void reset_host_errors(struct in_addr *in);
+char * ip_to_hostname(struct sockaddr_storage *in, int addrLen, uint *errors);
+void inc_host_errors(struct sockaddr_storage *in);
+void reset_host_errors(struct sockaddr_storage *in);
bool hostname_cache_init();
void hostname_cache_free();
void hostname_cache_refresh(void);
--- 5.1.34/sql/mysqld.cc 2009-06-03 23:17:32.000000000 +0200
+++ 7.0/sql/mysqld.cc 2009-06-04 10:35:50.000000000 +0200
@@ -106,7 +109,6 @@
#ifdef HAVE_SYS_UN_H
# include <sys/un.h>
#endif
-#include <netdb.h>
#ifdef HAVE_SELECT_H
# include <select.h>
#endif
@@ -380,7 +382,6 @@
static uint kill_cached_threads, wake_thread;
static ulong killed_threads, thread_created;
static ulong max_used_connections;
-static ulong my_bind_addr; /**< the address we bind to */
static volatile ulong cached_thread_count= 0;
static const char *sql_mode_str= "OFF";
/* Text representation for OPTIMIZER_SWITCH_DEFAULT */
@@ -442,20 +443,24 @@
handlerton *partition_hton;
#ifdef WITH_NDBCLUSTER_STORAGE_ENGINE
-const char *opt_ndbcluster_connectstring= 0;
-const char *opt_ndb_connectstring= 0;
-char opt_ndb_constrbuf[1024]= {0};
-unsigned opt_ndb_constrbuf_len= 0;
-my_bool opt_ndb_shm, opt_ndb_optimized_node_selection;
-ulong opt_ndb_cache_check_time;
-const char *opt_ndb_mgmd;
-ulong opt_ndb_nodeid;
+ulong opt_ndb_cache_check_time, opt_ndb_wait_connected;
+ulong opt_ndb_cluster_connection_pool;
ulong ndb_extra_logging;
-#ifdef HAVE_NDB_BINLOG
-ulong ndb_report_thresh_binlog_epoch_slip;
-ulong ndb_report_thresh_binlog_mem_usage;
-#endif
-
+ulong ndb_report_thresh_binlog_epoch_slip= 0;
+ulong ndb_report_thresh_binlog_mem_usage= 0;
+my_bool ndb_log_binlog_index= FALSE;
+my_bool opt_ndb_log_update_as_write= FALSE;
+my_bool opt_ndb_log_updated_only= FALSE;
+my_bool opt_ndb_log_orig= FALSE;
+my_bool opt_ndb_log_bin= FALSE;
+my_bool opt_ndb_log_empty_epochs= FALSE;
+
+extern "C" char opt_ndb_constrbuf[1024];
+extern "C" my_bool opt_ndb_shm;
+extern "C" const char *opt_ndb_connectstring;
+extern "C" unsigned opt_ndb_constrbuf_len;
+extern "C" const char *opt_ndb_mgmd;
+extern "C" ulong opt_ndb_nodeid;
extern const char *ndb_distribution_names[];
extern TYPELIB ndb_distribution_typelib;
extern const char *opt_ndb_distribution;
@@ -506,6 +511,7 @@
ulong slave_net_timeout, slave_trans_retries;
ulong slave_exec_mode_options;
const char *slave_exec_mode_str= "STRICT";
+my_bool slave_allow_batching;
ulong thread_cache_size=0, thread_pool_size= 0;
ulong binlog_cache_size=0, max_binlog_cache_size=0;
ulong query_cache_size=0;
@@ -859,11 +865,11 @@
DBUG_PRINT("quit",("Closing sockets"));
if (!opt_disable_networking )
{
- if (ip_sock != INVALID_SOCKET)
+ if (my_socket_valid(ip_sock))
{
- (void) shutdown(ip_sock, SHUT_RDWR);
- (void) closesocket(ip_sock);
- ip_sock= INVALID_SOCKET;
+ (void) my_shutdown(ip_sock, SHUT_RDWR);
+ (void) my_socket_close(ip_sock);
+ my_socket_invalidate(&ip_sock);
}
}
#ifdef __NT__
@@ -891,12 +897,12 @@
}
#endif
#ifdef HAVE_SYS_UN_H
- if (unix_sock != INVALID_SOCKET)
+ if (my_socket_valid(unix_sock))
{
- (void) shutdown(unix_sock, SHUT_RDWR);
- (void) closesocket(unix_sock);
+ (void) my_shutdown(unix_sock, SHUT_RDWR);
+ (void) my_socket_close(unix_sock);
(void) unlink(mysqld_unix_port);
- unix_sock= INVALID_SOCKET;
+ my_socket_invalidate(&unix_sock);
}
#endif
end_thr_alarm(0); // Abort old alarms.
@@ -993,33 +999,33 @@
DBUG_ENTER("close_server_sock");
my_socket tmp_sock;
tmp_sock=ip_sock;
- if (tmp_sock != INVALID_SOCKET)
+ if (my_socket_valid(tmp_sock))
{
- ip_sock=INVALID_SOCKET;
+ my_socket_invalidate(&ip_sock);
DBUG_PRINT("info",("calling shutdown on TCP/IP socket"));
- VOID(shutdown(tmp_sock, SHUT_RDWR));
+ VOID(my_shutdown(tmp_sock, SHUT_RDWR));
#if defined(__NETWARE__)
/*
The following code is disabled for normal systems as it causes MySQL
to hang on AIX 4.3 during shutdown
*/
DBUG_PRINT("info",("calling closesocket on TCP/IP socket"));
- VOID(closesocket(tmp_sock));
+ VOID(my_socket_close(tmp_sock));
#endif
}
tmp_sock=unix_sock;
- if (tmp_sock != INVALID_SOCKET)
+ if (my_socket_valid(tmp_sock))
{
- unix_sock=INVALID_SOCKET;
+ my_socket_invalidate(&unix_sock);
DBUG_PRINT("info",("calling shutdown on unix socket"));
- VOID(shutdown(tmp_sock, SHUT_RDWR));
+ VOID(my_shutdown(tmp_sock, SHUT_RDWR));
#if defined(__NETWARE__)
/*
The following code is disabled for normal systems as it may cause MySQL
to hang on AIX 4.3 during shutdown
*/
DBUG_PRINT("info",("calling closesocket on unix/IP socket"));
- VOID(closesocket(tmp_sock));
+ VOID(my_socket_close(tmp_sock));
#endif
VOID(unlink(mysqld_unix_port));
}
@@ -1583,15 +1589,14 @@
static void network_init(void)
{
- struct sockaddr_in IPaddr;
#ifdef HAVE_SYS_UN_H
struct sockaddr_un UNIXaddr;
#endif
- int arg=1;
int ret;
uint waited;
uint this_wait;
uint retry;
+ char port_buf[NI_MAXSERV];
DBUG_ENTER("network_init");
LINT_INIT(ret);
@@ -1602,26 +1607,61 @@
if (mysqld_port != 0 && !opt_disable_networking && !opt_bootstrap)
{
+ struct addrinfo *addrlist, *addr;
+ struct addrinfo hints;
+ int error;
DBUG_PRINT("general",("IP Socket is %d",mysqld_port));
- ip_sock = socket(AF_INET, SOCK_STREAM, 0);
- if (ip_sock == INVALID_SOCKET)
+
+ bzero(&hints, sizeof (hints));
+ hints.ai_flags = AI_PASSIVE;
+ hints.ai_socktype = SOCK_STREAM;
+ hints.ai_family= AF_UNSPEC;
+
+ my_snprintf(port_buf, NI_MAXSERV, "%d", mysqld_port);
+ error= getaddrinfo(my_bind_addr_str, port_buf, &hints, &addrlist);
+ if (error != 0)
+ {
+ DBUG_PRINT("error",("Got error: %d from getaddrinfo()", error));
+ sql_perror(ER(ER_IPSOCK_ERROR)); /* purecov: tested */
+ unireg_abort(1); /* purecov: tested */
+ }
+
+ for (addr = addrlist; addr != NULL; addr = addr->ai_next)
+ {
+ ip_sock= my_socket_create(addr->ai_family, addr->ai_socktype,
+ addr->ai_protocol);
+ if (my_socket_valid(ip_sock))
+ break;
+ }
+
+ if (!my_socket_valid(ip_sock))
{
DBUG_PRINT("error",("Got error: %d from socket()",socket_errno));
sql_perror(ER(ER_IPSOCK_ERROR)); /* purecov: tested */
unireg_abort(1); /* purecov: tested */
}
- bzero((char*) &IPaddr, sizeof(IPaddr));
- IPaddr.sin_family = AF_INET;
- IPaddr.sin_addr.s_addr = my_bind_addr;
- IPaddr.sin_port = (unsigned short) htons((unsigned short) mysqld_port);
#ifndef __WIN__
/*
We should not use SO_REUSEADDR on windows as this would enable a
user to open two mysqld servers with the same TCP/IP port.
*/
- (void) setsockopt(ip_sock,SOL_SOCKET,SO_REUSEADDR,(char*)&arg,sizeof(arg));
+ my_socket_reuseaddr(ip_sock, true);
#endif /* __WIN__ */
+#ifdef IPV6_V6ONLY
+ /*
+ For interoperability with older clients, IPv6 socket should
+ listen on both IPv6 and IPv4 wildcard addresses.
+ Turn off IPV6_V6ONLY option.
+ */
+ if (addr->ai_family == AF_INET6)
+ {
+ int enable= 0;
+ DBUG_PRINT("info",("Clearing IPV6_ONLY socket option"));
+ my_setsockopt(ip_sock, IPPROTO_IPV6, IPV6_V6ONLY,
+ &enable, sizeof(enable));
+ }
+#endif
/*
Sometimes the port is not released fast enough when stopping and
restarting the server. This happens quite often with the test suite
@@ -1632,8 +1672,7 @@
*/
for (waited= 0, retry= 1; ; retry++, waited+= this_wait)
{
- if (((ret= bind(ip_sock, my_reinterpret_cast(struct sockaddr *) (&IPaddr),
- sizeof(IPaddr))) >= 0) ||
+ if (((ret= my_bind(ip_sock, addr->ai_addr, addr->ai_addrlen)) >= 0 ) ||
(socket_errno != SOCKET_EADDRINUSE) ||
(waited >= mysqld_port_timeout))
break;
@@ -1641,6 +1680,7 @@
this_wait= retry * retry / 3 + 1;
sleep(this_wait);
}
+ freeaddrinfo(addrlist);
if (ret < 0)
{
DBUG_PRINT("error",("Got error: %d from bind",socket_errno));
@@ -1648,7 +1688,7 @@
sql_print_error("Do you already have another mysqld server running on port: %d ?",mysqld_port);
unireg_abort(1);
}
- if (listen(ip_sock,(int) back_log) < 0)
+ if (my_listen(ip_sock,(int) back_log) < 0)
{
sql_perror("Can't start server: listen() on TCP/IP port");
sql_print_error("listen() on TCP/IP failed with error %d",
@@ -1720,7 +1760,8 @@
(uint) sizeof(UNIXaddr.sun_path) - 1, mysqld_unix_port);
unireg_abort(1);
}
- if ((unix_sock= socket(AF_UNIX, SOCK_STREAM, 0)) < 0)
+ unix_sock= my_socket_create(AF_UNIX, SOCK_STREAM, 0);
+ if (!my_socket_valid(unix_sock))
{
sql_perror("Can't start server : UNIX Socket "); /* purecov: inspected */
unireg_abort(1); /* purecov: inspected */
@@ -1729,10 +1770,9 @@
UNIXaddr.sun_family = AF_UNIX;
strmov(UNIXaddr.sun_path, mysqld_unix_port);
(void) unlink(mysqld_unix_port);
- (void) setsockopt(unix_sock,SOL_SOCKET,SO_REUSEADDR,(char*)&arg,
- sizeof(arg));
+ my_socket_reuseaddr(unix_sock, true);
umask(0);
- if (bind(unix_sock, my_reinterpret_cast(struct sockaddr *) (&UNIXaddr),
+ if (my_bind(unix_sock, my_reinterpret_cast(struct sockaddr *) (&UNIXaddr),
sizeof(UNIXaddr)) < 0)
{
sql_perror("Can't start server : Bind on unix socket"); /* purecov: tested */
@@ -1743,7 +1783,7 @@
#if defined(S_IFSOCK) && defined(SECURE_SOCKETS)
(void) chmod(mysqld_unix_port,S_IFSOCK); /* Fix solaris 2.6 bug */
#endif
- if (listen(unix_sock,(int) back_log) < 0)
+ if (my_listen(unix_sock,(int) back_log) < 0)
sql_print_warning("listen() on Unix socket failed with error %d",
socket_errno);
}
@@ -3814,12 +3854,12 @@
}
else
{
- global_system_variables.binlog_format= BINLOG_FORMAT_STMT;
+ global_system_variables.binlog_format= BINLOG_FORMAT_MIXED;
}
}
else
if (opt_binlog_format_id == BINLOG_FORMAT_UNSPEC)
- global_system_variables.binlog_format= BINLOG_FORMAT_STMT;
+ global_system_variables.binlog_format= BINLOG_FORMAT_MIXED;
else
{
DBUG_ASSERT(global_system_variables.binlog_format != BINLOG_FORMAT_UNSPEC);
@@ -4391,7 +4431,7 @@
if (!opt_bootstrap)
(void) my_delete(pidfile_name,MYF(MY_WME)); // Not needed anymore
- if (unix_sock != INVALID_SOCKET)
+ if (my_socket_valid(unix_sock))
unlink(mysqld_unix_port);
exit(1);
}
@@ -4442,7 +4482,7 @@
unireg_abort(1);
sql_print_information(ER(ER_STARTUP),my_progname,server_version,
- ((unix_sock == INVALID_SOCKET) ? (char*) ""
+ ((!my_socket_valid(unix_sock)) ? (char*) ""
: mysqld_unix_port),
mysqld_port,
MYSQL_COMPILATION_COMMENT);
@@ -4911,9 +4951,9 @@
/* hack to get around signals ignored in syscalls for problem OS's */
if (
#if !defined(__NETWARE__)
- unix_sock == INVALID_SOCKET ||
+ !my_socket_valid(unix_sock) ||
#endif
- (!opt_disable_networking && ip_sock == INVALID_SOCKET))
+ (!opt_disable_networking && !my_socket_valid(ip_sock)))
{
select_thread_in_use = 0;
/* The following call will never return */
@@ -4932,31 +4972,27 @@
{
my_socket sock,new_sock;
uint error_count=0;
- uint max_used_connection= (uint) (max(ip_sock,unix_sock)+1);
+ int max_used_connection= 0;
fd_set readFDs,clientFDs;
THD *thd;
- struct sockaddr_in cAddr;
- int ip_flags=0,socket_flags=0,flags;
+ struct sockaddr_storage cAddr;
st_vio *vio_tmp;
DBUG_ENTER("handle_connections_sockets");
- LINT_INIT(new_sock);
+ my_socket_invalidate(&new_sock);
+
+ max_used_connection= my_socket_nfds(ip_sock, max_used_connection);
+ max_used_connection= my_socket_nfds(unix_sock, max_used_connection);
(void) my_pthread_getprio(pthread_self()); // For debugging
FD_ZERO(&clientFDs);
- if (ip_sock != INVALID_SOCKET)
+ if (my_socket_valid(ip_sock))
{
- FD_SET(ip_sock,&clientFDs);
-#ifdef HAVE_FCNTL
- ip_flags = fcntl(ip_sock, F_GETFL, 0);
-#endif
+ my_FD_SET(ip_sock,&clientFDs);
}
#ifdef HAVE_SYS_UN_H
- FD_SET(unix_sock,&clientFDs);
-#ifdef HAVE_FCNTL
- socket_flags=fcntl(unix_sock, F_GETFL, 0);
-#endif
+ my_FD_SET(unix_sock,&clientFDs);
#endif
DBUG_PRINT("general",("Waiting for connections."));
@@ -4965,10 +5001,10 @@
{
readFDs=clientFDs;
#ifdef HPUX10
- if (select(max_used_connection,(int*) &readFDs,0,0,0) < 0)
+ if (select(max_used_connection+1,(int*) &readFDs,0,0,0) < 0)
continue;
#else
- if (select((int) max_used_connection,&readFDs,0,0,0) < 0)
+ if (select((int) max_used_connection+1,&readFDs,0,0,0) < 0)
{
if (socket_errno != SOCKET_EINTR)
{
@@ -4987,41 +5023,35 @@
/* Is this a new connection request ? */
#ifdef HAVE_SYS_UN_H
- if (FD_ISSET(unix_sock,&readFDs))
+ if (my_FD_ISSET(unix_sock,&readFDs))
{
sock = unix_sock;
- flags= socket_flags;
}
else
#endif
{
sock = ip_sock;
- flags= ip_flags;
}
#if !defined(NO_FCNTL_NONBLOCK)
if (!(test_flags & TEST_BLOCKING))
{
-#if defined(O_NONBLOCK)
- fcntl(sock, F_SETFL, flags | O_NONBLOCK);
-#elif defined(O_NDELAY)
- fcntl(sock, F_SETFL, flags | O_NDELAY);
-#endif
+ my_socket_nonblock(sock, true);
}
#endif /* NO_FCNTL_NONBLOCK */
for (uint retry=0; retry < MAX_ACCEPT_RETRY; retry++)
{
- size_socket length=sizeof(struct sockaddr_in);
- new_sock = accept(sock, my_reinterpret_cast(struct sockaddr *) (&cAddr),
- &length);
+ size_socket length=sizeof(struct sockaddr_storage);
+ new_sock= my_accept(sock, my_reinterpret_cast(struct sockaddr *) (&cAddr),
+ &length);
#ifdef __NETWARE__
// TODO: temporary fix, waiting for TCP/IP fix - DEFECT000303149
- if ((new_sock == INVALID_SOCKET) && (socket_errno == EINVAL))
+ if ((!my_socket_valid(new_sock)) && (socket_errno == EINVAL))
{
kill_server(SIGTERM);
}
#endif
- if (new_sock != INVALID_SOCKET ||
+ if (my_socket_valid(new_sock) ||
(socket_errno != SOCKET_EINTR && socket_errno != SOCKET_EAGAIN))
break;
MAYBE_BROKEN_SYSCALL;
@@ -5029,15 +5059,15 @@
if (!(test_flags & TEST_BLOCKING))
{
if (retry == MAX_ACCEPT_RETRY - 1)
- fcntl(sock, F_SETFL, flags); // Try without O_NONBLOCK
+ my_socket_nonblock(sock, false);
}
#endif
}
#if !defined(NO_FCNTL_NONBLOCK)
if (!(test_flags & TEST_BLOCKING))
- fcntl(sock, F_SETFL, flags);
+ my_socket_nonblock(sock, false);
#endif
- if (new_sock == INVALID_SOCKET)
+ if (!my_socket_valid(new_sock))
{
if ((error_count++ & 255) == 0) // This can happen often
sql_perror("Error in accept");
@@ -5049,7 +5079,7 @@
#ifdef HAVE_LIBWRAP
{
- if (sock == ip_sock)
+ if (my_socket_equal(sock, ip_sock))
{
struct request_info req;
signal(SIGCHLD, SIG_DFL);
@@ -5074,8 +5104,8 @@
if (req.sink)
((void (*)(int))req.sink)(req.fd);
- (void) shutdown(new_sock, SHUT_RDWR);
- (void) closesocket(new_sock);
+ (void) my_shutdown(new_sock, SHUT_RDWR);
+ (void) my_socket_close(new_sock);
continue;
}
}
@@ -5083,16 +5113,14 @@
#endif /* HAVE_LIBWRAP */
{<