1
0
mirror of https://github.com/MariaDB/server.git synced 2025-07-08 17:02:21 +03:00

Merged by hands

BitKeeper/etc/gone:
  auto-union
BitKeeper/etc/logging_ok:
  auto-union
BitKeeper/deleted/.del-skipkeys~207548ca813d5081:
  'Auto converge rename'
libmysqld/lib_sql.cc:
  Auto merged
sql/field.h:
  Auto merged
sql/ha_myisam.cc:
  Auto merged
sql/item.h:
  Auto merged
sql/mysql_priv.h:
  Auto merged
sql/mysqld.cc:
  Auto merged
sql/sql_base.cc:
  Auto merged
sql/sql_class.cc:
  Auto merged
sql/sql_class.h:
  Auto merged
sql/sql_handler.cc:
  Auto merged
sql/sql_parse.cc:
  Auto merged
sql/sql_select.cc:
  Auto merged
sql/sql_table.cc:
  Auto merged
This commit is contained in:
unknown
2002-11-07 12:20:08 +04:00
27 changed files with 1792 additions and 371 deletions

View File

@ -20,6 +20,8 @@ heikki@donna.mysql.fi
heikki@hundin.mysql.fi heikki@hundin.mysql.fi
heikki@rescue. heikki@rescue.
heikki@work.mysql.com heikki@work.mysql.com
hf@bison.(none)
hf@bisonxp.(none)
hf@genie.(none) hf@genie.(none)
jani@dsl-jkl1657.dial.inet.fi jani@dsl-jkl1657.dial.inet.fi
jani@hynda.(none) jani@hynda.(none)

View File

@ -314,6 +314,10 @@ int mysql_rpl_parse_enabled(MYSQL* mysql __attribute__((unused))) { return 1; }
my_bool mysql_rpl_probe(MYSQL *mysql __attribute__((unused))) { return 1; } my_bool mysql_rpl_probe(MYSQL *mysql __attribute__((unused))) { return 1; }
#endif #endif
#ifdef EMBEDDED_LIBRARY
#define mysql_send_query mysql_real_query
#endif
#define MAX_SERVER_ARGS 20 #define MAX_SERVER_ARGS 20
static int embedded_server_arg_count=0; static int embedded_server_arg_count=0;

View File

@ -108,6 +108,9 @@ typedef struct st_mysql_data {
unsigned int fields; unsigned int fields;
MYSQL_ROWS *data; MYSQL_ROWS *data;
MEM_ROOT alloc; MEM_ROOT alloc;
#ifdef EMBEDDED_LIBRARY
MYSQL_ROWS **prev_ptr;
#endif
} MYSQL_DATA; } MYSQL_DATA;
struct st_mysql_options { struct st_mysql_options {
@ -137,13 +140,20 @@ struct st_mysql_options {
a read that is replication-aware a read that is replication-aware
*/ */
my_bool no_master_reads; my_bool no_master_reads;
#ifdef EMBEDDED_LIBRARY
my_bool separate_thread;
#endif
}; };
enum mysql_option { MYSQL_OPT_CONNECT_TIMEOUT, MYSQL_OPT_COMPRESS, enum mysql_option { MYSQL_OPT_CONNECT_TIMEOUT, MYSQL_OPT_COMPRESS,
MYSQL_OPT_NAMED_PIPE, MYSQL_INIT_COMMAND, MYSQL_OPT_NAMED_PIPE, MYSQL_INIT_COMMAND,
MYSQL_READ_DEFAULT_FILE, MYSQL_READ_DEFAULT_GROUP, MYSQL_READ_DEFAULT_FILE, MYSQL_READ_DEFAULT_GROUP,
MYSQL_SET_CHARSET_DIR, MYSQL_SET_CHARSET_NAME, MYSQL_SET_CHARSET_DIR, MYSQL_SET_CHARSET_NAME,
MYSQL_OPT_LOCAL_INFILE}; MYSQL_OPT_LOCAL_INFILE,
#ifdef EMBEDDED_LIBRARY
MYSQL_OPT_USE_RESULT
#endif
};
enum mysql_status { MYSQL_STATUS_READY,MYSQL_STATUS_GET_RESULT, enum mysql_status { MYSQL_STATUS_READY,MYSQL_STATUS_GET_RESULT,
MYSQL_STATUS_USE_RESULT}; MYSQL_STATUS_USE_RESULT};
@ -156,13 +166,19 @@ enum mysql_status { MYSQL_STATUS_READY,MYSQL_STATUS_GET_RESULT,
enum mysql_rpl_type { MYSQL_RPL_MASTER, MYSQL_RPL_SLAVE, enum mysql_rpl_type { MYSQL_RPL_MASTER, MYSQL_RPL_SLAVE,
MYSQL_RPL_ADMIN }; MYSQL_RPL_ADMIN };
struct st_mysql_res;
typedef struct st_mysql typedef struct st_mysql
{ {
NET net; /* Communication parameters */ NET net; /* Communication parameters */
gptr connector_fd; /* ConnectorFd for SSL */ gptr connector_fd; /* ConnectorFd for SSL */
char *host,*user,*passwd,*unix_socket,*server_version,*host_info, #ifndef _0EMBEDDED_LIBRARY
*info,*db; char *host,*user,*passwd,*unix_socket,*server_version,*host_info,*info;
#endif
#ifdef EMBEDDED_LIBRARY
struct st_mysql_res *result;
#endif
char *db;
struct charset_info_st *charset; struct charset_info_st *charset;
MYSQL_FIELD *fields; MYSQL_FIELD *fields;
MEM_ROOT field_alloc; MEM_ROOT field_alloc;
@ -201,6 +217,9 @@ typedef struct st_mysql
typedef struct st_mysql_res { typedef struct st_mysql_res {
#ifdef EMBEDDED_LIBRARY
const char *query_str;
#endif
my_ulonglong row_count; my_ulonglong row_count;
MYSQL_FIELD *fields; MYSQL_FIELD *fields;
MYSQL_DATA *data; MYSQL_DATA *data;

View File

@ -31,8 +31,13 @@
extern "C" { extern "C" {
#endif /* __cplusplus */ #endif /* __cplusplus */
enum enum_vio_type { VIO_CLOSED, VIO_TYPE_TCPIP, VIO_TYPE_SOCKET, enum enum_vio_type {
VIO_TYPE_NAMEDPIPE, VIO_TYPE_SSL}; VIO_CLOSED, VIO_TYPE_TCPIP, VIO_TYPE_SOCKET,
VIO_TYPE_NAMEDPIPE, VIO_TYPE_SSL
#ifdef EMBEDDED_LIBRARY
,VIO_SHARED_MEMORY, VIO_BUFFER
#endif
};
#ifndef __WIN__ #ifndef __WIN__
#define HANDLE void * #define HANDLE void *

View File

@ -26,6 +26,9 @@ C_MODE_START
extern void start_embedded_connection(NET * net); extern void start_embedded_connection(NET * net);
extern void end_embedded_connection(NET * net); extern void end_embedded_connection(NET * net);
extern void lib_connection_phase(NET *net, int phase); extern void lib_connection_phase(NET *net, int phase);
extern bool lib_dispatch_command(enum enum_server_command command, NET *net, extern void init_embedded_mysql(MYSQL *mysql, int client_flag, char *db);
const char *arg, ulong length); extern void *create_embedded_thd(Vio *vio, unsigned char *buff, int client_flag, char *db);
extern NET *get_mysql_net(MYSQL *mysql);
extern my_bool simple_command(MYSQL *mysql,enum enum_server_command command, const char *arg,
ulong length, my_bool skipp_check);
C_MODE_END C_MODE_END

View File

@ -23,6 +23,11 @@
#define mysql_unix_port mysql_inix_port1 #define mysql_unix_port mysql_inix_port1
#define mysql_port mysql_port1 #define mysql_port mysql_port1
static int fake_argc= 1;
static char *fake_argv[]= {(char *)"", 0};
static const char *fake_groups[] = { "server", "embedded", 0 };
static char inited, org_my_init_done;
#if defined (__WIN__) #if defined (__WIN__)
#include "../sql/mysqld.cpp" #include "../sql/mysqld.cpp"
#else #else
@ -32,6 +37,7 @@
#define SCRAMBLE_LENGTH 8 #define SCRAMBLE_LENGTH 8
C_MODE_START C_MODE_START
#include "lib_vio.c" #include "lib_vio.c"
#include "errmsg.h"
static int check_connections1(THD * thd); static int check_connections1(THD * thd);
static int check_connections2(THD * thd); static int check_connections2(THD * thd);
@ -41,19 +47,44 @@ static bool check_user(THD *thd, enum_server_command command,
char * get_mysql_home(){ return mysql_home;}; char * get_mysql_home(){ return mysql_home;};
char * get_mysql_real_data_home(){ return mysql_real_data_home;}; char * get_mysql_real_data_home(){ return mysql_real_data_home;};
bool lib_dispatch_command(enum enum_server_command command, NET *net, my_bool simple_command(MYSQL *mysql,enum enum_server_command command, const char *arg,
const char *arg, ulong length) ulong length, my_bool skipp_check)
{ {
NET *net= &mysql->net;
my_bool result= 1;
THD *thd=(THD *) net->vio->dest_thd; THD *thd=(THD *) net->vio->dest_thd;
thd->store_globals(); // Fix if more than one connect
thd->net.last_error[0]=0; // Clear error message
thd->net.last_errno=0;
net_new_transaction(&thd->net); /* Check that we are calling the client functions in right order */
return dispatch_command(command, thd, (char *) arg, length + 1); if (mysql->status != MYSQL_STATUS_READY)
{
strmov(net->last_error,ER(mysql->net.last_errno=CR_COMMANDS_OUT_OF_SYNC));
return 1;
}
/* Clear result variables */
mysql->net.last_error[0]=0;
mysql->net.last_errno=0;
mysql->info=0;
mysql->affected_rows= ~(my_ulonglong) 0;
/* Clear receive buffer and vio packet list */
net_clear(net);
vio_reset(net->vio);
thd->store_globals(); // Fix if more than one connect
// thd->net.last_error[0]=0; // Clear error message
// thd->net.last_errno=0;
net_new_transaction(net);
result= dispatch_command(command, thd, (char *) arg, length + 1);
if (!skipp_check)
result= net->last_errno ? -1 : 0;
return result;
} }
#ifdef _DUMMY
void lib_connection_phase(NET * net, int phase) void lib_connection_phase(NET * net, int phase)
{ {
THD * thd; THD * thd;
@ -82,7 +113,7 @@ void start_embedded_conn1(NET * net)
Vio * v = net->vio; Vio * v = net->vio;
if (!v) if (!v)
{ {
v = vio_new(0,VIO_CLOSED,0); v = vio_new(0,VIO_BUFFER,0);
net->vio = v; net->vio = v;
} }
if (v) if (v)
@ -113,9 +144,6 @@ void start_embedded_conn1(NET * net)
check_connections1(thd); check_connections1(thd);
} }
static int static int
check_connections1(THD *thd) check_connections1(THD *thd)
{ {
@ -211,6 +239,9 @@ check_connections2(THD * thd)
thd->password=test(passwd[0]); thd->password=test(passwd[0]);
return 0; return 0;
} }
#else
C_MODE_END
#endif /* _DUMMY */
static bool check_user(THD *thd,enum_server_command command, const char *user, static bool check_user(THD *thd,enum_server_command command, const char *user,
const char *passwd, const char *db, bool check_count) const char *passwd, const char *db, bool check_count)
@ -277,9 +308,136 @@ static bool check_user(THD *thd,enum_server_command command, const char *user,
extern "C" extern "C"
{ {
static my_bool inited, org_my_init_done;
ulong max_allowed_packet, net_buffer_length; ulong max_allowed_packet, net_buffer_length;
int STDCALL mysql_server_init(int argc, char **argv, char **groups)
{
char glob_hostname[FN_REFLEN];
/* This mess is to allow people to call the init function without
* having to mess with a fake argv */
int *argcp;
char ***argvp;
int fake_argc = 1;
char *fake_argv[] = { (char *)"", 0 };
const char *fake_groups[] = { "server", "embedded", 0 };
if (argc)
{
argcp = &argc;
argvp = (char***) &argv;
}
else
{
argcp = &fake_argc;
argvp = (char ***) &fake_argv;
}
if (!groups)
groups = (char**) fake_groups;
/* Only call MY_INIT() if it hasn't been called before */
if (!inited)
{
inited=1;
org_my_init_done=my_init_done;
}
if (!org_my_init_done)
{
MY_INIT((char *)"mysql_embedded"); // init my_sys library & pthreads
}
if (init_common_variables("my", argc, argv, (const char **)groups))
{
mysql_server_end();
return 1;
}
/* Get default temporary directory */
opt_mysql_tmpdir=getenv("TMPDIR"); /* Use this if possible */
#if defined( __WIN__) || defined(OS2)
if (!opt_mysql_tmpdir)
opt_mysql_tmpdir=getenv("TEMP");
if (!opt_mysql_tmpdir)
opt_mysql_tmpdir=getenv("TMP");
#endif
if (!opt_mysql_tmpdir || !opt_mysql_tmpdir[0])
opt_mysql_tmpdir=(char*) P_tmpdir; /* purecov: inspected */
if (init_thread_environement())
{
mysql_server_end();
return 1;
}
umask(((~my_umask) & 0666));
if (init_server_components())
{
mysql_server_end();
return 1;
}
error_handler_hook = my_message_sql;
opt_noacl = 1; // No permissions
if (acl_init(opt_noacl))
{
mysql_server_end();
return 1;
}
if (!opt_noacl)
(void) grant_init();
init_max_user_conn();
init_update_queries();
#ifdef HAVE_DLOPEN
if (!opt_noacl)
udf_init();
#endif
if (opt_bin_log)
{
if (!opt_bin_logname)
{
char tmp[FN_REFLEN];
/* TODO: The following should be using fn_format(); We just need to
first change fn_format() to cut the file name if it's too long.
*/
strmake(tmp,glob_hostname,FN_REFLEN-5);
strmov(strcend(tmp,'.'),"-bin");
opt_bin_logname=my_strdup(tmp,MYF(MY_WME));
}
open_log(&mysql_bin_log, glob_hostname, opt_bin_logname, "-bin",
opt_binlog_index_name, LOG_BIN);
using_update_log=1;
}
(void) thr_setconcurrency(concurrency); // 10 by default
if (
#ifdef HAVE_BERKELEY_DB
!berkeley_skip ||
#endif
(flush_time && flush_time != ~(ulong) 0L))
{
pthread_t hThread;
if (pthread_create(&hThread,&connection_attrib,handle_manager,0))
sql_print_error("Warning: Can't create thread to manage maintenance");
}
/*
Update mysqld variables from client variables if set
The client variables are set also by get_one_option() in mysqld.cc
*/
if (max_allowed_packet)
global_system_variables.max_allowed_packet= max_allowed_packet;
if (net_buffer_length)
global_system_variables.net_buffer_length= net_buffer_length;
return 0;
}
#ifdef __DUMMY
int STDCALL mysql_server_init(int argc, char **argv, char **groups) int STDCALL mysql_server_init(int argc, char **argv, char **groups)
{ {
char glob_hostname[FN_REFLEN]; char glob_hostname[FN_REFLEN];
@ -562,6 +720,288 @@ int STDCALL mysql_server_init(int argc, char **argv, char **groups)
return 0; return 0;
} }
int STDCALL mysql_server_init(int argc, char **argv, char **groups)
{
char glob_hostname[FN_REFLEN];
/* This mess is to allow people to call the init function without
* having to mess with a fake argv */
int *argcp;
char ***argvp;
int fake_argc = 1;
char *fake_argv[] = { (char *)"", 0 };
const char *fake_groups[] = { "server", "embedded", 0 };
if (argc)
{
argcp = &argc;
argvp = (char***) &argv;
}
else
{
argcp = &fake_argc;
argvp = (char ***) &fake_argv;
}
if (!groups)
groups = (char**) fake_groups;
my_umask=0660; // Default umask for new files
my_umask_dir=0700; // Default umask for new directories
/* Only call MY_INIT() if it hasn't been called before */
if (!inited)
{
inited=1;
org_my_init_done=my_init_done;
}
if (!org_my_init_done)
{
MY_INIT((char *)"mysql_embedded"); // init my_sys library & pthreads
}
tzset(); // Set tzname
start_time=time((time_t*) 0);
#ifdef HAVE_TZNAME
#if defined(HAVE_LOCALTIME_R) && defined(_REENTRANT)
{
struct tm tm_tmp;
localtime_r(&start_time,&tm_tmp);
strmov(time_zone,tzname[tm_tmp.tm_isdst != 0 ? 1 : 0]);
}
#else
{
struct tm *start_tm;
start_tm=localtime(&start_time);
strmov(time_zone,tzname[start_tm->tm_isdst != 0 ? 1 : 0]);
}
#endif
#endif
if (gethostname(glob_hostname,sizeof(glob_hostname)-4) < 0)
strmov(glob_hostname,"mysql");
#ifndef DBUG_OFF
strxmov(strend(server_version),MYSQL_SERVER_SUFFIX,"-debug",NullS);
#else
strmov(strend(server_version),MYSQL_SERVER_SUFFIX);
#endif
load_defaults("my", (const char **) groups, argcp, argvp);
defaults_argv=*argvp;
/* Get default temporary directory */
opt_mysql_tmpdir=getenv("TMPDIR"); /* Use this if possible */
#if defined( __WIN__) || defined(OS2)
if (!opt_mysql_tmpdir)
opt_mysql_tmpdir=getenv("TEMP");
if (!opt_mysql_tmpdir)
opt_mysql_tmpdir=getenv("TMP");
#endif
if (!opt_mysql_tmpdir || !opt_mysql_tmpdir[0])
opt_mysql_tmpdir=(char*) P_tmpdir; /* purecov: inspected */
set_options();
get_options(*argcp, *argvp);
if (opt_log || opt_update_log || opt_slow_log || opt_bin_log)
strcat(server_version,"-log");
DBUG_PRINT("info",("%s Ver %s for %s on %s\n",my_progname,
server_version, SYSTEM_TYPE,MACHINE_TYPE));
/* These must be set early */
(void) pthread_mutex_init(&LOCK_mysql_create_db,MY_MUTEX_INIT_SLOW);
(void) pthread_mutex_init(&LOCK_Acl,MY_MUTEX_INIT_SLOW);
(void) pthread_mutex_init(&LOCK_open,MY_MUTEX_INIT_FAST);
(void) pthread_mutex_init(&LOCK_thread_count,MY_MUTEX_INIT_FAST);
(void) pthread_mutex_init(&LOCK_mapped_file,MY_MUTEX_INIT_SLOW);
(void) pthread_mutex_init(&LOCK_status,MY_MUTEX_INIT_FAST);
(void) pthread_mutex_init(&LOCK_error_log,MY_MUTEX_INIT_FAST);
(void) pthread_mutex_init(&LOCK_delayed_insert,MY_MUTEX_INIT_FAST);
(void) pthread_mutex_init(&LOCK_delayed_status,MY_MUTEX_INIT_FAST);
(void) pthread_mutex_init(&LOCK_delayed_create,MY_MUTEX_INIT_SLOW);
(void) pthread_mutex_init(&LOCK_manager,MY_MUTEX_INIT_FAST);
(void) pthread_mutex_init(&LOCK_crypt,MY_MUTEX_INIT_FAST);
(void) pthread_mutex_init(&LOCK_bytes_sent,MY_MUTEX_INIT_FAST);
(void) pthread_mutex_init(&LOCK_bytes_received,MY_MUTEX_INIT_FAST);
(void) pthread_mutex_init(&LOCK_timezone,MY_MUTEX_INIT_FAST);
(void) pthread_mutex_init(&LOCK_user_conn, MY_MUTEX_INIT_FAST);
(void) pthread_mutex_init(&LOCK_rpl_status, MY_MUTEX_INIT_FAST);
(void) pthread_mutex_init(&LOCK_active_mi, MY_MUTEX_INIT_FAST);
(void) pthread_mutex_init(&LOCK_global_system_variables, MY_MUTEX_INIT_FAST);
(void) my_rwlock_init(&LOCK_grant, NULL);
(void) pthread_cond_init(&COND_thread_count,NULL);
(void) pthread_cond_init(&COND_refresh,NULL);
(void) pthread_cond_init(&COND_thread_cache,NULL);
(void) pthread_cond_init(&COND_flush_thread_cache,NULL);
(void) pthread_cond_init(&COND_manager,NULL);
(void) pthread_cond_init(&COND_rpl_status, NULL);
if (set_default_charset_by_name(sys_charset.value, MYF(MY_WME)))
{
mysql_server_end();
return 1;
}
charsets_list = list_charsets(MYF(MY_CS_COMPILED|MY_CS_CONFIG));
/* Parameter for threads created for connections */
(void) pthread_attr_init(&connection_attrib);
(void) pthread_attr_setdetachstate(&connection_attrib,
PTHREAD_CREATE_DETACHED);
pthread_attr_setstacksize(&connection_attrib,thread_stack);
pthread_attr_setscope(&connection_attrib, PTHREAD_SCOPE_SYSTEM);
#if defined( SET_RLIMIT_NOFILE) || defined( OS2)
/* connections and databases needs lots of files */
{
uint wanted_files=10+(uint) max(max_connections*5,
max_connections+table_cache_size*2);
set_if_bigger(wanted_files, open_files_limit);
// Note that some system returns 0 if we succeed here:
uint files=set_maximum_open_files(wanted_files);
if (files && files < wanted_files && ! open_files_limit)
{
max_connections= (ulong) min((files-10),max_connections);
table_cache_size= (ulong) max((files-10-max_connections)/2,64);
DBUG_PRINT("warning",
("Changed limits: max_connections: %ld table_cache: %ld",
max_connections,table_cache_size));
sql_print_error("Warning: Changed limits: max_connections: %ld table_cache: %ld",max_connections,table_cache_size);
}
}
#endif
unireg_init(opt_specialflag); /* Set up extern variabels */
init_errmessage(); /* Read error messages from file */
lex_init();
item_init();
set_var_init();
mysys_uses_curses=0;
#ifdef USE_REGEX
regex_init();
#endif
if (use_temp_pool && bitmap_init(&temp_pool,1024,1))
{
mysql_server_end();
return 1;
}
/*
We have enough space for fiddling with the argv, continue
*/
umask(((~my_umask) & 0666));
table_cache_init();
hostname_cache_init();
query_cache_result_size_limit(query_cache_limit);
query_cache_resize(query_cache_size);
randominit(&sql_rand,(ulong) start_time,(ulong) start_time/2);
reset_floating_point_exceptions();
init_thr_lock();
init_slave_list();
/* Setup log files */
if (opt_log)
open_log(&mysql_log, glob_hostname, opt_logname, ".log", NullS,
LOG_NORMAL);
if (opt_update_log)
{
open_log(&mysql_update_log, glob_hostname, opt_update_logname, "",
NullS, LOG_NEW);
using_update_log=1;
}
if (opt_slow_log)
open_log(&mysql_slow_log, glob_hostname, opt_slow_logname, "-slow.log",
NullS, LOG_NORMAL);
if (ha_init())
{
sql_print_error("Can't init databases");
exit(1);
}
ha_key_cache();
#if defined(HAVE_MLOCKALL) && defined(MCL_CURRENT)
if (locked_in_memory && !geteuid())
{
if (mlockall(MCL_CURRENT))
{
sql_print_error("Warning: Failed to lock memory. Errno: %d\n",errno);
}
else
locked_in_memory=1;
}
#else
locked_in_memory=0;
#endif
if (opt_myisam_log)
(void) mi_log( 1 );
ft_init_stopwords(ft_precompiled_stopwords);
/*
init signals & alarm
After this we can't quit by a simple unireg_abort
*/
error_handler_hook = my_message_sql;
if (pthread_key_create(&THR_THD,NULL) ||
pthread_key_create(&THR_MALLOC,NULL))
{
sql_print_error("Can't create thread-keys");
exit(1);
}
opt_noacl = 1; // No permissions
if (acl_init(opt_noacl))
{
mysql_server_end();
return 1;
}
if (!opt_noacl)
(void) grant_init();
init_max_user_conn();
init_update_queries();
#ifdef HAVE_DLOPEN
if (!opt_noacl)
udf_init();
#endif
if (opt_bin_log)
{
if (!opt_bin_logname)
{
char tmp[FN_REFLEN];
/* TODO: The following should be using fn_format(); We just need to
first change fn_format() to cut the file name if it's too long.
*/
strmake(tmp,glob_hostname,FN_REFLEN-5);
strmov(strcend(tmp,'.'),"-bin");
opt_bin_logname=my_strdup(tmp,MYF(MY_WME));
}
open_log(&mysql_bin_log, glob_hostname, opt_bin_logname, "-bin",
opt_binlog_index_name, LOG_BIN);
using_update_log=1;
}
(void) thr_setconcurrency(concurrency); // 10 by default
if (
#ifdef HAVE_BERKELEY_DB
!berkeley_skip ||
#endif
(flush_time && flush_time != ~(ulong) 0L))
{
pthread_t hThread;
if (pthread_create(&hThread,&connection_attrib,handle_manager,0))
sql_print_error("Warning: Can't create thread to manage maintenance");
}
/*
Update mysqld variables from client variables if set
The client variables are set also by get_one_option() in mysqld.cc
*/
if (max_allowed_packet)
global_system_variables.max_allowed_packet= max_allowed_packet;
if (net_buffer_length)
global_system_variables.net_buffer_length= net_buffer_length;
return 0;
}
#endif
void STDCALL mysql_server_end() void STDCALL mysql_server_end()
{ {
@ -594,7 +1034,7 @@ void STDCALL mysql_thread_end()
void start_embedded_connection(NET * net) void start_embedded_connection(NET * net)
{ {
start_embedded_conn1(net); // start_embedded_conn1(net);
} }
void end_embedded_connection(NET * net) void end_embedded_connection(NET * net)
@ -604,3 +1044,469 @@ void end_embedded_connection(NET * net)
} }
} /* extern "C" */ } /* extern "C" */
C_MODE_START
NET *get_mysql_net(MYSQL *mysql)
{
return &((THD *)mysql->net.vio->dest_thd)->net;
}
void init_embedded_mysql(MYSQL *mysql, int client_flag, char *db)
{
THD *thd = (THD *)mysql->net.vio->dest_thd;
mysql->reconnect= 1; /* Reconnect as default */
mysql->server_status= SERVER_STATUS_AUTOCOMMIT;
mysql->protocol_version= ::protocol_version;
mysql->thread_id= thd->thread_id;
strmake(mysql->scramble_buff, thd->scramble, 8);
mysql->server_capabilities= CLIENT_LONG_FLAG | CLIENT_CONNECT_WITH_DB |
CLIENT_TRANSACTIONS;
mysql->server_language= MY_CHARSET_CURRENT;
mysql->server_status= thd->server_status;
mysql->client_flag= client_flag | mysql->options.client_flag;
mysql->db= db;
thd->mysql= mysql;
}
C_MODE_END
static int embedded_thd_net_init(NET *net, unsigned char *buff)
{
net->buff = buff;
if (net_buffer_length > max_allowed_packet)
max_allowed_packet= net_buffer_length;
net->buff_end= net->buff+(net->max_packet=net_buffer_length);
net->vio= NULL;
net->no_send_ok= 0;
net->error=0; net->return_errno=0; net->return_status=0;
// net->timeout=(uint) net_read_timeout; /* Timeout for read */
net->pkt_nr= net->compress_pkt_nr=0;
net->write_pos= net->read_pos = net->buff;
net->last_error[0]= 0;
net->compress= 0;
net->reading_or_writing= 0;
net->where_b = net->remain_in_buf= 0;
net->last_errno= 0;
net->query_cache_query= 0;
return 0;
}
C_MODE_START
void *create_embedded_thd(Vio *vio, unsigned char *buff, int client_flag, char *db)
{
THD * thd= new THD;
embedded_thd_net_init(&thd->net, buff);
/* if (protocol_version>9) */
thd->net.return_errno=1;
thd->thread_id= thread_id++;
if (thd->store_globals())
{
fprintf(stderr,"store_globals failed.\n");
return NULL;
}
thd->mysys_var= my_thread_var;
thd->dbug_thread_id= my_thread_id();
thd->thread_stack= (char*) &thd;
// if (thd->max_join_size == HA_POS_ERROR)
// thd->options |= OPTION_BIG_SELECTS;
thd->proc_info=0; // Remove 'login'
thd->command=COM_SLEEP;
thd->version=refresh_version;
thd->set_time();
init_sql_alloc(&thd->mem_root,8192,8192);
thd->client_capabilities= client_flag;
// thd->max_packet_length= max_allowed_packet;
thd->net.vio = vio;
// if (thd->client_capabilities & CLIENT_INTERACTIVE)
// thd->inactive_timeout= net_interactive_timeout;
if (thd->client_capabilities & CLIENT_TRANSACTIONS)
thd->net.return_status= &thd->server_status;
thd->db= db;
thd->db_length= db ? strip_sp(db) : 0;
thd->db_access= DB_ACLS;
thd->master_access= ~NO_ACCESS;
return thd;
}
C_MODE_END
bool send_fields(THD *thd, List<Item> &list, uint flag)
{
List_iterator_fast<Item> it(list);
Item *item;
MEM_ROOT *alloc;
MYSQL_FIELD *field, *client_field;
unsigned int field_count= list.elements;
MYSQL *mysql= thd->mysql;
if (!(mysql->result=(MYSQL_RES*) my_malloc(sizeof(MYSQL_RES)+
sizeof(ulong) * field_count,
MYF(MY_WME | MY_ZEROFILL))))
goto err;
mysql->field_count=field_count;
alloc= &mysql->field_alloc;
field= (MYSQL_FIELD *)alloc_root(alloc, sizeof(MYSQL_FIELD)*list.elements);
if (!field)
goto err;
client_field= field;
while ((item= it++))
{
Send_field server_field;
item->make_field(&server_field);
client_field->table= strdup_root(alloc, server_field.table_name);
client_field->name= strdup_root(alloc,server_field.col_name);
client_field->length= server_field.length;
client_field->type= server_field.type;
client_field->flags= server_field.flags;
client_field->decimals= server_field.decimals;
if (INTERNAL_NUM_FIELD(client_field))
client_field->flags|= NUM_FLAG;
if (flag & 2)
{
char buff[80];
String tmp(buff, sizeof(buff), default_charset_info), *res;
if (!(res=item->val_str(&tmp)))
client_field->def= strdup_root(alloc, "");
else
client_field->def= strdup_root(alloc, tmp.ptr());
}
else
client_field->def=0;
client_field->max_length= 0;
++client_field;
}
mysql->result->fields = field;
if (!(mysql->result->data= (MYSQL_DATA*) my_malloc(sizeof(MYSQL_DATA),
MYF(MY_WME | MY_ZEROFILL))))
goto err;
init_alloc_root(&mysql->result->data->alloc,8192,0); /* Assume rowlength < 8192 */
mysql->result->data->alloc.min_malloc=sizeof(MYSQL_ROWS);
mysql->result->data->rows=0;
mysql->result->data->fields=field_count;
mysql->result->field_count=field_count;
mysql->result->data->prev_ptr= &mysql->result->data->data;
mysql->result->field_alloc= mysql->field_alloc;
mysql->result->current_field=0;
mysql->result->current_row=0;
return 0;
err:
send_error(thd, ER_OUT_OF_RESOURCES); /* purecov: inspected */
return 1; /* purecov: inspected */
}
/* Get the length of next field. Change parameter to point at fieldstart */
static ulong
net_field_length(uchar **packet)
{
reg1 uchar *pos= *packet;
if (*pos < 251)
{
(*packet)++;
return (ulong) *pos;
}
if (*pos == 251)
{
(*packet)++;
return NULL_LENGTH;
}
if (*pos == 252)
{
(*packet)+=3;
return (ulong) uint2korr(pos+1);
}
if (*pos == 253)
{
(*packet)+=4;
return (ulong) uint3korr(pos+1);
}
(*packet)+=9; /* Must be 254 when here */
return (ulong) uint4korr(pos+1);
}
#ifdef __DUMMY
bool select_send___send_data(List<Item> &items)
{
List_iterator_fast<Item> li(items);
Item *item;
String *packet= &thd->packet;
MYSQL *mysql= thd->mysql;
MYSQL_DATA *result= mysql->result->data;
MYSQL_ROWS **prev_ptr= &mysql->result->data->data;
MYSQL_ROWS *cur;
MEM_ROOT *alloc= &mysql->result->data->alloc;
char *to;
int n_fields= items.elements;
uchar *cp;
MYSQL_FIELD *mysql_fields= mysql->result->fields;
MYSQL_ROW cur_field, end_field;
ulong len;
DBUG_ENTER("send_data");
if (unit->offset_limit_cnt)
{ // using limit offset,count
unit->offset_limit_cnt--;
DBUG_RETURN(0);
}
thd->packet.length(0);
while ((item=li++))
{
if (item->send(thd, packet))
{
packet->free();
my_error(ER_OUT_OF_RESOURCES, MYF(0));
DBUG_RETURN(1);
}
}
result->rows++;
if (!(cur= (MYSQL_ROWS *)alloc_root(alloc, sizeof(MYSQL_ROWS))) ||
!(cur->data= (MYSQL_ROW)alloc_root(alloc,
(n_fields + 1) * sizeof(char *) + packet->length())))
{
my_error(ER_OUT_OF_RESOURCES,MYF(0));
DBUG_RETURN(1);
}
*result->prev_ptr= cur;
result->prev_ptr= &cur->next;
to= (char*) (cur->data+n_fields+1);
cp= (uchar *)packet->ptr();
end_field= cur->data + n_fields;
for (cur_field=cur->data; cur_field<end_field; ++cur_field, ++mysql_fields)
{
if ((len= (ulong) net_field_length(&cp)) == NULL_LENGTH)
{
*cur_field = 0;
}
else
{
*cur_field= to;
memcpy(to,(char*) cp,len);
to[len]=0;
to+=len+1;
cp+=len;
if (mysql_fields->max_length < len)
mysql_fields->max_length=len;
}
}
*cur_field= to;
DBUG_RETURN(0);
}
#endif
bool select_send::send_data(List<Item> &items)
{
List_iterator_fast<Item> li(items);
Item *item;
MYSQL_ROWS *cur;
int n_fields= items.elements;
ulong len;
CONVERT *convert= thd->variables.convert_set;
CHARSET_INFO *charset_info= thd->packet.charset();
MYSQL_DATA *result= thd->mysql->result->data;
MEM_ROOT *alloc= &result->alloc;
MYSQL_ROW cur_field;
MYSQL_FIELD *mysql_fields= thd->mysql->result->fields;
DBUG_ENTER("send_data");
if (unit->offset_limit_cnt)
{ // using limit offset,count
unit->offset_limit_cnt--;
DBUG_RETURN(0);
}
result->rows++;
if (!(cur= (MYSQL_ROWS *)alloc_root(alloc, sizeof(MYSQL_ROWS)+(n_fields + 1) * sizeof(char *))))
{
my_error(ER_OUT_OF_RESOURCES,MYF(0));
DBUG_RETURN(1);
}
cur->data= (MYSQL_ROW)(((char *)cur) + sizeof(MYSQL_ROWS));
*result->prev_ptr= cur;
result->prev_ptr= &cur->next;
cur_field=cur->data;
for (item=li++; item; item=li++, cur_field++, mysql_fields++)
{
if (item->embedded_send(convert, charset_info, alloc, cur_field, &len))
{
my_error(ER_OUT_OF_RESOURCES,MYF(0));
DBUG_RETURN(1);
}
if (mysql_fields->max_length < len)
mysql_fields->max_length=len;
}
*cur_field= 0;
DBUG_RETURN(0);
}
bool do_command(THD *thd)
{
MYSQL *mysql= thd->mysql;
char *packet;
uint old_timeout;
ulong packet_length;
NET *net;
enum enum_server_command command;
DBUG_ENTER("do_command");
net= &thd->net;
thd->current_tablenr=0;
packet=0;
// old_timeout=net->timeout;
// net->timeout=(uint) thd->inactive_timeout; // Wait max for 8 hours
net->last_error[0]=0; // Clear error message
net->last_errno=0;
net_new_transaction(net);
if ((packet_length=my_net_read(net)) == packet_error)
{
DBUG_PRINT("info",("Got error reading command from socket %s",
vio_description(net->vio) ));
return TRUE;
}
else
{
packet=(char*) net->read_pos;
command = (enum enum_server_command) (uchar) packet[0];
DBUG_PRINT("info",("Command on %s = %d (%s)",
vio_description(net->vio), command,
command_name[command]));
}
// net->timeout=old_timeout; // Timeout for writing
DBUG_RETURN(dispatch_command(command,thd, packet+1, (uint) packet_length));
}
void
send_ok(THD *thd,ha_rows affected_rows,ulonglong id,const char *message)
{
NET *net= &thd->net;
if (net->no_send_ok) // hack for re-parsing queries
return;
DBUG_ENTER("send_ok");
MYSQL *mysql= current_thd->mysql;
mysql->affected_rows= affected_rows;
mysql->insert_id= id;
if (net->return_status)
mysql->server_status= *net->return_status;
if (message)
{
strmake(net->last_error, message, sizeof(net->last_error));
mysql->info= net->last_error;
}
DBUG_VOID_RETURN;
}
void
send_eof(THD *thd, bool no_flush)
{
/* static char eof_buff[1]= { (char) 254 };
NET *net= &thd->net;
DBUG_ENTER("send_eof");
if (net->vio != 0)
{
if (!no_flush && (thd->client_capabilities & CLIENT_PROTOCOL_41))
{
char buff[5];
uint tmp= min(thd->total_warn_count, 65535);
buff[0]=254;
int2store(buff+1, tmp);
int2store(buff+3, 0); // No flags yet
VOID(my_net_write(net,buff,5));
VOID(net_flush(net));
}
else
{
VOID(my_net_write(net,eof_buff,1));
if (!no_flush)
VOID(net_flush(net));
}
}
DBUG_VOID_RETURN;
*/
}
int embedded_send_row(THD *thd, int n_fields, char *data, int data_len)
{
MYSQL *mysql= thd->mysql;
MYSQL_DATA *result= mysql->result->data;
MYSQL_ROWS **prev_ptr= &mysql->result->data->data;
MYSQL_ROWS *cur;
MEM_ROOT *alloc= &mysql->result->data->alloc;
char *to;
uchar *cp;
MYSQL_FIELD *mysql_fields= mysql->result->fields;
MYSQL_ROW cur_field, end_field;
ulong len;
DBUG_ENTER("embedded_send_row");
result->rows++;
if (!(cur= (MYSQL_ROWS *)alloc_root(alloc, sizeof(MYSQL_ROWS) + (n_fields + 1) * sizeof(char *) + data_len)))
{
my_error(ER_OUT_OF_RESOURCES,MYF(0));
DBUG_RETURN(1);
}
cur->data= (MYSQL_ROW)((char *)cur) + sizeof(MYSQL_ROWS);
*result->prev_ptr= cur;
result->prev_ptr= &cur->next;
to= (char*) (cur->data+n_fields+1);
cp= (uchar *)data;
end_field= cur->data + n_fields;
for (cur_field=cur->data; cur_field<end_field; cur_field++, mysql_fields++)
{
if ((len= (ulong) net_field_length(&cp)) == NULL_LENGTH)
{
*cur_field = 0;
}
else
{
*cur_field= to;
memcpy(to,(char*) cp,len);
to[len]=0;
to+=len+1;
cp+=len;
if (mysql_fields->max_length < len)
mysql_fields->max_length=len;
}
}
*cur_field= to;
DBUG_RETURN(0);
}

View File

@ -42,14 +42,7 @@
struct st_vio struct st_vio
{ {
my_socket sd; /* my_socket - real or imaginary */
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 */
enum enum_vio_type type; /* Type of connection */ enum enum_vio_type type; /* Type of connection */
char desc[30]; /* String description */
void *dest_thd; void *dest_thd;
char *packets, **last_packet; char *packets, **last_packet;
char *where_in_packet, *end_of_packet; char *where_in_packet, *end_of_packet;
@ -57,6 +50,7 @@ struct st_vio
MEM_ROOT root; MEM_ROOT root;
}; };
/* Initialize the communication buffer */ /* Initialize the communication buffer */
Vio *vio_new(my_socket sd, enum enum_vio_type type, my_bool localhost) Vio *vio_new(my_socket sd, enum enum_vio_type type, my_bool localhost)
@ -69,6 +63,7 @@ Vio *vio_new(my_socket sd, enum enum_vio_type type, my_bool localhost)
init_alloc_root(&vio->root, 8192, 8192); init_alloc_root(&vio->root, 8192, 8192);
vio->root.min_malloc = sizeof(char *) + 4; vio->root.min_malloc = sizeof(char *) + 4;
vio->last_packet = &vio->packets; vio->last_packet = &vio->packets;
vio->type = type;
} }
DBUG_RETURN(vio); DBUG_RETURN(vio);
} }
@ -219,4 +214,22 @@ my_bool vio_poll_read(Vio *vio,uint timeout)
return 0; return 0;
} }
int create_vio(NET *net, int separate_thread)
{
Vio * v = net->vio;
if (!v)
{
v = vio_new(0, separate_thread ? VIO_SHARED_MEMORY : VIO_BUFFER, 0);
net->vio = v;
}
return !v;
}
void set_thd(Vio *v, void *thd)
{
if (v)
{
v -> dest_thd = thd;
}
}
#endif /* HAVE_VIO */ #endif /* HAVE_VIO */

View File

@ -68,7 +68,8 @@ static MYSQL_DATA *read_rows (MYSQL *mysql,MYSQL_FIELD *fields,
static int read_one_row(MYSQL *mysql,uint fields,MYSQL_ROW row, static int read_one_row(MYSQL *mysql,uint fields,MYSQL_ROW row,
ulong *lengths); ulong *lengths);
static void end_server(MYSQL *mysql); static void end_server(MYSQL *mysql);
static void read_user_name(char *name); /*static void read_user_name(char *name);
*/
static void append_wild(char *to,char *end,const char *wild); static void append_wild(char *to,char *end,const char *wild);
static int send_file_to_server(MYSQL *mysql,const char *filename); static int send_file_to_server(MYSQL *mysql,const char *filename);
static ulong mysql_sub_escape_string(CHARSET_INFO *charset_info, char *to, static ulong mysql_sub_escape_string(CHARSET_INFO *charset_info, char *to,
@ -211,40 +212,6 @@ static void free_rows(MYSQL_DATA *cur)
} }
} }
my_bool
simple_command(MYSQL *mysql,enum enum_server_command command, const char *arg,
ulong length, my_bool skipp_check)
{
NET *net= &mysql->net;
my_bool result= 1;
/* Check that we are calling the client functions in right order */
if (mysql->status != MYSQL_STATUS_READY)
{
strmov(net->last_error,ER(mysql->net.last_errno=CR_COMMANDS_OUT_OF_SYNC));
goto end;
}
/* Clear result variables */
mysql->net.last_error[0]=0;
mysql->net.last_errno=0;
mysql->info=0;
mysql->affected_rows= ~(my_ulonglong) 0;
/* Clear receive buffer and vio packet list */
net_clear(net);
vio_reset(net->vio);
result = lib_dispatch_command(command, net, arg,length);
if (!skipp_check)
result= ((mysql->packet_length=net_safe_read(mysql)) == packet_error ?
1 : 0);
end:
return result;
}
static void free_old_query(MYSQL *mysql) static void free_old_query(MYSQL *mysql)
{ {
DBUG_ENTER("free_old_query"); DBUG_ENTER("free_old_query");
@ -261,6 +228,8 @@ struct passwd *getpwuid(uid_t);
char* getlogin(void); char* getlogin(void);
#endif #endif
#ifdef _DUMMY
#if !defined(MSDOS) && ! defined(VMS) && !defined(__WIN__) #if !defined(MSDOS) && ! defined(VMS) && !defined(__WIN__)
static void read_user_name(char *name) static void read_user_name(char *name)
{ {
@ -307,6 +276,7 @@ static void read_user_name(char *name)
} }
#endif #endif
#endif /*_DUMMY */
#ifdef __WIN__ #ifdef __WIN__
static my_bool is_NT(void) static my_bool is_NT(void)
@ -391,7 +361,7 @@ end_server(MYSQL *mysql)
end_embedded_connection(&mysql->net); end_embedded_connection(&mysql->net);
mysql->net.vio= 0; /* Marker */ mysql->net.vio= 0; /* Marker */
} }
net_end(&mysql->net); mysql->net.buff = NULL;
free_old_query(mysql); free_old_query(mysql);
DBUG_VOID_RETURN; DBUG_VOID_RETURN;
} }
@ -753,6 +723,7 @@ static void mysql_once_init()
if (!mysql_client_init) if (!mysql_client_init)
{ {
mysql_client_init=1; mysql_client_init=1;
my_init(); /* Will init threads */ my_init(); /* Will init threads */
init_client_errs(); init_client_errs();
mysql_port = MYSQL_PORT; mysql_port = MYSQL_PORT;
@ -787,99 +758,15 @@ mysql_connect(MYSQL *mysql,const char *host,
} }
/* int create_vio(NET *net, int separate_thread);
** Note that the mysql argument must be initialized with mysql_init() void set_thd(Vio *vio, void *thd);
** before calling mysql_real_connect !
*/
MYSQL * STDCALL /************/
mysql_real_connect(MYSQL *mysql,const char *host, const char *user,
const char *passwd, const char *db, static inline int mysql_init_charset(MYSQL *mysql)
uint port, const char *unix_socket,uint client_flag)
{ {
char buff[100],charset_name_buff[16],*end,*host_info, *charset_name; char charset_name_buff[16], *charset_name;
uint pkt_length;
ulong max_allowed_packet;
NET *net= &mysql->net;
DBUG_ENTER("mysql_real_connect");
DBUG_PRINT("enter",("host: %s db: %s user: %s",
host ? host : "(Null)",
db ? db : "(Null)",
user ? user : "(Null)"));
net->vio = 0; /* If something goes wrong */
/* use default options */
if (mysql->options.my_cnf_file || mysql->options.my_cnf_group)
{
mysql_read_default_options(&mysql->options,
(mysql->options.my_cnf_file ?
mysql->options.my_cnf_file : "my"),
mysql->options.my_cnf_group);
my_free(mysql->options.my_cnf_file,MYF(MY_ALLOW_ZERO_PTR));
my_free(mysql->options.my_cnf_group,MYF(MY_ALLOW_ZERO_PTR));
mysql->options.my_cnf_file=mysql->options.my_cnf_group=0;
}
/* Some empty-string-tests are done because of ODBC */
if (!host || !host[0])
host=mysql->options.host;
if (!user || !user[0])
user=mysql->options.user;
if (!passwd)
{
passwd=mysql->options.password;
}
if (!db || !db[0])
db=mysql->options.db;
port=0;
unix_socket=0;
mysql->reconnect=1; /* Reconnect as default */
mysql->server_status=SERVER_STATUS_AUTOCOMMIT;
host_info=(char*) ER(CR_EMBEDDED_CONNECTION);
if (my_net_init(net, net->vio))
{
vio_delete(net->vio);
net->last_errno=CR_OUT_OF_MEMORY;
strmov(net->last_error,ER(net->last_errno));
goto error;
}
/* Get version info */
mysql->protocol_version= PROTOCOL_VERSION; /* Assume this */
start_embedded_connection(net);
if ((pkt_length=net_safe_read(mysql)) == packet_error)
goto error;
/* Check if version of protocoll matches current one */
mysql->protocol_version= net->read_pos[0];
DBUG_DUMP("packet",(char*) net->read_pos,10);
DBUG_PRINT("info",("mysql protocol version %d, server=%d",
PROTOCOL_VERSION, mysql->protocol_version));
if (mysql->protocol_version != PROTOCOL_VERSION &&
mysql->protocol_version != PROTOCOL_VERSION-1)
{
net->last_errno= CR_VERSION_ERROR;
sprintf(net->last_error, ER(CR_VERSION_ERROR), mysql->protocol_version,
PROTOCOL_VERSION);
goto error;
}
end=strend((char*) net->read_pos+1);
mysql->thread_id=uint4korr(end+1);
end+=5;
strmake(mysql->scramble_buff,end,8);
end+=9;
if (pkt_length >= (uint) (end+1 - (char*) net->read_pos))
mysql->server_capabilities=uint2korr(end);
if (pkt_length >= (uint) (end+18 - (char*) net->read_pos))
{
/* New protocol with 16 bytes to describe server characteristics */
mysql->server_language=end[2];
mysql->server_status=uint2korr(end+3);
}
/* Set character set */
if ((charset_name=mysql->options.charset_name)) if ((charset_name=mysql->options.charset_name))
{ {
const char *save=charsets_dir; const char *save=charsets_dir;
@ -900,89 +787,94 @@ mysql_real_connect(MYSQL *mysql,const char *host, const char *user,
if (!mysql->charset) if (!mysql->charset)
{ {
net->last_errno=CR_CANT_READ_CHARSET; mysql->net.last_errno=CR_CANT_READ_CHARSET;
if (mysql->options.charset_dir) if (mysql->options.charset_dir)
sprintf(net->last_error,ER(net->last_errno), sprintf(mysql->net.last_error,ER(mysql->net.last_errno),
charset_name ? charset_name : "unknown", charset_name ? charset_name : "unknown",
mysql->options.charset_dir); mysql->options.charset_dir);
else else
{ {
char cs_dir_name[FN_REFLEN]; char cs_dir_name[FN_REFLEN];
get_charsets_dir(cs_dir_name); get_charsets_dir(cs_dir_name);
sprintf(net->last_error,ER(net->last_errno), sprintf(mysql->net.last_error,ER(mysql->net.last_errno),
charset_name ? charset_name : "unknown", charset_name ? charset_name : "unknown",
cs_dir_name); cs_dir_name);
} }
return mysql->net.last_errno;
}
return 0;
}
/*
** Note that the mysql argument must be initialized with mysql_init()
** before calling mysql_real_connect !
*/
MYSQL * STDCALL
mysql_real_connect(MYSQL *mysql,const char *host, const char *user,
const char *passwd __attribute__((unused)), const char *db,
uint port, const char *unix_socket,uint client_flag)
{
ulong max_allowed_packet;
NET *net= &mysql->net;
char *db_name;
DBUG_ENTER("mysql_real_connect");
DBUG_PRINT("enter",("host: %s db: %s user: %s",
host ? host : "(Null)",
db ? db : "(Null)",
user ? user : "(Null)"));
/* use default options */
if (mysql->options.my_cnf_file || mysql->options.my_cnf_group)
{
mysql_read_default_options(&mysql->options,
(mysql->options.my_cnf_file ?
mysql->options.my_cnf_file : "my"),
mysql->options.my_cnf_group);
my_free(mysql->options.my_cnf_file,MYF(MY_ALLOW_ZERO_PTR));
my_free(mysql->options.my_cnf_group,MYF(MY_ALLOW_ZERO_PTR));
mysql->options.my_cnf_file=mysql->options.my_cnf_group=0;
}
if (!db || !db[0])
db=mysql->options.db;
port=0;
unix_socket=0;
db_name = db ? my_strdup(db,MYF(MY_WME)) : NULL;
create_vio(net, mysql->options.separate_thread);
if (my_net_init(net, net->vio))
{
vio_delete(net->vio);
net->last_errno=CR_OUT_OF_MEMORY;
strmov(net->last_error,ER(net->last_errno));
goto error; goto error;
} }
/* Save connection information */ set_thd(net->vio, create_embedded_thd(net->vio, net->buff, client_flag, db_name));
if (!user) user="";
if (!passwd) passwd=""; init_embedded_mysql(mysql, client_flag, db_name);
host=LOCAL_HOST;
if (!my_multi_malloc(MYF(0), if (mysql_init_charset(mysql))
&mysql->host_info, (uint) strlen(host_info)+1,
&mysql->host, (uint) strlen(host)+1,
&mysql->unix_socket,unix_socket ?
(uint) strlen(unix_socket)+1 : (uint) 1,
&mysql->server_version,
(uint) (end - (char*) net->read_pos),
NullS) ||
!(mysql->user=my_strdup(user,MYF(0))) ||
!(mysql->passwd=my_strdup(passwd,MYF(0))))
{
strmov(net->last_error, ER(net->last_errno=CR_OUT_OF_MEMORY));
goto error; goto error;
}
strmov(mysql->host_info,host_info);
strmov(mysql->host,host);
if (unix_socket)
strmov(mysql->unix_socket,unix_socket);
else
mysql->unix_socket=0;
strmov(mysql->server_version,(char*) net->read_pos+1);
mysql->port=port;
mysql->client_flag=client_flag | mysql->options.client_flag;
DBUG_PRINT("info",("Server version = '%s' capabilites: %ld status: %d",
mysql->server_version,mysql->server_capabilities,
mysql->server_status));
/* Send client information for access check */ /* Send client information for access check */
client_flag|=CLIENT_CAPABILITIES; client_flag|=CLIENT_CAPABILITIES;
client_flag&= ~CLIENT_COMPRESS; client_flag&= ~CLIENT_COMPRESS;
if (db) if (db)
client_flag|=CLIENT_CONNECT_WITH_DB; client_flag|=CLIENT_CONNECT_WITH_DB;
int2store(buff,client_flag);
mysql->client_flag=client_flag;
max_allowed_packet=net->max_packet_size; max_allowed_packet=net->max_packet_size;
int3store(buff+2,max_allowed_packet);
if (user && user[0])
strmake(buff+5,user,32);
else
read_user_name((char*) buff+5);
#ifdef _CUSTOMCONFIG_
#include "_cust_libmysql.h";
#endif
DBUG_PRINT("info",("user: %s",buff+5));
end=scramble(strend(buff+5)+1, mysql->scramble_buff, passwd,
(my_bool) (mysql->protocol_version == 9));
if (db) if (db)
{ {
end=strmov(end+1,db);
mysql->db=my_strdup(db,MYF(MY_WME)); mysql->db=my_strdup(db,MYF(MY_WME));
db=0; db=0;
} }
if (my_net_write(net,buff,(ulong) (end-buff)) || net_flush(net))
goto error;
lib_connection_phase(net,2); /****
net->timeout=net_read_timeout;
if( net_safe_read(mysql) == packet_error) */
goto error;
if (db && mysql_select_db(mysql,db))
goto error;
if (mysql->options.init_command) if (mysql->options.init_command)
{ {
my_bool reconnect=mysql->reconnect; my_bool reconnect=mysql->reconnect;
@ -1122,59 +1014,22 @@ mysql_query(MYSQL *mysql, const char *query)
return mysql_real_query(mysql,query, (ulong) strlen(query)); return mysql_real_query(mysql,query, (ulong) strlen(query));
} }
int STDCALL
mysql_send_query(MYSQL* mysql, const char* query, ulong length)
{
return simple_command(mysql, COM_QUERY, query, length, 1);
}
my_bool STDCALL my_bool STDCALL
mysql_read_query_result(MYSQL *mysql) mysql_read_query_result(MYSQL *mysql)
{ {
uchar *pos; NET *net= get_mysql_net(mysql);
ulong field_count;
MYSQL_DATA *fields;
uint length;
DBUG_ENTER("mysql_read_query_result");
if ((length=net_safe_read(mysql)) == packet_error) if (net->last_errno)
DBUG_RETURN(1); return -1;
free_old_query(mysql); /* Free old result */
get_info:
pos=(uchar*) mysql->net.read_pos;
if ((field_count= net_field_length(&pos)) == 0)
{
mysql->affected_rows= net_field_length_ll(&pos);
mysql->insert_id= net_field_length_ll(&pos);
mysql->server_status=uint2korr(pos); pos+=2;
mysql->warning_count=uint2korr(pos); pos+=2;
if (pos < mysql->net.read_pos+length && net_field_length(&pos))
mysql->info=(char*) pos;
DBUG_RETURN(0);
}
if (field_count == NULL_LENGTH) /* LOAD DATA LOCAL INFILE */
{
int error=send_file_to_server(mysql,(char*) pos);
if ((length=net_safe_read(mysql)) == packet_error || error)
DBUG_RETURN(1);
goto get_info; /* Get info packet */
}
if (!(mysql->server_status & SERVER_STATUS_AUTOCOMMIT))
mysql->server_status|= SERVER_STATUS_IN_TRANS;
mysql->extra_info= net_field_length_ll(&pos); /* Maybe number of rec */ if (mysql->field_count)
if (!(fields=read_rows(mysql,(MYSQL_FIELD*) 0,5))) {
DBUG_RETURN(1); mysql->status=MYSQL_STATUS_GET_RESULT;
if (!(mysql->fields=unpack_fields(fields,&mysql->field_alloc, mysql->affected_rows= mysql->result->row_count= mysql->result->data->rows;
(uint) field_count,0, mysql->result->data_cursor= mysql->result->data->data;
(my_bool) test(mysql->server_capabilities & }
CLIENT_LONG_FLAG))))
DBUG_RETURN(1); return 0;
mysql->status=MYSQL_STATUS_GET_RESULT;
mysql->field_count=field_count;
mysql->warning_count= 0;
DBUG_RETURN(0);
} }
/**************************************************************************** /****************************************************************************
@ -1277,15 +1132,25 @@ my_bool my_connect(my_socket s, const struct sockaddr *name, uint namelen,
#endif #endif
} }
int STDCALL int STDCALL
mysql_real_query(MYSQL *mysql, const char *query, ulong length) mysql_real_query(MYSQL *mysql, const char *query, ulong length)
{ {
DBUG_ENTER("mysql_real_query"); DBUG_ENTER("mysql_real_query");
DBUG_PRINT("enter",("handle: %lx",mysql)); DBUG_PRINT("enter",("handle: %lx",mysql));
DBUG_PRINT("query",("Query = \"%s\"",query)); DBUG_PRINT("query",("Query = \"%s\"",query));
if (mysql_send_query(mysql, query, length))
if (mysql->options.separate_thread)
{
return -1;
}
mysql->result= NULL;
free_old_query(mysql); /* Free old result */
if (simple_command(mysql, COM_QUERY, query, length, 1))
DBUG_RETURN(-1); DBUG_RETURN(-1);
DBUG_RETURN(mysql_read_query_result(mysql)); DBUG_RETURN(mysql_read_query_result(mysql));
} }
@ -1350,48 +1215,23 @@ send_file_to_server(MYSQL *mysql, const char *filename)
** Alloc result struct for buffered results. All rows are read to buffer. ** Alloc result struct for buffered results. All rows are read to buffer.
** mysql_data_seek may be used. ** mysql_data_seek may be used.
**************************************************************************/ **************************************************************************/
MYSQL_RES * STDCALL MYSQL_RES * STDCALL
mysql_store_result(MYSQL *mysql) mysql_store_result(MYSQL *mysql)
{ {
MYSQL_RES *result; MYSQL_RES *result= mysql->result;
DBUG_ENTER("mysql_store_result"); if (!result)
return 0;
if (!mysql->fields) mysql->result= NULL;
DBUG_RETURN(0); *result->data->prev_ptr= 0;
if (mysql->status != MYSQL_STATUS_GET_RESULT) result->eof= 1;
{ result->lengths= (ulong*)(result + 1);
strmov(mysql->net.last_error,
ER(mysql->net.last_errno=CR_COMMANDS_OUT_OF_SYNC));
DBUG_RETURN(0);
}
mysql->status=MYSQL_STATUS_READY; /* server is ready */
if (!(result=(MYSQL_RES*) my_malloc(sizeof(MYSQL_RES)+
sizeof(ulong)*mysql->field_count,
MYF(MY_WME | MY_ZEROFILL))))
{
mysql->net.last_errno=CR_OUT_OF_MEMORY;
strmov(mysql->net.last_error, ER(mysql->net.last_errno));
DBUG_RETURN(0);
}
result->eof=1; /* Marker for buffered */
result->lengths=(ulong*) (result+1);
if (!(result->data=read_rows(mysql,mysql->fields,mysql->field_count)))
{
my_free((gptr) result,MYF(0));
DBUG_RETURN(0);
}
mysql->affected_rows= result->row_count= result->data->rows; mysql->affected_rows= result->row_count= result->data->rows;
result->data_cursor= result->data->data; result->data_cursor= result->data->data;
result->fields= mysql->fields;
result->field_alloc= mysql->field_alloc;
result->field_count= mysql->field_count;
result->current_field=0;
result->current_row=0; /* Must do a fetch first */
mysql->fields=0; /* fields is now in result */
DBUG_RETURN(result); /* Data fetched */
}
mysql->status=MYSQL_STATUS_READY; /* server is ready */
return result;
}
/************************************************************************** /**************************************************************************
** Alloc struct for use with unbuffered reads. Data is fetched by domand ** Alloc struct for use with unbuffered reads. Data is fetched by domand
@ -1406,41 +1246,13 @@ mysql_store_result(MYSQL *mysql)
MYSQL_RES * STDCALL MYSQL_RES * STDCALL
mysql_use_result(MYSQL *mysql) mysql_use_result(MYSQL *mysql)
{ {
MYSQL_RES *result;
DBUG_ENTER("mysql_use_result"); DBUG_ENTER("mysql_use_result");
if (mysql->options.separate_thread)
DBUG_RETURN(0);
if (!mysql->fields) DBUG_RETURN(mysql_store_result(mysql));
DBUG_RETURN(0);
if (mysql->status != MYSQL_STATUS_GET_RESULT)
{
strmov(mysql->net.last_error,
ER(mysql->net.last_errno=CR_COMMANDS_OUT_OF_SYNC));
DBUG_RETURN(0);
}
if (!(result=(MYSQL_RES*) my_malloc(sizeof(*result)+
sizeof(ulong)*mysql->field_count,
MYF(MY_WME | MY_ZEROFILL))))
DBUG_RETURN(0);
result->lengths=(ulong*) (result+1);
if (!(result->row=(MYSQL_ROW)
my_malloc(sizeof(result->row[0])*(mysql->field_count+1), MYF(MY_WME))))
{ /* Ptrs: to one row */
my_free((gptr) result,MYF(0));
DBUG_RETURN(0);
}
result->fields= mysql->fields;
result->field_alloc= mysql->field_alloc;
result->field_count= mysql->field_count;
result->current_field=0;
result->handle= mysql;
result->current_row= 0;
mysql->fields=0; /* fields is now in result */
mysql->status=MYSQL_STATUS_USE_RESULT;
DBUG_RETURN(result); /* Data is read to be fetched */
} }
/************************************************************************** /**************************************************************************
** Return next field of the query results ** Return next field of the query results
**************************************************************************/ **************************************************************************/
@ -1788,6 +1600,9 @@ mysql_options(MYSQL *mysql,enum mysql_option option, const char *arg)
case MYSQL_OPT_COMPRESS: case MYSQL_OPT_COMPRESS:
mysql->options.compress=1; /* Remember for connect */ mysql->options.compress=1; /* Remember for connect */
break; break;
case MYSQL_OPT_USE_RESULT:
mysql->options.separate_thread=1; /* Use separate thread for query execution*/
break;
case MYSQL_OPT_NAMED_PIPE: case MYSQL_OPT_NAMED_PIPE:
mysql->options.named_pipe=1; /* Force named pipe */ mysql->options.named_pipe=1; /* Force named pipe */
break; break;
@ -1877,12 +1692,12 @@ my_ulonglong STDCALL mysql_insert_id(MYSQL *mysql)
uint STDCALL mysql_errno(MYSQL *mysql) uint STDCALL mysql_errno(MYSQL *mysql)
{ {
return (mysql)->net.last_errno; return get_mysql_net(mysql)->last_errno;
} }
const char * STDCALL mysql_error(MYSQL *mysql) const char * STDCALL mysql_error(MYSQL *mysql)
{ {
return (mysql)->net.last_error; return get_mysql_net(mysql)->last_error;
} }
uint STDCALL mysql_warning_count(MYSQL *mysql) uint STDCALL mysql_warning_count(MYSQL *mysql)

View File

@ -473,3 +473,12 @@ bool CONVERT::store(String *packet,const char *from,uint length)
packet->length((uint) (to-packet->ptr())); packet->length((uint) (to-packet->ptr()));
return 0; return 0;
} }
#ifdef EMBEDDED_LIBRARY
void CONVERT::convert_back(char *dest, const char *source, uint length) const
{
for (char *end= dest+length; dest < end; dest++, source++)
*dest= to_map[*source];
}
#endif

View File

@ -4472,7 +4472,7 @@ void Field_blob::set_key_image(char *buff,uint length)
void Field_geom::get_key_image(char *buff,uint length, imagetype type) void Field_geom::get_key_image(char *buff,uint length, imagetype type)
{ {
length-=HA_KEY_BLOB_LENGTH; /* length-=HA_KEY_BLOB_LENGTH;
ulong blob_length=get_length(ptr); ulong blob_length=get_length(ptr);
char *blob; char *blob;
get_ptr(&blob); get_ptr(&blob);
@ -4487,12 +4487,19 @@ void Field_geom::get_key_image(char *buff,uint length, imagetype type)
float8store(buff+16, mbr.ymin); float8store(buff+16, mbr.ymin);
float8store(buff+24, mbr.ymax); float8store(buff+24, mbr.ymax);
return; return;
*/
Field_blob::get_key_image(buff, length, type);
} }
void Field_geom::set_key_image(char *buff,uint length) void Field_geom::set_key_image(char *buff,uint length)
{ {
Field_blob::set_key_image(buff, length);
} }
void Field_geom::sql_type(String &res) const
{
res.set("geometry", 8U, default_charset_info);
}
int Field_blob::key_cmp(const byte *key_ptr, uint max_key_length) int Field_blob::key_cmp(const byte *key_ptr, uint max_key_length)
{ {
@ -5163,6 +5170,7 @@ uint32 calc_pack_length(enum_field_types type,uint32 length)
case FIELD_TYPE_BLOB: return 2+portable_sizeof_char_ptr; case FIELD_TYPE_BLOB: return 2+portable_sizeof_char_ptr;
case FIELD_TYPE_MEDIUM_BLOB: return 3+portable_sizeof_char_ptr; case FIELD_TYPE_MEDIUM_BLOB: return 3+portable_sizeof_char_ptr;
case FIELD_TYPE_LONG_BLOB: return 4+portable_sizeof_char_ptr; case FIELD_TYPE_LONG_BLOB: return 4+portable_sizeof_char_ptr;
case FIELD_TYPE_GEOMETRY: return 2+portable_sizeof_char_ptr;
case FIELD_TYPE_SET: case FIELD_TYPE_SET:
case FIELD_TYPE_ENUM: abort(); return 0; // This shouldn't happen case FIELD_TYPE_ENUM: abort(); return 0; // This shouldn't happen
default: return 0; default: return 0;
@ -5209,15 +5217,15 @@ Field *make_field(char *ptr, uint32 field_length,
f_packtype(pack_flag), f_packtype(pack_flag),
field_length); field_length);
if (f_is_blob(pack_flag))
return new Field_blob(ptr,null_pos,null_bit,
unireg_check, field_name, table,
pack_length, field_charset);
if (f_is_geom(pack_flag)) if (f_is_geom(pack_flag))
return new Field_geom(ptr,null_pos,null_bit, return new Field_geom(ptr,null_pos,null_bit,
unireg_check, field_name, table, unireg_check, field_name, table,
pack_length); pack_length,f_is_binary(pack_flag) != 0);
if (f_is_blob(pack_flag))
return new Field_blob(ptr,null_pos,null_bit,
unireg_check, field_name, table,
pack_length,f_is_binary(pack_flag) != 0,
default_charset_info);
if (interval) if (interval)
{ {
if (f_is_enum(pack_flag)) if (f_is_enum(pack_flag))

View File

@ -922,6 +922,8 @@ public:
:Field_blob(len_arg, maybe_null_arg, field_name_arg, :Field_blob(len_arg, maybe_null_arg, field_name_arg,
table_arg, my_charset_bin) {} table_arg, my_charset_bin) {}
enum ha_base_keytype key_type() const { return HA_KEYTYPE_VARBINARY; } enum ha_base_keytype key_type() const { return HA_KEYTYPE_VARBINARY; }
enum_field_types type() const { return FIELD_TYPE_GEOMETRY;}
void sql_type(String &str) const;
void get_key_image(char *buff,uint length, imagetype type); void get_key_image(char *buff,uint length, imagetype type);
void set_key_image(char *buff,uint length); void set_key_image(char *buff,uint length);

View File

@ -79,7 +79,7 @@ static void mi_check_print_msg(MI_CHECK *param, const char* msg_type,
net_store_data(packet, msg_type); net_store_data(packet, msg_type);
net_store_data(packet, msgbuf); net_store_data(packet, msgbuf);
if (my_net_write(&thd->net, (char*)thd->packet.ptr(), thd->packet.length())) if (SEND_ROW(thd, 4, (char*)thd->packet.ptr(), thd->packet.length()))
sql_print_error("Failed on my_net_write, writing to stderr instead: %s\n", sql_print_error("Failed on my_net_write, writing to stderr instead: %s\n",
msgbuf); msgbuf);
return; return;
@ -1097,7 +1097,7 @@ int ha_myisam::create(const char *name, register TABLE *table,
keydef[i].flag|=HA_AUTO_KEY; keydef[i].flag|=HA_AUTO_KEY;
found_auto_increment=1; found_auto_increment=1;
} }
if (field->type() == FIELD_TYPE_BLOB) if ((field->type() == FIELD_TYPE_BLOB) || (field->type() == FIELD_TYPE_GEOMETRY))
{ {
keydef[i].seg[j].flag|=HA_BLOB_PART; keydef[i].seg[j].flag|=HA_BLOB_PART;
/* save number of bytes used to pack length */ /* save number of bytes used to pack length */

View File

@ -444,6 +444,9 @@ bool Item_field::fix_fields(THD *thd, TABLE_LIST *tables, Item **ref)
cause error ER_NON_UNIQ_ERROR in find_field_in_tables. cause error ER_NON_UNIQ_ERROR in find_field_in_tables.
*/ */
SELECT_LEX *last= 0; SELECT_LEX *last= 0;
#ifdef EMBEDDED_LIBRARY
thd->net.last_errno= 0;
#endif
for (SELECT_LEX *sl= thd->lex.current_select->outer_select(); for (SELECT_LEX *sl= thd->lex.current_select->outer_select();
sl; sl;
sl= sl->outer_select()) sl= sl->outer_select())
@ -797,11 +800,64 @@ bool Item::send(THD *thd, String *packet)
return net_store_data(packet,res->ptr(),res->length()); return net_store_data(packet,res->ptr(),res->length());
} }
bool Item_null::send(THD *thd, String *packet) bool Item_null::send(THD *thd, String *packet)
{ {
return net_store_null(packet); return net_store_null(packet);
} }
#ifdef EMBEDDED_LIBRARY
bool Item::embedded_send(const CONVERT *convert, CHARSET_INFO *charset, MEM_ROOT *alloc,
char **result, ulong *length)
{
char buff[MAX_FIELD_WIDTH];
String s(buff, sizeof(buff), charset), *value;
if (!(value=val_str(&s)) ||
!(*result=alloc_root(alloc, value->length() + 1)))
return true;
*length= value->length();
if (convert)
convert->convert_back(*result, value->ptr(), *length);
else
memcpy(*result, value->ptr(), *length);
(*result)[*length]= 0;
return false;
}
bool Item_null::embedded_send(const CONVERT *convert, CHARSET_INFO *charset, MEM_ROOT *alloc,
char **result, ulong *length)
{
*result= NULL;
return false;
}
bool Item_field::embedded_send(const CONVERT *convert, CHARSET_INFO *charset, MEM_ROOT *alloc,
char **result, ulong *length)
{
if (result_field->is_null())
{
result= NULL;
return false;
}
char buff[MAX_FIELD_WIDTH];
String tmp(buff,sizeof(buff),default_charset_info);
result_field->val_str(&tmp,&tmp);
if (!(*result=alloc_root(alloc, tmp.length() + 1)))
return true;
*length= tmp.length();
if (convert)
convert->convert_back(*result, tmp.ptr(), *length);
else
memcpy(*result, tmp.ptr(), *length);
(*result)[*length]= 0;
return false;
}
#endif
/* /*
This is used for HAVING clause This is used for HAVING clause
Find field in select list having the same name Find field in select list having the same name

View File

@ -22,6 +22,8 @@
struct st_table_list; struct st_table_list;
void item_init(void); /* Init item functions */ void item_init(void); /* Init item functions */
class CONVERT;
class Item { class Item {
Item(const Item &); /* Prevent use of these */ Item(const Item &); /* Prevent use of these */
void operator=(Item &); void operator=(Item &);
@ -58,6 +60,10 @@ public:
virtual int save_safe_in_field(Field *field) virtual int save_safe_in_field(Field *field)
{ return save_in_field(field); } { return save_in_field(field); }
virtual bool send(THD *thd, String *str); virtual bool send(THD *thd, String *str);
#ifdef EMBEDDED_LIBRARY
virtual bool embedded_send(const CONVERT *convert, CHARSET_INFO *charset, MEM_ROOT *alloc,
char **result, ulong *length);
#endif
virtual bool eq(const Item *, bool binary_cmp) const; virtual bool eq(const Item *, bool binary_cmp) const;
virtual Item_result result_type () const { return REAL_RESULT; } virtual Item_result result_type () const { return REAL_RESULT; }
virtual enum Type type() const =0; virtual enum Type type() const =0;
@ -133,6 +139,10 @@ public:
{ {
return result_field->send(thd,str_arg); return result_field->send(thd,str_arg);
} }
#ifdef EMBEDDED_LIBRARY
bool embedded_send(const CONVERT *convert, CHARSET_INFO *charset, MEM_ROOT *alloc,
char **result, ulong *length);
#endif
void make_field(Send_field *field); void make_field(Send_field *field);
bool fix_fields(THD *, struct st_table_list *, Item **); bool fix_fields(THD *, struct st_table_list *, Item **);
int save_in_field(Field *field); int save_in_field(Field *field);
@ -165,6 +175,10 @@ public:
enum Item_result result_type () const enum Item_result result_type () const
{ return STRING_RESULT; } { return STRING_RESULT; }
bool send(THD *thd, String *str); bool send(THD *thd, String *str);
#ifdef EMBEDDED_LIBRARY
bool embedded_send(const CONVERT *convert, CHARSET_INFO *charset, MEM_ROOT *alloc,
char **result, ulong *length);
#endif
bool basic_const_item() const { return 1; } bool basic_const_item() const { return 1; }
Item *new_item() { return new Item_null(name); } Item *new_item() { return new Item_null(name); }
bool is_null() { return 1; } bool is_null() { return 1; }
@ -428,6 +442,11 @@ public:
return (null_value=(*ref)->get_date(ltime,fuzzydate)); return (null_value=(*ref)->get_date(ltime,fuzzydate));
} }
bool send(THD *thd, String *tmp) { return (*ref)->send(thd, tmp); } bool send(THD *thd, String *tmp) { return (*ref)->send(thd, tmp); }
#ifdef EMBEDDED_LIBRARY
bool embedded_send(const CONVERT *convert, CHARSET_INFO *charset, MEM_ROOT *alloc,
char **result, ulong *length)
{ return (*ref)->embedded_send(convert, charset, alloc, result, length); }
#endif
void make_field(Send_field *field) { (*ref)->make_field(field); } void make_field(Send_field *field) { (*ref)->make_field(field); }
bool fix_fields(THD *, struct st_table_list *, Item **); bool fix_fields(THD *, struct st_table_list *, Item **);
int save_in_field(Field *field) { return (*ref)->save_in_field(field); } int save_in_field(Field *field) { return (*ref)->save_in_field(field); }

View File

@ -1373,10 +1373,15 @@ String *Item_func_database::val_str(String *str)
String *Item_func_user::val_str(String *str) String *Item_func_user::val_str(String *str)
{ {
THD *thd=current_thd; THD *thd=current_thd;
#ifdef EMBEDDED_LIBRARY
if (str->copy("localuser@localhost", (uint)strlen("localuser@localhost")))
return &empty_string;
#else
if (str->copy((const char*) thd->user,(uint) strlen(thd->user), system_charset_info) || if (str->copy((const char*) thd->user,(uint) strlen(thd->user), system_charset_info) ||
str->append('@') || str->append('@') ||
str->append(thd->host ? thd->host : thd->ip ? thd->ip : "")) str->append(thd->host ? thd->host : thd->ip ? thd->ip : ""))
return &empty_string; return &empty_string;
#endif
return str; return str;
} }

View File

@ -867,3 +867,13 @@ inline void mark_as_null_row(TABLE *table)
table->status|=STATUS_NULL_ROW; table->status|=STATUS_NULL_ROW;
bfill(table->null_flags,table->null_bytes,255); bfill(table->null_flags,table->null_bytes,255);
} }
#ifdef EMBEDDED_LIBRARY
int embedded_send_row(THD *thd, int n_fields, char *data, int data_len);
#define SEND_ROW(thd, n_fields, data, data_len)\
embedded_send_row(thd, n_fields, data, data_len)
#else
#define SEND_ROW(thd, n_fields, data, data_len)\
my_net_write(&thd->net, data, data_len)
#endif

View File

@ -1768,7 +1768,496 @@ bool open_log(MYSQL_LOG *log, const char *hostname,
no_auto_events); no_auto_events);
} }
static int init_common_variables(const char *conf_file_name, int argc, char **argv,
const char **groups)
{
my_umask=0660; // Default umask for new files
my_umask_dir=0700; // Default umask for new directories
umask(((~my_umask) & 0666));
tzset(); // Set tzname
start_time=time((time_t*) 0);
#ifdef OS2
{
// fix timezone for daylight saving
struct tm *ts = localtime(&start_time);
if (ts->tm_isdst > 0)
_timezone -= 3600;
}
#endif
#ifdef HAVE_TZNAME
#if defined(HAVE_LOCALTIME_R) && defined(_REENTRANT)
{
struct tm tm_tmp;
localtime_r(&start_time,&tm_tmp);
strmov(time_zone,tzname[tm_tmp.tm_isdst != 0 ? 1 : 0]);
}
#else
{
struct tm *start_tm;
start_tm=localtime(&start_time);
strmov(time_zone,tzname[start_tm->tm_isdst != 0 ? 1 : 0]);
}
#endif
#endif
if (gethostname(glob_hostname,sizeof(glob_hostname)-4) < 0)
strmov(glob_hostname,"mysql");
#ifndef DBUG_OFF
strxmov(strend(server_version),MYSQL_SERVER_SUFFIX,"-debug",NullS);
#else
strmov(strend(server_version),MYSQL_SERVER_SUFFIX);
#endif
load_defaults(conf_file_name, groups, &argc, &argv);
defaults_argv=argv;
set_options();
get_options(argc,argv);
if (opt_log || opt_update_log || opt_slow_log || opt_bin_log)
strcat(server_version,"-log");
DBUG_PRINT("info",("%s Ver %s for %s on %s\n",my_progname,
server_version, SYSTEM_TYPE,MACHINE_TYPE));
#if defined( SET_RLIMIT_NOFILE) || defined( OS2)
/* connections and databases needs lots of files */
{
uint wanted_files=10+(uint) max(max_connections*5,
max_connections+table_cache_size*2);
set_if_bigger(wanted_files, open_files_limit);
// Note that some system returns 0 if we succeed here:
uint files=set_maximum_open_files(wanted_files);
if (files && files < wanted_files && ! open_files_limit)
{
max_connections= (ulong) min((files-10),max_connections);
table_cache_size= (ulong) max((files-10-max_connections)/2,64);
DBUG_PRINT("warning",
("Changed limits: max_connections: %ld table_cache: %ld",
max_connections,table_cache_size));
sql_print_error("Warning: Changed limits: max_connections: %ld table_cache: %ld",max_connections,table_cache_size);
}
}
#endif
unireg_init(opt_specialflag); /* Set up extern variabels */
init_errmessage(); /* Read error messages from file */
lex_init();
item_init();
set_var_init();
mysys_uses_curses=0;
#ifdef USE_REGEX
regex_init();
#endif
if (set_default_charset_by_name(sys_charset.value, MYF(MY_WME)))
return 1;
charsets_list= list_charsets(MYF(MY_CS_COMPILED | MY_CS_CONFIG));
if (use_temp_pool && bitmap_init(&temp_pool,1024,1))
return 2;
return 0;
}
static int init_thread_environement()
{
(void) pthread_mutex_init(&LOCK_mysql_create_db,MY_MUTEX_INIT_SLOW);
(void) pthread_mutex_init(&LOCK_Acl,MY_MUTEX_INIT_SLOW);
(void) pthread_mutex_init(&LOCK_open,MY_MUTEX_INIT_FAST);
(void) pthread_mutex_init(&LOCK_thread_count,MY_MUTEX_INIT_FAST);
(void) pthread_mutex_init(&LOCK_mapped_file,MY_MUTEX_INIT_SLOW);
(void) pthread_mutex_init(&LOCK_status,MY_MUTEX_INIT_FAST);
(void) pthread_mutex_init(&LOCK_error_log,MY_MUTEX_INIT_FAST);
(void) pthread_mutex_init(&LOCK_delayed_insert,MY_MUTEX_INIT_FAST);
(void) pthread_mutex_init(&LOCK_delayed_status,MY_MUTEX_INIT_FAST);
(void) pthread_mutex_init(&LOCK_delayed_create,MY_MUTEX_INIT_SLOW);
(void) pthread_mutex_init(&LOCK_manager,MY_MUTEX_INIT_FAST);
(void) pthread_mutex_init(&LOCK_crypt,MY_MUTEX_INIT_FAST);
(void) pthread_mutex_init(&LOCK_bytes_sent,MY_MUTEX_INIT_FAST);
(void) pthread_mutex_init(&LOCK_bytes_received,MY_MUTEX_INIT_FAST);
(void) pthread_mutex_init(&LOCK_timezone,MY_MUTEX_INIT_FAST);
(void) pthread_mutex_init(&LOCK_user_conn, MY_MUTEX_INIT_FAST);
(void) pthread_mutex_init(&LOCK_rpl_status, MY_MUTEX_INIT_FAST);
(void) pthread_mutex_init(&LOCK_active_mi, MY_MUTEX_INIT_FAST);
(void) pthread_mutex_init(&LOCK_global_system_variables, MY_MUTEX_INIT_FAST);
(void) my_rwlock_init(&LOCK_grant, NULL);
(void) pthread_cond_init(&COND_thread_count,NULL);
(void) pthread_cond_init(&COND_refresh,NULL);
(void) pthread_cond_init(&COND_thread_cache,NULL);
(void) pthread_cond_init(&COND_flush_thread_cache,NULL);
(void) pthread_cond_init(&COND_manager,NULL);
(void) pthread_cond_init(&COND_rpl_status, NULL);
/* Parameter for threads created for connections */
(void) pthread_attr_init(&connection_attrib);
(void) pthread_attr_setdetachstate(&connection_attrib,
PTHREAD_CREATE_DETACHED);
pthread_attr_setstacksize(&connection_attrib,thread_stack);
pthread_attr_setscope(&connection_attrib, PTHREAD_SCOPE_SYSTEM);
if (pthread_key_create(&THR_THD,NULL) ||
pthread_key_create(&THR_MALLOC,NULL))
{
sql_print_error("Can't create thread-keys");
return 1;
}
(void) thr_setconcurrency(concurrency); // 10 by default
return 0;
}
static void init_ssl()
{
#ifdef HAVE_OPENSSL
if (opt_use_ssl)
{
/* having ssl_acceptor_fd != 0 signals the use of SSL */
ssl_acceptor_fd= new_VioSSLAcceptorFd(opt_ssl_key, opt_ssl_cert,
opt_ssl_ca, opt_ssl_capath,
opt_ssl_cipher);
DBUG_PRINT("info",("ssl_acceptor_fd: %lx", (long) ssl_acceptor_fd));
if (!ssl_acceptor_fd)
opt_use_ssl = 0;
}
if (des_key_file)
load_des_key_file(des_key_file);
#endif /* HAVE_OPENSSL */
}
static int init_server_components()
{
table_cache_init();
hostname_cache_init();
query_cache_result_size_limit(query_cache_limit);
query_cache_resize(query_cache_size);
randominit(&sql_rand,(ulong) start_time,(ulong) start_time/2);
reset_floating_point_exceptions();
init_thr_lock();
init_slave_list();
/* Setup log files */
if (opt_log)
open_log(&mysql_log, glob_hostname, opt_logname, ".log", NullS,
LOG_NORMAL);
if (opt_update_log)
{
open_log(&mysql_update_log, glob_hostname, opt_update_logname, "",
NullS, LOG_NEW);
using_update_log=1;
}
if (opt_slow_log)
open_log(&mysql_slow_log, glob_hostname, opt_slow_logname, "-slow.log",
NullS, LOG_NORMAL);
if (ha_init())
{
sql_print_error("Can't init databases");
return 1;
}
ha_key_cache();
#if defined(HAVE_MLOCKALL) && defined(MCL_CURRENT)
if (locked_in_memory && !geteuid())
{
if (mlockall(MCL_CURRENT))
{
sql_print_error("Warning: Failed to lock memory. Errno: %d\n",errno);
}
else
locked_in_memory=1;
}
#else
locked_in_memory=0;
#endif
if (opt_myisam_log)
(void) mi_log( 1 );
ft_init_stopwords(ft_precompiled_stopwords);
init_max_user_conn();
init_update_queries();
if (opt_bin_log)
{
open_log(&mysql_bin_log, glob_hostname, opt_bin_logname, "-bin",
opt_binlog_index_name,LOG_BIN);
using_update_log=1;
}
return 0;
}
static void create_maintenance_thread()
{
if (
#ifdef HAVE_BERKELEY_DB
!berkeley_skip ||
#endif
(flush_time && flush_time != ~(ulong) 0L))
{
pthread_t hThread;
if (pthread_create(&hThread,&connection_attrib,handle_manager,0))
sql_print_error("Warning: Can't create thread to manage maintenance");
}
}
static void create_shutdown_thread()
{
#ifdef __WIN__
{
hEventShutdown=CreateEvent(0, FALSE, FALSE, event_name);
pthread_t hThread;
if (pthread_create(&hThread,&connection_attrib,handle_shutdown,0))
sql_print_error("Warning: Can't create thread to handle shutdown requests");
// On "Stop Service" we have to do regular shutdown
Service.SetShutdownEvent(hEventShutdown);
}
#endif
#ifdef OS2
{
pthread_cond_init( &eventShutdown, NULL);
pthread_t hThread;
if (pthread_create(&hThread,&connection_attrib,handle_shutdown,0))
sql_print_error("Warning: Can't create thread to handle shutdown requests");
}
#endif
}
#ifdef __NT__
void create_named_pipe_thread()
{
if (hPipe == INVALID_HANDLE_VALUE &&
(!have_tcpip || opt_disable_networking))
{
sql_print_error("TCP/IP or --enable-named-pipe should be configured on NT OS");
unireg_abort(1);
}
else
{
pthread_mutex_lock(&LOCK_thread_count);
(void) pthread_cond_init(&COND_handler_count,NULL);
{
pthread_t hThread;
handler_count=0;
if (hPipe != INVALID_HANDLE_VALUE && opt_enable_named_pipe)
{
handler_count++;
if (pthread_create(&hThread,&connection_attrib,
handle_connections_namedpipes, 0))
{
sql_print_error("Warning: Can't create thread to handle named pipes");
handler_count--;
}
}
if (have_tcpip && !opt_disable_networking)
{
handler_count++;
if (pthread_create(&hThread,&connection_attrib,
handle_connections_sockets, 0))
{
sql_print_error("Warning: Can't create thread to handle named pipes");
handler_count--;
}
}
while (handler_count > 0)
pthread_cond_wait(&COND_handler_count,&LOCK_thread_count);
}
pthread_mutex_unlock(&LOCK_thread_count);
}
}
#endif
#ifdef __WIN__
int win_main(int argc, char **argv)
#else
int main(int argc, char **argv)
#endif
{
int init_error;
DEBUGGER_OFF;
#ifdef _CUSTOMSTARTUPCONFIG_
if (_cust_check_startup())
{
/ * _cust_check_startup will report startup failure error * /
exit( 1 );
}
#endif
MY_INIT(argv[0]); // init my_sys library & pthreads
if ((init_error=init_common_variables(MYSQL_CONFIG_NAME,
argc, argv, load_default_groups)))
if (init_error == 2)
unireg_abort(1);
else
exit(1);
strmake(pidfile_name, glob_hostname, sizeof(pidfile_name)-5);
strmov(fn_ext(pidfile_name),".pid"); // Add proper extension
init_signals();
if (init_thread_environement())
exit(1);
select_thread=pthread_self();
select_thread_in_use=1;
if (!(opt_specialflag & SPECIAL_NO_PRIOR))
my_pthread_setprio(pthread_self(),CONNECT_PRIOR);
if (!(opt_specialflag & SPECIAL_NO_PRIOR))
my_pthread_attr_setprio(&connection_attrib,WAIT_PRIOR);
init_ssl();
#ifdef HAVE_LIBWRAP
libwrapName= my_progname+dirname_length(my_progname);
openlog(libwrapName, LOG_PID, LOG_AUTH);
#endif
/*
We have enough space for fiddling with the argv, continue
*/
if (my_setwd(mysql_real_data_home,MYF(MY_WME)))
{
unireg_abort(1); /* purecov: inspected */
}
mysql_data_home= mysql_data_home_buff;
mysql_data_home[0]=FN_CURLIB; // all paths are relative from here
mysql_data_home[1]=0;
server_init();
if (opt_bin_log && !server_id)
{
server_id= !master_host ? 1 : 2;
switch (server_id) {
#ifdef EXTRA_DEBUG
case 1:
sql_print_error("\
Warning: You have enabled the binary log, but you haven't set server-id:\n\
Updates will be logged to the binary log, but connections to slaves will\n\
not be accepted.");
break;
#endif
case 2:
sql_print_error("\
Warning: You should set server-id to a non-0 value if master_host is set.\n\
The server will not act as a slave.");
break;
}
}
if (init_server_components())
exit(1);
#ifdef __WIN__
#define MYSQL_ERR_FILE "mysql.err"
if (!opt_console)
{
freopen(MYSQL_ERR_FILE,"a+",stdout);
freopen(MYSQL_ERR_FILE,"a+",stderr);
}
#endif
#ifdef __WIN__
if (!opt_console)
FreeConsole(); // Remove window
#endif
/*
init signals & alarm
After this we can't quit by a simple unireg_abort
*/
error_handler_hook = my_message_sql;
start_signal_handler(); // Creates pidfile
if (acl_init(opt_noacl))
{
abort_loop=1;
select_thread_in_use=0;
(void) pthread_kill(signal_thread,MYSQL_KILL_SIGNAL);
#ifndef __WIN__
if (!opt_bootstrap)
(void) my_delete(pidfile_name,MYF(MY_WME)); // Not needed anymore
#endif
exit(1);
}
if (!opt_noacl)
(void) grant_init();
#ifdef HAVE_DLOPEN
if (!opt_noacl)
udf_init();
#endif
/* init_slave() must be called after the thread keys are created */
init_slave();
if (opt_bootstrap)
{
int error=bootstrap(stdin);
end_thr_alarm(); // Don't allow alarms
unireg_abort(error ? 1 : 0);
}
if (opt_init_file)
{
if (read_init_file(opt_init_file))
{
end_thr_alarm(); // Don't allow alarms
unireg_abort(1);
}
}
create_shutdown_thread();
create_maintenance_thread();
printf(ER(ER_READY),my_progname,server_version,"");
fflush(stdout);
#ifdef __NT__
create_named_pipe_thread();
#else
handle_connections_sockets(0);
#ifdef EXTRA_DEBUG2
sql_print_error("Exiting main thread");
#endif
#endif /* __NT__ */
/* (void) pthread_attr_destroy(&connection_attrib); */
DBUG_PRINT("quit",("Exiting main thread"));
#ifndef __WIN__
#ifdef EXTRA_DEBUG2
sql_print_error("Before Lock_thread_count");
#endif
(void) pthread_mutex_lock(&LOCK_thread_count);
DBUG_PRINT("quit", ("Got thread_count mutex"));
select_thread_in_use=0; // For close_connections
(void) pthread_mutex_unlock(&LOCK_thread_count);
(void) pthread_cond_broadcast(&COND_thread_count);
#ifdef EXTRA_DEBUG2
sql_print_error("After lock_thread_count");
#endif
#endif /* __WIN__ */
/* Wait until cleanup is done */
(void) pthread_mutex_lock(&LOCK_thread_count);
while (!ready_to_exit)
pthread_cond_wait(&COND_thread_count,&LOCK_thread_count);
(void) pthread_mutex_unlock(&LOCK_thread_count);
#if defined(__WIN__) && !defined(EMBEDDED_LIBRARY)
if (Service.IsNT() && start_mode)
Service.Stop();
else
{
Service.SetShutdownEvent(0);
if (hEventShutdown)
CloseHandle(hEventShutdown);
}
#endif
my_end(opt_endinfo ? MY_CHECK_ERROR | MY_GIVE_INFO : 0);
exit(0);
return(0); /* purecov: deadcode */
}
#ifdef _DUMMY
#ifdef __WIN__ #ifdef __WIN__
int win_main(int argc, char **argv) int win_main(int argc, char **argv)
@ -1944,7 +2433,6 @@ int main(int argc, char **argv)
/* /*
We have enough space for fiddling with the argv, continue We have enough space for fiddling with the argv, continue
*/ */
umask(((~my_umask) & 0666));
if (my_setwd(mysql_real_data_home,MYF(MY_WME))) if (my_setwd(mysql_real_data_home,MYF(MY_WME)))
{ {
unireg_abort(1); /* purecov: inspected */ unireg_abort(1); /* purecov: inspected */
@ -2208,7 +2696,7 @@ The server will not act as a slave.");
exit(0); exit(0);
return(0); /* purecov: deadcode */ return(0); /* purecov: deadcode */
} }
#endif
/**************************************************************************** /****************************************************************************
Main and thread entry function for Win32 Main and thread entry function for Win32

View File

@ -47,6 +47,12 @@ void send_error(THD *thd, uint sql_errno, const char *err)
} }
} }
} }
#ifdef EMBEDDED_LIBRARY
net->last_errno= sql_errno;
strmake(net->last_error, err, sizeof(net->last_error)-1);
#else
if (net->vio == 0) if (net->vio == 0)
{ {
if (thd->bootstrap) if (thd->bootstrap)
@ -69,6 +75,7 @@ void send_error(THD *thd, uint sql_errno, const char *err)
set_if_smaller(length,MYSQL_ERRMSG_SIZE-1); set_if_smaller(length,MYSQL_ERRMSG_SIZE-1);
} }
VOID(net_write_command(net,(uchar) 255, "", 0, (char*) err,length)); VOID(net_write_command(net,(uchar) 255, "", 0, (char*) err,length));
#endif /* EMBEDDED_LIBRARY*/
thd->fatal_error=0; // Error message is given thd->fatal_error=0; // Error message is given
thd->net.report_error= 0; thd->net.report_error= 0;
DBUG_VOID_RETURN; DBUG_VOID_RETURN;
@ -158,6 +165,7 @@ net_printf(THD *thd, uint errcode, ...)
length=sizeof(net->last_error)-1; /* purecov: inspected */ length=sizeof(net->last_error)-1; /* purecov: inspected */
va_end(args); va_end(args);
#ifndef EMBEDDED_LIBRARY
if (net->vio == 0) if (net->vio == 0)
{ {
if (thd->bootstrap) if (thd->bootstrap)
@ -175,6 +183,10 @@ net_printf(THD *thd, uint errcode, ...)
if (offset) if (offset)
int2store(text_pos-2, errcode); int2store(text_pos-2, errcode);
VOID(net_real_write(net,(char*) net->buff,length+head_length+1+offset)); VOID(net_real_write(net,(char*) net->buff,length+head_length+1+offset));
#else
net->last_errno= errcode;
strmake(net->last_error, text_pos, length);
#endif
thd->fatal_error=0; // Error message is given thd->fatal_error=0; // Error message is given
DBUG_VOID_RETURN; DBUG_VOID_RETURN;
} }
@ -205,6 +217,7 @@ net_printf(THD *thd, uint errcode, ...)
If net->no_send_ok return without sending packet If net->no_send_ok return without sending packet
*/ */
#ifndef EMBEDDED_LIBRARY
void void
send_ok(THD *thd, ha_rows affected_rows, ulonglong id, const char *message) send_ok(THD *thd, ha_rows affected_rows, ulonglong id, const char *message)
@ -290,6 +303,7 @@ send_eof(THD *thd, bool no_flush)
} }
DBUG_VOID_RETURN; DBUG_VOID_RETURN;
} }
#endif /* EMBEDDED_LIBRARY */
/**************************************************************************** /****************************************************************************

View File

@ -2635,8 +2635,12 @@ ulong get_table_grant(THD *thd, TABLE_LIST *table)
GRANT_TABLE *grant_table; GRANT_TABLE *grant_table;
rw_rdlock(&LOCK_grant); rw_rdlock(&LOCK_grant);
#ifdef EMBEDDED_LIBRARY
grant_table= NULL;
#else
grant_table = table_hash_search(thd->host,thd->ip,db,user, grant_table = table_hash_search(thd->host,thd->ip,db,user,
table->real_name,0); table->real_name,0);
#endif
table->grant.grant_table=grant_table; // Remember for column test table->grant.grant_table=grant_table; // Remember for column test
table->grant.version=grant_version; table->grant.version=grant_version;
if (grant_table) if (grant_table)

View File

@ -195,7 +195,6 @@ OPEN_TABLE_LIST *list_open_tables(THD *thd, const char *wild)
DBUG_RETURN(open_list); DBUG_RETURN(open_list);
} }
/* /*
Send name and type of result to client converted to a given char set Send name and type of result to client converted to a given char set
@ -216,6 +215,8 @@ OPEN_TABLE_LIST *list_open_tables(THD *thd, const char *wild)
1 Error (Note that in this case the error is not sent to the client) 1 Error (Note that in this case the error is not sent to the client)
*/ */
#ifndef EMBEDDED_LIBRARY
bool bool
send_convert_fields(THD *thd,List<Item> &list,CONVERT *convert,uint flag) send_convert_fields(THD *thd,List<Item> &list,CONVERT *convert,uint flag)
{ {
@ -439,6 +440,7 @@ err:
DBUG_RETURN(1); /* purecov: inspected */ DBUG_RETURN(1); /* purecov: inspected */
} }
#endif /* EMBEDDED_LIBRARY */
/***************************************************************************** /*****************************************************************************
* Functions to free open table cache * Functions to free open table cache

View File

@ -463,6 +463,8 @@ bool select_send::send_fields(List<Item> &list,uint flag)
} }
#ifndef EMBEDDED_LIBRARY
/* Send data to client. Returns 0 if ok */ /* Send data to client. Returns 0 if ok */
bool select_send::send_data(List<Item> &items) bool select_send::send_data(List<Item> &items)
@ -497,6 +499,7 @@ bool select_send::send_data(List<Item> &items)
else else
DBUG_RETURN(1); DBUG_RETURN(1);
} }
#endif /* EMBEDDED_LIBRARY */
bool select_send::send_eof() bool select_send::send_eof()
{ {

View File

@ -178,6 +178,9 @@ public:
convert_array(from_map, (uchar*) a,length); convert_array(from_map, (uchar*) a,length);
} }
bool store(String *, const char *,uint); bool store(String *, const char *,uint);
#ifdef EMBEDDED_LIBRARY
void convert_back(char *dest, const char *source, uint length) const;
#endif
inline uint number() { return numb; } inline uint number() { return numb; }
}; };
@ -335,6 +338,10 @@ class select_result;
#define THD_SENTRY_MAGIC 0xfeedd1ff #define THD_SENTRY_MAGIC 0xfeedd1ff
#define THD_SENTRY_GONE 0xdeadbeef #define THD_SENTRY_GONE 0xdeadbeef
#ifdef EMBEDDED_LIBRARY
typedef struct st_mysql;
#endif
#define THD_CHECK_SENTRY(thd) DBUG_ASSERT(thd->dbug_sentry == THD_SENTRY_MAGIC) #define THD_CHECK_SENTRY(thd) DBUG_ASSERT(thd->dbug_sentry == THD_SENTRY_MAGIC)
struct system_variables struct system_variables
@ -393,6 +400,9 @@ public:
struct rand_struct rand; // used for authentication struct rand_struct rand; // used for authentication
struct system_variables variables; // Changeable local variables struct system_variables variables; // Changeable local variables
pthread_mutex_t LOCK_delete; // Locked before thd is deleted pthread_mutex_t LOCK_delete; // Locked before thd is deleted
#ifdef EMBEDDED_LIBRARY
struct st_mysql *mysql;
#endif
char *query; // Points to the current query, char *query; // Points to the current query,
/* /*

View File

@ -233,7 +233,7 @@ int mysql_ha_read(THD *thd, TABLE_LIST *tables,
goto err; goto err;
} }
} }
my_net_write(&thd->net, (char*)packet->ptr(), packet->length()); SEND_ROW(thd, list.elements, (char*)packet->ptr(), packet->length());
} }
} }
num_rows++; num_rows++;

View File

@ -839,8 +839,9 @@ err:
} }
/* Execute one command from socket (query or simple command) */ #ifndef EMBEDDED_LIBRARY
/* Execute one command from socket (query or simple command) */
bool do_command(THD *thd) bool do_command(THD *thd)
{ {
char *packet; char *packet;
@ -878,6 +879,7 @@ bool do_command(THD *thd)
DBUG_RETURN(dispatch_command(command,thd, packet+1, (uint) packet_length)); DBUG_RETURN(dispatch_command(command,thd, packet+1, (uint) packet_length));
} }
#endif /* EMBEDDED_LIBRARY */
bool dispatch_command(enum enum_server_command command, THD *thd, bool dispatch_command(enum enum_server_command command, THD *thd,
char* packet, uint packet_length) char* packet, uint packet_length)
@ -3166,7 +3168,6 @@ bool add_field_to_list(char *field_name, enum_field_types type,
case FIELD_TYPE_STRING: case FIELD_TYPE_STRING:
case FIELD_TYPE_VAR_STRING: case FIELD_TYPE_VAR_STRING:
case FIELD_TYPE_NULL: case FIELD_TYPE_NULL:
case FIELD_TYPE_GEOMETRY:
break; break;
case FIELD_TYPE_DECIMAL: case FIELD_TYPE_DECIMAL:
if (!length) if (!length)
@ -3179,6 +3180,7 @@ bool add_field_to_list(char *field_name, enum_field_types type,
case FIELD_TYPE_TINY_BLOB: case FIELD_TYPE_TINY_BLOB:
case FIELD_TYPE_LONG_BLOB: case FIELD_TYPE_LONG_BLOB:
case FIELD_TYPE_MEDIUM_BLOB: case FIELD_TYPE_MEDIUM_BLOB:
case FIELD_TYPE_GEOMETRY:
if (default_value) // Allow empty as default value if (default_value) // Allow empty as default value
{ {
String str,*res; String str,*res;
@ -3314,7 +3316,7 @@ bool add_field_to_list(char *field_name, enum_field_types type,
if (new_field->length >= MAX_FIELD_WIDTH || if (new_field->length >= MAX_FIELD_WIDTH ||
(!new_field->length && !(new_field->flags & BLOB_FLAG) && (!new_field->length && !(new_field->flags & BLOB_FLAG) &&
type != FIELD_TYPE_STRING && type != FIELD_TYPE_VAR_STRING)) type != FIELD_TYPE_STRING && type != FIELD_TYPE_VAR_STRING && type != FIELD_TYPE_GEOMETRY))
{ {
net_printf(thd,ER_TOO_BIG_FIELDLENGTH,field_name, net_printf(thd,ER_TOO_BIG_FIELDLENGTH,field_name,
MAX_FIELD_WIDTH-1); /* purecov: inspected */ MAX_FIELD_WIDTH-1); /* purecov: inspected */

View File

@ -5354,6 +5354,9 @@ end_update(JOIN *join, JOIN_TAB *join_tab __attribute__((unused)),
{ {
Item *item= *group->item; Item *item= *group->item;
item->save_org_in_field(group->field); item->save_org_in_field(group->field);
#ifdef EMBEDDED_LIBRARY
join->thd->net.last_errno= 0;
#endif
/* Store in the used key if the field was 0 */ /* Store in the used key if the field was 0 */
if (item->maybe_null) if (item->maybe_null)
group->buff[-1]=item->null_value ? 1 : 0; group->buff[-1]=item->null_value ? 1 : 0;

View File

@ -52,8 +52,6 @@ extern struct st_VioSSLAcceptorFd * ssl_acceptor_fd;
** Send list of databases ** Send list of databases
** A database is a directory in the mysql_data_home directory ** A database is a directory in the mysql_data_home directory
****************************************************************************/ ****************************************************************************/
int int
mysqld_show_dbs(THD *thd,const char *wild) mysqld_show_dbs(THD *thd,const char *wild)
{ {
@ -87,8 +85,8 @@ mysqld_show_dbs(THD *thd,const char *wild)
{ {
packet->length(0); packet->length(0);
net_store_data(packet, thd->variables.convert_set, file_name); net_store_data(packet, thd->variables.convert_set, file_name);
if (my_net_write(&thd->net, (char*) packet->ptr(), if (SEND_ROW(thd, field_list.elements,
packet->length())) (char *)packet->ptr(), packet->length()))
DBUG_RETURN(-1); DBUG_RETURN(-1);
} }
} }
@ -127,7 +125,8 @@ int mysqld_show_open_tables(THD *thd,const char *wild)
net_store_data(packet,convert, open_list->table); net_store_data(packet,convert, open_list->table);
net_store_data(packet,open_list->in_use); net_store_data(packet,open_list->in_use);
net_store_data(packet,open_list->locked); net_store_data(packet,open_list->locked);
if (my_net_write(&thd->net,(char*) packet->ptr(),packet->length())) if (SEND_ROW(thd, field_list.elements,
(char *)packet->ptr(), packet->length()))
{ {
DBUG_RETURN(-1); DBUG_RETURN(-1);
} }
@ -169,7 +168,8 @@ int mysqld_show_tables(THD *thd,const char *db,const char *wild)
{ {
packet->length(0); packet->length(0);
net_store_data(packet, thd->variables.convert_set, file_name); net_store_data(packet, thd->variables.convert_set, file_name);
if (my_net_write(&thd->net,(char*) packet->ptr(),packet->length())) if (SEND_ROW(thd, field_list.elements,
(char *)packet->ptr(), packet->length()))
DBUG_RETURN(-1); DBUG_RETURN(-1);
} }
send_eof(thd); send_eof(thd);
@ -635,9 +635,9 @@ int mysqld_extend_show_tables(THD *thd,const char *db,const char *wild)
} }
close_thread_tables(thd,0); close_thread_tables(thd,0);
} }
if (my_net_write(&thd->net,(char*) packet->ptr(), if (SEND_ROW(thd, field_list.elements,
packet->length())) (char *)packet->ptr(), packet->length()))
DBUG_RETURN(-1); DBUG_RETURN(-1);
} }
send_eof(thd); send_eof(thd);
DBUG_RETURN(0); DBUG_RETURN(0);
@ -647,7 +647,6 @@ int mysqld_extend_show_tables(THD *thd,const char *db,const char *wild)
/*************************************************************************** /***************************************************************************
** List all columns in a table_list->real_name ** List all columns in a table_list->real_name
***************************************************************************/ ***************************************************************************/
int int
mysqld_show_fields(THD *thd, TABLE_LIST *table_list,const char *wild, mysqld_show_fields(THD *thd, TABLE_LIST *table_list,const char *wild,
bool verbose) bool verbose)
@ -750,8 +749,8 @@ mysqld_show_fields(THD *thd, TABLE_LIST *table_list,const char *wild,
if (verbose) if (verbose)
{ {
/* Add grant options & comments */ /* Add grant options & comments */
col_access= get_column_grant(thd,table_list,field) & COL_ACLS;
end=tmp; end=tmp;
col_access= get_column_grant(thd,table_list,field) & COL_ACLS;
for (uint bitnr=0; col_access ; col_access>>=1,bitnr++) for (uint bitnr=0; col_access ; col_access>>=1,bitnr++)
{ {
if (col_access & 1) if (col_access & 1)
@ -763,8 +762,9 @@ mysqld_show_fields(THD *thd, TABLE_LIST *table_list,const char *wild,
net_store_data(packet,convert, tmp+1,end == tmp ? 0 : (uint) (end-tmp-1)); net_store_data(packet,convert, tmp+1,end == tmp ? 0 : (uint) (end-tmp-1));
net_store_data(packet, field->comment.str,field->comment.length); net_store_data(packet, field->comment.str,field->comment.length);
} }
if (my_net_write(&thd->net,(char*) packet->ptr(),packet->length())) if (SEND_ROW(thd, field_list.elements,
DBUG_RETURN(1); (char *)packet->ptr(), packet->length()))
DBUG_RETURN(-1);
} }
} }
} }
@ -833,8 +833,9 @@ mysqld_show_create(THD *thd, TABLE_LIST *table_list)
int3store(p, create_len); int3store(p, create_len);
// now we are in business :-) // now we are in business :-)
if (my_net_write(&thd->net, (char*)packet->ptr(), packet->length())) if (SEND_ROW(thd, field_list.elements,
DBUG_RETURN(1); (char *)packet->ptr(), packet->length()))
DBUG_RETURN(-1);
} }
send_eof(thd); send_eof(thd);
DBUG_RETURN(0); DBUG_RETURN(0);
@ -956,8 +957,9 @@ mysqld_show_keys(THD *thd, TABLE_LIST *table_list)
net_store_data(packet,convert,table->file->index_type(i)); net_store_data(packet,convert,table->file->index_type(i));
/* Comment */ /* Comment */
net_store_data(packet,convert,""); net_store_data(packet,convert,"");
if (my_net_write(&thd->net,(char*) packet->ptr(),packet->length())) if (SEND_ROW(thd, field_list.elements,
DBUG_RETURN(1); /* purecov: inspected */ (char *)packet->ptr(), packet->length()))
DBUG_RETURN(-1);
} }
} }
send_eof(thd); send_eof(thd);
@ -1384,8 +1386,9 @@ void mysqld_list_processes(THD *thd,const char *user, bool verbose)
net_store_data(packet,convert,thd_info->query); net_store_data(packet,convert,thd_info->query);
else else
net_store_null(packet); net_store_null(packet);
if (my_net_write(&thd->net,(char*) packet->ptr(),packet->length())) if (SEND_ROW(thd, field_list.elements,
break; /* purecov: inspected */ (char *)packet->ptr(), packet->length()))
break;
} }
send_eof(thd); send_eof(thd);
DBUG_VOID_RETURN; DBUG_VOID_RETURN;
@ -1684,8 +1687,9 @@ int mysqld_show(THD *thd, const char *wild, show_var_st *variables,
net_store_data(&packet2, ""); // Safety net_store_data(&packet2, ""); // Safety
break; break;
} }
if (my_net_write(&thd->net, (char*) packet2.ptr(),packet2.length())) if (SEND_ROW(thd, field_list.elements,
goto err; /* purecov: inspected */ (char *)packet2.ptr(), packet2.length()))
goto err;
} }
} }
pthread_mutex_unlock(&LOCK_status); pthread_mutex_unlock(&LOCK_status);

View File

@ -403,6 +403,16 @@ int mysql_create_table(THD *thd,const char *db, const char *table_name,
sql_field->unireg_check=Field::BLOB_FIELD; sql_field->unireg_check=Field::BLOB_FIELD;
blob_columns++; blob_columns++;
break; break;
case FIELD_TYPE_GEOMETRY:
sql_field->pack_flag=FIELDFLAG_GEOM |
pack_length_to_packflag(sql_field->pack_length -
portable_sizeof_char_ptr);
if (sql_field->flags & BINARY_FLAG)
sql_field->pack_flag|=FIELDFLAG_BINARY;
sql_field->length=8; // Unireg field length
sql_field->unireg_check=Field::BLOB_FIELD;
blob_columns++;
break;
case FIELD_TYPE_VAR_STRING: case FIELD_TYPE_VAR_STRING:
case FIELD_TYPE_STRING: case FIELD_TYPE_STRING:
sql_field->pack_flag=0; sql_field->pack_flag=0;
@ -1012,8 +1022,7 @@ static int send_check_errmsg(THD* thd, TABLE_LIST* table,
net_store_data(packet, "error"); net_store_data(packet, "error");
net_store_data(packet, errmsg); net_store_data(packet, errmsg);
thd->net.last_error[0]=0; thd->net.last_error[0]=0;
if (my_net_write(&thd->net, (char*) thd->packet.ptr(), if (SEND_ROW(thd, 4, (char*) thd->packet.ptr(), packet->length()))
packet->length()))
return -1; return -1;
return 1; return 1;
} }
@ -1183,6 +1192,9 @@ static int mysql_admin_table(THD* thd, TABLE_LIST* tables,
thd->open_options|= extra_open_options; thd->open_options|= extra_open_options;
table->table = open_ltable(thd, table, lock_type); table->table = open_ltable(thd, table, lock_type);
#ifdef EMBEDDED_LIBRARY
thd->net.last_errno= 0; // these errors shouldn't get client
#endif
thd->open_options&= ~extra_open_options; thd->open_options&= ~extra_open_options;
packet->length(0); packet->length(0);
if (prepare_func) if (prepare_func)
@ -1204,7 +1216,7 @@ static int mysql_admin_table(THD* thd, TABLE_LIST* tables,
err_msg=ER(ER_CHECK_NO_SUCH_TABLE); err_msg=ER(ER_CHECK_NO_SUCH_TABLE);
net_store_data(packet, err_msg); net_store_data(packet, err_msg);
thd->net.last_error[0]=0; thd->net.last_error[0]=0;
if (my_net_write(&thd->net, (char*) thd->packet.ptr(), if (SEND_ROW(thd, field_list.elements, (char*) thd->packet.ptr(),
packet->length())) packet->length()))
goto err; goto err;
continue; continue;
@ -1219,7 +1231,7 @@ static int mysql_admin_table(THD* thd, TABLE_LIST* tables,
net_store_data(packet, buff); net_store_data(packet, buff);
close_thread_tables(thd); close_thread_tables(thd);
table->table=0; // For query cache table->table=0; // For query cache
if (my_net_write(&thd->net, (char*) thd->packet.ptr(), if (SEND_ROW(thd, field_list.elements, (char*) thd->packet.ptr(),
packet->length())) packet->length()))
goto err; goto err;
continue; continue;
@ -1248,6 +1260,9 @@ static int mysql_admin_table(THD* thd, TABLE_LIST* tables,
} }
int result_code = (table->table->file->*operator_func)(thd, check_opt); int result_code = (table->table->file->*operator_func)(thd, check_opt);
#ifdef EMBEDDED_LIBRARY
thd->net.last_errno= 0; // these errors shouldn't get client
#endif
packet->length(0); packet->length(0);
net_store_data(packet, table_name); net_store_data(packet, table_name);
net_store_data(packet, operator_name); net_store_data(packet, operator_name);
@ -1303,8 +1318,8 @@ static int mysql_admin_table(THD* thd, TABLE_LIST* tables,
} }
close_thread_tables(thd); close_thread_tables(thd);
table->table=0; // For query cache table->table=0; // For query cache
if (my_net_write(&thd->net, (char*) packet->ptr(), if (SEND_ROW(thd, field_list.elements,
packet->length())) (char *)thd->packet.ptr(), thd->packet.length()))
goto err; goto err;
} }