Fixes and code cleanups after merge with 4.0.3

Warning handling and initial prepared statement handling (last not complete yet)
Changed a lot of functions that returned 0/1 to my_bool type.
GRANT handling now uses read/write locks instead of mutex
Change basic net functions to use THD instead of NET
(needed for 4.1 protocol)
Use my_sprintf instead of sprintf() + strlen()
Added alloc_query() to be able to chare query initialization code with
prepared statements.
Cleanup handling of SHOW COUNT(*) WARNINGS and SELECT LAST_INSERT_ID()

Note that the following test fails (will be fixed ASAP):
sub_select, union, rpl_rotate_logs and rpl_mystery22
This commit is contained in:
monty@mashka.mysql.fi 2002-10-02 13:33:08 +03:00
commit d69250a969
108 changed files with 3026 additions and 2916 deletions

View file

@ -28684,6 +28684,7 @@ and if you can use @code{GLOBAL} or @code{SESSION} with them.
@item delayed_insert_limit @tab num @tab GLOBAL
@item delayed_insert_timeout @tab num @tab GLOBAL
@item delayed_queue_size @tab num @tab GLOBAL
@item error_count @tab num @tab LOCAL
@item flush @tab bool @tab GLOBAL
@item flush_time @tab num @tab GLOBAL
@item foreign_key_checks @tab bool @tab SESSION
@ -28702,6 +28703,7 @@ and if you can use @code{GLOBAL} or @code{SESSION} with them.
@item max_binlog_size @tab num @tab GLOBAL
@item max_connect_errors @tab num @tab GLOBAL
@item max_connections @tab num @tab GLOBAL
@item max_error_count @tab num @tab GLOBAL | SESSION
@item max_delayed_threads @tab num @tab GLOBAL
@item max_heap_table_size @tab num @tab GLOBAL | SESSION
@item max_join_size @tab num @tab GLOBAL | SESSION
@ -28750,6 +28752,7 @@ and if you can use @code{GLOBAL} or @code{SESSION} with them.
@item tx_isolation @tab enum @tab GLOBAL | SESSION
@item version @tab string @tab GLOBAL
@item wait_timeout @tab num @tab GLOBAL | SESSION
@item warning_count @tab num @tab LOCAL
@item unique_checks @tab bool @tab SESSION
@end multitable

View file

@ -40,7 +40,7 @@
#include <signal.h>
#include <violite.h>
const char *VER= "12.12";
const char *VER= "12.13";
/* Don't try to make a nice table if the data is too big */
#define MAX_COLUMN_LENGTH 1024
@ -1362,9 +1362,9 @@ com_clear(String *buffer,char *line __attribute__((unused)))
static int
com_go(String *buffer,char *line __attribute__((unused)))
{
char buff[160],time_buff[32];
char buff[200], time_buff[32], *pos;
MYSQL_RES *result;
ulong timer;
ulong timer, warnings;
uint error=0;
if (!status.batch)
@ -1447,7 +1447,7 @@ com_go(String *buffer,char *line __attribute__((unused)))
{
if (!mysql_num_rows(result) && ! quick)
{
sprintf(buff,"Empty set%s",time_buff);
strmov(buff, "Empty set");
}
else
{
@ -1462,20 +1462,30 @@ com_go(String *buffer,char *line __attribute__((unused)))
print_tab_data(result);
else
print_table_data(result);
sprintf(buff,"%ld %s in set%s",
sprintf(buff,"%ld %s in set",
(long) mysql_num_rows(result),
(long) mysql_num_rows(result) == 1 ? "row" : "rows",
time_buff);
(long) mysql_num_rows(result) == 1 ? "row" : "rows");
end_pager();
}
}
else if (mysql_affected_rows(&mysql) == ~(ulonglong) 0)
sprintf(buff,"Query OK%s",time_buff);
strmov(buff,"Query OK");
else
sprintf(buff,"Query OK, %ld %s affected%s",
sprintf(buff,"Query OK, %ld %s affected",
(long) mysql_affected_rows(&mysql),
(long) mysql_affected_rows(&mysql) == 1 ? "row" : "rows",
time_buff);
(long) mysql_affected_rows(&mysql) == 1 ? "row" : "rows");
pos=strend(buff);
if ((warnings= mysql_warning_count(&mysql)))
{
*pos++= ',';
*pos++= ' ';
pos=int2str(warnings, pos, 10);
pos=strmov(pos, " warning");
if (warnings != 1)
*pos++= 's';
}
strmov(pos, time_buff);
put_info(buff,INFO_RESULT);
if (mysql_info(&mysql))
put_info(mysql_info(&mysql),INFO_RESULT);

View file

@ -311,7 +311,7 @@ static int eval_result = 0;
void mysql_enable_rpl_parse(MYSQL* mysql __attribute__((unused))) {}
void mysql_disable_rpl_parse(MYSQL* mysql __attribute__((unused))) {}
int mysql_rpl_parse_enabled(MYSQL* mysql __attribute__((unused))) { return 1; }
int mysql_rpl_probe(MYSQL *mysql __attribute__((unused))) { return 1; }
my_bool mysql_rpl_probe(MYSQL *mysql __attribute__((unused))) { return 1; }
#endif
#define MAX_SERVER_ARGS 20
@ -1073,7 +1073,7 @@ int do_disable_rpl_parse(struct st_query* q __attribute__((unused)))
}
int do_sleep(struct st_query* q)
int do_sleep(struct st_query* q, my_bool real_sleep)
{
char *p=q->first_argument;
struct timeval t;
@ -2055,6 +2055,36 @@ static void replace_dynstr_append_mem(DYNAMIC_STRING *ds, const char *val,
dynstr_append_mem(ds, val, len);
}
/*
Append all results to the dynamic string separated with '\t'
*/
static void append_result(DYNAMIC_STRING *ds, MYSQL_RES *res)
{
MYSQL_ROW row;
int num_fields= mysql_num_fields(res);
unsigned long *lengths;
while ((row = mysql_fetch_row(res)))
{
int i;
lengths = mysql_fetch_lengths(res);
for (i = 0; i < num_fields; i++)
{
const char *val= row[i];
ulonglong len= lengths[i];
if (!val)
{
val = "NULL";
len = 4;
}
if (i)
dynstr_append_mem(ds, "\t", 1);
replace_dynstr_append_mem(ds, val, len);
}
dynstr_append_mem(ds, "\n", 1);
}
}
/*
* flags control the phased/stages of query execution to be performed
@ -2065,12 +2095,7 @@ static void replace_dynstr_append_mem(DYNAMIC_STRING *ds, const char *val,
int run_query(MYSQL* mysql, struct st_query* q, int flags)
{
MYSQL_RES* res = 0;
MYSQL_FIELD* fields;
MYSQL_ROW row;
int num_fields,i, error = 0;
unsigned long* lengths;
char* val;
int len;
int i, error = 0;
DYNAMIC_STRING *ds;
DYNAMIC_STRING ds_tmp;
DYNAMIC_STRING eval_query;
@ -2178,45 +2203,37 @@ int run_query(MYSQL* mysql, struct st_query* q, int flags)
goto end;
}
if (!res)
goto end;
if (!disable_result_log)
if (!disable_result_log && res)
{
fields = mysql_fetch_fields(res);
num_fields = mysql_num_fields(res);
int num_fields= mysql_num_fields(res);
MYSQL_FIELD *fields= mysql_fetch_fields(res);
for (i = 0; i < num_fields; i++)
{
if (i)
dynstr_append_mem(ds, "\t", 1);
dynstr_append(ds, fields[i].name);
}
dynstr_append_mem(ds, "\n", 1);
while ((row = mysql_fetch_row(res)))
{
lengths = mysql_fetch_lengths(res);
for (i = 0; i < num_fields; i++)
{
val = (char*)row[i];
len = lengths[i];
if (!val)
{
val = (char*)"NULL";
len = 4;
}
if (i)
dynstr_append_mem(ds, "\t", 1);
replace_dynstr_append_mem(ds, val, len);
}
dynstr_append_mem(ds, "\n", 1);
}
if (glob_replace)
free_replace();
append_result(ds, res);
}
/* Add all warnings to the result */
if (!disable_result_log && mysql_warning_count(mysql))
{
MYSQL_RES *warn_res= mysql_warnings(mysql);
if (!warn_res)
verbose_msg("Warning count is %d but didn't get any warnings\n",
mysql_warning_count(mysql));
else
{
dynstr_append_mem(ds, "Warnings:\n", 10);
append_result(ds, warn_res);
mysql_free_result(warn_res);
}
}
if (glob_replace)
free_replace();
if (record)
{
if (!q->record_file[0] && !result_file)

View file

@ -10,7 +10,7 @@ AM_CONFIG_HEADER(config.h)
PROTOCOL_VERSION=10
DOT_FRM_VERSION=6
# See the libtool docs for information on how to do shared lib versions.
SHARED_LIB_VERSION=11:0:0
SHARED_LIB_VERSION=12:0:0
# Set all version vars based on $VERSION. How do we do this more elegant ?
# Remember that regexps needs to quote [ and ] since this is run through m4

View file

@ -63,15 +63,12 @@ extern const char *client_errors[]; /* Error messages */
#define CR_PROBE_MASTER_CONNECT 2025
/* new 4.1 error codes */
#define CR_INVALID_CONN_HANDLE 2026
#define CR_NULL_POINTER 2027
#define CR_MEMORY_ERROR 2028
#define CR_NO_PREPARE_STMT 2029
#define CR_NOT_ALL_PARAMS_BOUND 2030
#define CR_DATA_TRUNCATED 2031
#define CR_NOT_ALL_BUFFERS_BOUND 2032
#define CR_FAILED_TO_SET_PARAM_DATA 2033
#define CR_NO_PARAMETERS_EXISTS 2033
#define CR_INVALID_PARAMETER_NO 2035
#define CR_INVALID_BUFFER_USE 2036
#define CR_INVALID_CONN_HANDLE 2026
#define CR_NULL_POINTER 2027
#define CR_NO_PREPARE_STMT 2028
#define CR_NOT_ALL_PARAMS_BOUND 2029
#define CR_DATA_TRUNCATED 2030
#define CR_NO_PARAMETERS_EXISTS 2031
#define CR_INVALID_PARAMETER_NO 2032
#define CR_INVALID_BUFFER_USE 2033
#define CR_UNSUPPORTED_PARAM_TYPE 2034

View file

@ -157,7 +157,8 @@ enum mysql_rpl_type { MYSQL_RPL_MASTER, MYSQL_RPL_SLAVE,
MYSQL_RPL_ADMIN };
typedef struct st_mysql {
typedef struct st_mysql
{
NET net; /* Communication parameters */
gptr connector_fd; /* ConnectorFd for SSL */
char *host,*user,*passwd,*unix_socket,*server_version,*host_info,
@ -175,6 +176,7 @@ typedef struct st_mysql {
unsigned int field_count;
unsigned int server_status;
unsigned int server_language;
unsigned int warning_count;
struct st_mysql_options options;
enum mysql_status status;
my_bool free_me; /* If free in mysql_close */
@ -273,12 +275,13 @@ my_ulonglong STDCALL mysql_affected_rows(MYSQL *mysql);
my_ulonglong STDCALL mysql_insert_id(MYSQL *mysql);
unsigned int STDCALL mysql_errno(MYSQL *mysql);
const char * STDCALL mysql_error(MYSQL *mysql);
uint STDCALL mysql_warning_count(MYSQL *mysql);
const char * STDCALL mysql_info(MYSQL *mysql);
unsigned long STDCALL mysql_thread_id(MYSQL *mysql);
const char * STDCALL mysql_character_set_name(MYSQL *mysql);
MYSQL * STDCALL mysql_init(MYSQL *mysql);
int STDCALL mysql_ssl_set(MYSQL *mysql, const char *key,
my_bool STDCALL mysql_ssl_set(MYSQL *mysql, const char *key,
const char *cert, const char *ca,
const char *capath, const char *cipher);
my_bool STDCALL mysql_change_user(MYSQL *mysql, const char *user,
@ -295,19 +298,19 @@ int STDCALL mysql_select_db(MYSQL *mysql, const char *db);
int STDCALL mysql_query(MYSQL *mysql, const char *q);
int STDCALL mysql_send_query(MYSQL *mysql, const char *q,
unsigned long length);
int STDCALL mysql_read_query_result(MYSQL *mysql);
my_bool STDCALL mysql_read_query_result(MYSQL *mysql);
int STDCALL mysql_real_query(MYSQL *mysql, const char *q,
unsigned long length);
/* perform query on master */
int STDCALL mysql_master_query(MYSQL *mysql, const char *q,
unsigned long length);
int STDCALL mysql_master_send_query(MYSQL *mysql, const char *q,
unsigned long length);
my_bool STDCALL mysql_master_query(MYSQL *mysql, const char *q,
unsigned long length);
my_bool STDCALL mysql_master_send_query(MYSQL *mysql, const char *q,
unsigned long length);
/* perform query on slave */
int STDCALL mysql_slave_query(MYSQL *mysql, const char *q,
unsigned long length);
int STDCALL mysql_slave_send_query(MYSQL *mysql, const char *q,
unsigned long length);
my_bool STDCALL mysql_slave_query(MYSQL *mysql, const char *q,
unsigned long length);
my_bool STDCALL mysql_slave_send_query(MYSQL *mysql, const char *q,
unsigned long length);
/*
enable/disable parsing of all queries to decide if they go on master or
@ -322,12 +325,12 @@ int STDCALL mysql_rpl_parse_enabled(MYSQL* mysql);
void STDCALL mysql_enable_reads_from_master(MYSQL* mysql);
void STDCALL mysql_disable_reads_from_master(MYSQL* mysql);
/* get the value of the master read flag */
int STDCALL mysql_reads_from_master_enabled(MYSQL* mysql);
my_bool STDCALL mysql_reads_from_master_enabled(MYSQL* mysql);
enum mysql_rpl_type STDCALL mysql_rpl_query_type(const char* q, int len);
/* discover the master and its slaves */
int STDCALL mysql_rpl_probe(MYSQL* mysql);
my_bool STDCALL mysql_rpl_probe(MYSQL* mysql);
/* set the master, close/free the old one, if it is not a pivot */
int STDCALL mysql_set_master(MYSQL* mysql, const char* host,
@ -357,6 +360,7 @@ MYSQL_RES * STDCALL mysql_list_fields(MYSQL *mysql, const char *table,
MYSQL_RES * STDCALL mysql_list_processes(MYSQL *mysql);
MYSQL_RES * STDCALL mysql_store_result(MYSQL *mysql);
MYSQL_RES * STDCALL mysql_use_result(MYSQL *mysql);
MYSQL_RES * STDCALL mysql_warnings(MYSQL *mysql);
int STDCALL mysql_options(MYSQL *mysql,enum mysql_option option,
const char *arg);
void STDCALL mysql_free_result(MYSQL_RES *result);
@ -401,7 +405,6 @@ int STDCALL mysql_manager_fetch_line(MYSQL_MANAGER* con,
int res_buf_size);
/*
The following definitions are added for the enhanced
client-server protocol
@ -411,67 +414,76 @@ int STDCALL mysql_manager_fetch_line(MYSQL_MANAGER* con,
enum MY_STMT_STATE { MY_ST_UNKNOWN, MY_ST_PREPARE, MY_ST_EXECUTE };
/* bind structure */
typedef struct st_mysql_bind {
enum enum_field_types buffer_type; /* buffer type */
enum enum_field_types field_type; /* field type */
gptr buffer; /* buffer */
long *length; /* output length pointer */
unsigned long buffer_length; /* buffer length */
unsigned long bind_length; /* internal use */
my_bool is_null; /* NULL indicator */
my_bool is_long_data; /* long data indicator */
my_bool long_ended; /* internal use */
typedef struct st_mysql_bind
{
long *length; /* output length pointer */
gptr buffer; /* buffer */
unsigned long buffer_length; /* buffer length */
enum enum_field_types buffer_type; /* buffer type */
enum enum_field_types field_type; /* field type */
my_bool is_null; /* NULL indicator */
my_bool is_long_data; /* long data indicator */
/* The following are for internal use. Set by mysql_bind_param */
long bind_length; /* Default length of data */
my_bool long_ended; /* All data supplied for long */
uint param_number; /* For null count and error messages */
void (*store_param_func)(NET *net, struct st_mysql_bind *param);
char *(*fetch_result)(struct st_mysql_bind *, const char *row);
} MYSQL_BIND;
/* statement handler */
typedef struct st_mysql_stmt {
MYSQL *mysql; /* connection handle */
MYSQL_BIND *params; /* input parameters */
MYSQL_RES *result; /* resultset */
MYSQL_BIND *bind; /* row binding */
MYSQL_FIELD *fields; /* prepare meta info */
MEM_ROOT mem_root; /* root allocations */
unsigned long param_count; /* parameters count */
unsigned long field_count; /* fields count */
unsigned long long_length; /* long buffer alloced length */
uint err_no; /* error code */
char error[MYSQL_ERRMSG_SIZE]; /* error message */
char *query; /* query buffer */
char *long_data; /* long buffer */
enum MY_STMT_STATE state; /* statement state */
my_bool long_alloced; /* flag to indicate long alloced */
my_bool types_supplied; /* to indicate types supply */
typedef struct st_mysql_stmt
{
MYSQL *mysql; /* connection handle */
MYSQL_BIND *params; /* input parameters */
MYSQL_RES *result; /* resultset */
MYSQL_BIND *bind; /* row binding */
MYSQL_FIELD *fields; /* prepare meta info */
char *query; /* query buffer */
MEM_ROOT mem_root; /* root allocations */
MYSQL_RES tmp_result; /* Used by mysql_prepare_result */
unsigned long param_count; /* parameters count */
unsigned long field_count; /* fields count */
unsigned long long_length; /* long buffer alloced length */
ulong stmt_id; /* Id for prepared statement */
uint last_errno; /* error code */
enum MY_STMT_STATE state; /* statement state */
char last_error[MYSQL_ERRMSG_SIZE]; /* error message */
my_bool long_alloced; /* flag to indicate long alloced */
my_bool types_supplied; /* to indicate types supply */
} MYSQL_STMT;
MYSQL_STMT * STDCALL mysql_prepare(MYSQL * mysql, const char *query);
MYSQL_STMT * STDCALL mysql_prepare(MYSQL * mysql, const char *query,
unsigned long length);
int STDCALL mysql_execute(MYSQL_STMT * stmt);
unsigned long STDCALL mysql_param_count(MYSQL_STMT * stmt);
int STDCALL mysql_bind_param(MYSQL_STMT * stmt, MYSQL_BIND * bind);
int STDCALL mysql_bind_result(MYSQL_STMT * stmt, MYSQL_BIND * bind);
int STDCALL mysql_stmt_close(MYSQL_STMT * stmt);
my_bool STDCALL mysql_bind_param(MYSQL_STMT * stmt, MYSQL_BIND * bind);
my_bool STDCALL mysql_bind_result(MYSQL_STMT * stmt, MYSQL_BIND * bind);
my_bool STDCALL mysql_stmt_close(MYSQL_STMT * stmt);
uint STDCALL mysql_stmt_errno(MYSQL_STMT * stmt);
const char *STDCALL mysql_stmt_error(MYSQL_STMT * stmt);
int STDCALL mysql_commit(MYSQL * mysql);
int STDCALL mysql_rollback(MYSQL * mysql);
int STDCALL mysql_autocommit(MYSQL * mysql, my_bool auto_mode);
int STDCALL mysql_fetch(MYSQL_STMT *stmt);
my_bool STDCALL mysql_commit(MYSQL * mysql);
my_bool STDCALL mysql_rollback(MYSQL * mysql);
my_bool STDCALL mysql_autocommit(MYSQL * mysql, my_bool auto_mode);
int STDCALL mysql_fetch(MYSQL_STMT *stmt);
my_bool STDCALL mysql_send_long_data(MYSQL_STMT *stmt,
uint param_number,gptr data,
unsigned long length);
int STDCALL mysql_multi_query(MYSQL *mysql,const char *query,unsigned long len);
uint param_number,
const char *data,
unsigned long length,
my_bool last_data);
int STDCALL mysql_multi_query(MYSQL *mysql,const char *query,
unsigned long len);
MYSQL_RES *STDCALL mysql_next_result(MYSQL *mysql);
MYSQL_RES * STDCALL mysql_prepare_result(MYSQL_STMT *stmt);
MYSQL_RES *STDCALL mysql_prepare_result(MYSQL_STMT *stmt);
/* new status messages */
#define MYSQL_SUCCESS 0
#define MYSQL_WARNING 1
#define MYSQL_ERROR -1
#define MYSQL_STATUS_ERROR 2
#define MYSQL_NO_DATA 100
#define MYSQL_NEED_DATA 99
#define MYSQL_LONG_DATA_END 0xFF
@ -492,8 +504,9 @@ int STDCALL mysql_drop_db(MYSQL *mysql, const char *DB);
They are not for general usage
*/
int simple_command(MYSQL *mysql,enum enum_server_command command,
const char *arg, unsigned long length, my_bool skipp_check);
my_bool
simple_command(MYSQL *mysql,enum enum_server_command command, const char *arg,
ulong length, my_bool skip_check);
unsigned long net_safe_read(MYSQL* mysql);
#ifdef __cplusplus

View file

@ -34,15 +34,15 @@
#define MYSQL_SERVICENAME "MySql"
#endif /* __WIN__ */
enum enum_server_command {COM_SLEEP,COM_QUIT,COM_INIT_DB,COM_QUERY,
COM_FIELD_LIST,COM_CREATE_DB,COM_DROP_DB,COM_REFRESH,
COM_SHUTDOWN,COM_STATISTICS,
COM_PROCESS_INFO,COM_CONNECT,COM_PROCESS_KILL,
COM_DEBUG,COM_PING,COM_TIME,COM_DELAYED_INSERT,
COM_CHANGE_USER, COM_BINLOG_DUMP,
COM_TABLE_DUMP, COM_CONNECT_OUT,
COM_REGISTER_SLAVE,
COM_PREPARE,COM_EXECUTE,COM_LONG_DATA };
enum enum_server_command
{
COM_SLEEP, COM_QUIT, COM_INIT_DB, COM_QUERY, COM_FIELD_LIST,
COM_CREATE_DB, COM_DROP_DB, COM_REFRESH, COM_SHUTDOWN, COM_STATISTICS,
COM_PROCESS_INFO, COM_CONNECT, COM_PROCESS_KILL, COM_DEBUG, COM_PING,
COM_TIME, COM_DELAYED_INSERT, COM_CHANGE_USER, COM_BINLOG_DUMP,
COM_TABLE_DUMP, COM_CONNECT_OUT, COM_REGISTER_SLAVE,
COM_PREPARE, COM_EXECUTE, COM_LONG_DATA, COM_CLOSE_STMT
};
#define NOT_NULL_FLAG 1 /* Field can't be NULL */
#define PRI_KEY_FLAG 2 /* Field is part of a primary key */
@ -98,8 +98,9 @@ enum enum_server_command {COM_SLEEP,COM_QUIT,COM_INIT_DB,COM_QUERY,
#define CLIENT_TRANSACTIONS 8192 /* Client knows about transactions */
#define CLIENT_PROTOCOL_41 16384 /* New 4.1 protocol */
#define SERVER_STATUS_IN_TRANS 1 /* Transaction has started */
#define SERVER_STATUS_AUTOCOMMIT 2 /* Server in auto_commit mode */
#define SERVER_STATUS_IN_TRANS 1 /* Transaction has started */
#define SERVER_STATUS_AUTOCOMMIT 2 /* Server in auto_commit mode */
#define SERVER_STATUS_MORE_RESULTS 4 /* More results on server */
#define MYSQL_ERRMSG_SIZE 200
#define NET_READ_TIMEOUT 30 /* Timeout on read */
@ -203,21 +204,26 @@ enum enum_field_types { MYSQL_TYPE_DECIMAL, MYSQL_TYPE_TINY,
extern "C" {
#endif
int my_net_init(NET *net, Vio* vio);
my_bool my_net_init(NET *net, Vio* vio);
void my_net_local_init(NET *net);
void net_end(NET *net);
void net_clear(NET *net);
int net_flush(NET *net);
int my_net_write(NET *net,const char *packet,unsigned long len);
int net_write_command(NET *net,unsigned char command,const char *packet,
unsigned long len);
my_bool net_realloc(NET *net, unsigned long length);
my_bool net_flush(NET *net);
my_bool my_net_write(NET *net,const char *packet,unsigned long len);
my_bool net_write_command(NET *net,unsigned char command,
const char *header, unsigned long head_len,
const char *packet, unsigned long len);
int net_real_write(NET *net,const char *packet,unsigned long len);
unsigned long my_net_read(NET *net);
/* The following function is not meant for normal usage */
/*
The following function is not meant for normal usage
Currently it's used internally by manager.c
*/
struct sockaddr;
int my_connect(my_socket s, const struct sockaddr *name, unsigned int namelen,
unsigned int timeout);
my_bool my_connect(my_socket s, const struct sockaddr *name,
unsigned int namelen, unsigned int timeout);
struct rand_struct {
unsigned long seed1,seed2,max_value;
@ -291,6 +297,6 @@ void my_thread_end(void);
#endif
#define NULL_LENGTH ((unsigned long) ~0) /* For net_store_length */
#define MYSQL_LONG_DATA_END 0xFF /* For indication of long data ending */
#define MYSQL_LONG_DATA_HEADER 8
#endif

View file

@ -257,4 +257,5 @@
#define ER_KEY_REF_DO_NOT_MATCH_TABLE_REF 1238
#define ER_SUBSELECT_NO_1_COL 1239
#define ER_SUBSELECT_NO_1_ROW 1240
#define ER_ERROR_MESSAGES 241
#define ER_UNKNOWN_STMT_HANDLER 1241
#define ER_ERROR_MESSAGES 242

View file

@ -687,7 +687,8 @@ static HUFF_COUNTS *init_huff_count(N_INFO *info,my_off_t records)
(type == FIELD_NORMAL ||
type == FIELD_SKIP_ZERO))
count[i].max_zero_fill= count[i].field_length;
init_tree(&count[i].int_tree,0,0,-1,(qsort_cmp2) compare_tree,0,NULL,NULL);
init_tree(&count[i].int_tree,0,0,-1,(qsort_cmp2) compare_tree,0,
NULL, NULL);
if (records)
count[i].tree_pos=count[i].tree_buff =
my_malloc(count[i].field_length > 1 ? tree_buff_length : 2,

View file

@ -49,10 +49,6 @@ link_sources:
rm -f $(srcdir)/$$f; \
@LN_CP_F@ $(srcdir)/../strings/$$f $(srcdir)/$$f; \
done; \
for f in $(mystringsgen); do \
rm -f $(srcdir)/$$f; \
@LN_CP_F@ ../strings/$$f $(srcdir)/$$f; \
done; \
for f in $$qs; do \
rm -f $(srcdir)/$$f; \
@LN_CP_F@ $(srcdir)/../sql/$$f $(srcdir)/$$f; \

View file

@ -39,9 +39,10 @@ mystringsobjects = strmov.lo strxmov.lo strxnmov.lo strnmov.lo \
bchange.lo bmove.lo bmove_upp.lo longlong2str.lo \
strtoull.lo strtoll.lo llstr.lo \
ctype.lo ctype-simple.lo ctype-mb.lo \
ctype-big5.lo ctype-czech.lo ctype-euc_kr.lo ctype-win1250ch.lo\
ctype-big5.lo ctype-czech.lo ctype-euc_kr.lo \
ctype-win1250ch.lo ctype-utf8.lo \
ctype-gb2312.lo ctype-gbk.lo ctype-latin1_de.lo \
ctype-sjis.lo ctype-tis620.lo ctype-ujis.lo ctype-utf8.lo
ctype-sjis.lo ctype-tis620.lo ctype-ujis.lo
mystringsextra= strto.c
dbugobjects = dbug.lo # IT IS IN SAFEMALLOC.C sanity.lo

View file

@ -52,15 +52,13 @@ const char *client_errors[]=
"Error connecting to master:",
"Invalid connection handle",
"Invalid use of null pointer",
"Memory allocation error",
"Statement not prepared",
"Not all parameters data supplied",
"Data truncated",
"Not all parameters bound for the row fetch",
"Failed to send the parameter data",
"No parameters exists in the statement",
"Invalid parameter number",
"Can't send long data for non string or binary data types"
"Can't send long data for non string or binary data types (parameter: %d)",
"Using not supported parameter type: %d (parameter: %d)"
};
/* Start of code added by Roberto M. Serqueira - martinsc@uol.com.br - 05.24.2001 */
@ -96,15 +94,13 @@ const char *client_errors[]=
"Error connecting to master:",
"Invalid connection handle",
"Invalid use of null pointer",
"Memory allocation error",
"Statement not prepared",
"Not all parameters data supplied",
"Data truncated",
"Not all parameters bound for the row fetch",
"Failed to send the parameter data",
"No parameters exists in the statement",
"Invalid parameter number",
"Can't send long data for non string or binary data types"
"Can't send long data for non string or binary data types (parameter: %d)",
"Using not supported parameter type: %d (parameter: %d)"
};
#else /* ENGLISH */
@ -138,15 +134,13 @@ const char *client_errors[]=
"Error connecting to master:",
"Invalid connection handle",
"Invalid use of null pointer",
"Memory allocation error",
"Statement not prepared",
"Not all parameters data supplied",
"Data truncated",
"Not all parameters bound for the row fetch",
"Failed to send the parameter data",
"No parameters exists in the statement",
"Invalid parameter number",
"Can't send long data for non string or binary data types"
"Can't send long data for non string or binary data types (parameter: %d)",
"Using not supported parameter type: %d (parameter: %d)"
};
#endif

File diff suppressed because it is too large Load diff

View file

@ -104,8 +104,8 @@ EXPORTS
mysql_rpl_probe
mysql_set_master
mysql_add_slave
mysql_warning_count
mysql_warnings

View file

@ -138,7 +138,7 @@ MYSQL_MANAGER* STDCALL mysql_manager_connect(MYSQL_MANAGER* con,
}
sock_addr.sin_port = (ushort) htons((ushort) port);
if (my_connect(sock,(struct sockaddr *) &sock_addr, sizeof(sock_addr),
0) <0)
0))
{
con->last_errno=errno;
sprintf(con->last_error ,"Could not connect to %-.64s", host);

View file

@ -154,14 +154,12 @@ check_connections1(THD *thd)
end+=SCRAMBLE_LENGTH +1;
int2store(end,client_flags);
end[2]=MY_CHARSET_CURRENT;
#define MIN_HANDSHAKE_SIZE 6
int2store(end+3,thd->server_status);
bzero(end+5,13);
end+=18;
if (net_write_command(net,protocol_version, buff,
(uint) (end-buff)))
if (net_write_command(net,protocol_version,
NullS, 0,
buff, (uint) (end-buff)))
{
inc_host_errors(&thd->remote.sin_addr);
return(ER_HANDSHAKE_ERROR);
@ -169,6 +167,8 @@ check_connections1(THD *thd)
return 0;
}
#define MIN_HANDSHAKE_SIZE 6
static int
check_connections2(THD * thd)
{
@ -214,13 +214,12 @@ check_connections2(THD * thd)
static bool check_user(THD *thd,enum_server_command command, const char *user,
const char *passwd, const char *db, bool check_count)
{
NET *net= &thd->net;
USER_RESOURCES ur;
thd->db=0;
if (!(thd->user = my_strdup(user, MYF(0))))
{
send_error(net,ER_OUT_OF_RESOURCES);
send_error(thd,ER_OUT_OF_RESOURCES);
return 1;
}
thd->master_access=acl_getroot(thd, thd->host, thd->ip, thd->user,
@ -236,7 +235,7 @@ static bool check_user(THD *thd,enum_server_command command, const char *user,
thd->master_access, thd->db ? thd->db : "*none*"));
if (thd->master_access & NO_ACCESS)
{
net_printf(net, ER_ACCESS_DENIED_ERROR,
net_printf(thd, ER_ACCESS_DENIED_ERROR,
thd->user,
thd->host_or_ip,
passwd[0] ? ER(ER_YES) : ER(ER_NO));
@ -254,7 +253,7 @@ static bool check_user(THD *thd,enum_server_command command, const char *user,
VOID(pthread_mutex_unlock(&LOCK_thread_count));
if (tmp)
{ // Too many connections
send_error(net, ER_CON_COUNT_ERROR);
send_error(thd, ER_CON_COUNT_ERROR);
return(1);
}
}
@ -269,7 +268,7 @@ static bool check_user(THD *thd,enum_server_command command, const char *user,
if (db && db[0])
return test(mysql_change_db(thd,db));
else
send_ok(net); // Ready to handle questions
send_ok(thd); // Ready to handle questions
return 0; // ok
}
@ -370,7 +369,6 @@ int STDCALL mysql_server_init(int argc, char **argv, char **groups)
(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_grant,MY_MUTEX_INIT_FAST);
(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);
@ -388,6 +386,7 @@ int STDCALL mysql_server_init(int argc, char **argv, char **groups)
(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);
@ -499,7 +498,7 @@ int STDCALL mysql_server_init(int argc, char **argv, char **groups)
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_NET,NULL) ||
if (pthread_key_create(&THR_THD,NULL) ||
pthread_key_create(&THR_MALLOC,NULL))
{
sql_print_error("Can't create thread-keys");

View file

@ -212,12 +212,12 @@ static void free_rows(MYSQL_DATA *cur)
}
int
my_bool
simple_command(MYSQL *mysql,enum enum_server_command command, const char *arg,
ulong length, my_bool skipp_check)
{
NET *net= &mysql->net;
int result= -1;
my_bool result= 1;
/* Check that we are calling the client functions in right order */
if (mysql->status != MYSQL_STATUS_READY)
@ -239,7 +239,7 @@ simple_command(MYSQL *mysql,enum enum_server_command command, const char *arg,
result = lib_dispatch_command(command, net, arg,length);
if (!skipp_check)
result= ((mysql->packet_length=net_safe_read(mysql)) == packet_error ?
-1 : 0);
1 : 0);
end:
return result;
}
@ -1124,7 +1124,7 @@ mysql_send_query(MYSQL* mysql, const char* query, ulong length)
}
int STDCALL
my_bool STDCALL
mysql_read_query_result(MYSQL *mysql)
{
uchar *pos;
@ -1134,7 +1134,7 @@ mysql_read_query_result(MYSQL *mysql)
DBUG_ENTER("mysql_read_query_result");
if ((length=net_safe_read(mysql)) == packet_error)
DBUG_RETURN(-1);
DBUG_RETURN(1);
free_old_query(mysql); /* Free old result */
get_info:
pos=(uchar*) mysql->net.read_pos;
@ -1154,7 +1154,7 @@ get_info:
{
int error=send_file_to_server(mysql,(char*) pos);
if ((length=net_safe_read(mysql)) == packet_error || error)
DBUG_RETURN(-1);
DBUG_RETURN(1);
goto get_info; /* Get info packet */
}
if (!(mysql->server_status & SERVER_STATUS_AUTOCOMMIT))
@ -1162,19 +1162,19 @@ get_info:
mysql->extra_info= net_field_length_ll(&pos); /* Maybe number of rec */
if (!(fields=read_rows(mysql,(MYSQL_FIELD*) 0,5)))
DBUG_RETURN(-1);
DBUG_RETURN(1);
if (!(mysql->fields=unpack_fields(fields,&mysql->field_alloc,
(uint) field_count,0,
(my_bool) test(mysql->server_capabilities &
CLIENT_LONG_FLAG))))
DBUG_RETURN(-1);
DBUG_RETURN(1);
mysql->status=MYSQL_STATUS_GET_RESULT;
mysql->field_count=field_count;
DBUG_RETURN(0);
}
/****************************************************************************
* A modified version of connect(). connect2() allows you to specify
* A modified version of connect(). my_connect() allows you to specify
* a timeout value, in seconds, that we should wait until we
* derermine we can't connect to a particular host. If timeout is 0,
* my_connect() will behave exactly like connect().
@ -1182,11 +1182,11 @@ get_info:
* Base version coded by Steve Bernacki, Jr. <steve@navinet.net>
*****************************************************************************/
int my_connect(my_socket s, const struct sockaddr *name, uint namelen,
uint timeout)
my_bool my_connect(my_socket s, const struct sockaddr *name, uint namelen,
uint timeout)
{
#if defined(__WIN__) || defined(OS2)
return connect(s, (struct sockaddr*) name, namelen);
return connect(s, (struct sockaddr*) name, namelen) != 0;
#else
int flags, res, s_err;
SOCKOPT_OPTLEN_TYPE s_err_size = sizeof(uint);
@ -1199,7 +1199,7 @@ int my_connect(my_socket s, const struct sockaddr *name, uint namelen,
*/
if (timeout == 0)
return connect(s, (struct sockaddr*) name, namelen);
return connect(s, (struct sockaddr*) name, namelen) != 0;
flags = fcntl(s, F_GETFL, 0); /* Set socket to not block */
#ifdef O_NONBLOCK
@ -1212,7 +1212,7 @@ int my_connect(my_socket s, const struct sockaddr *name, uint namelen,
if ((res != 0) && (s_err != EINPROGRESS))
{
errno = s_err; /* Restore it */
return(-1);
return(1);
}
if (res == 0) /* Connected quickly! */
return(0);
@ -1252,7 +1252,7 @@ int my_connect(my_socket s, const struct sockaddr *name, uint namelen,
now_time=time(NULL);
timeout-= (uint) (now_time - start_time);
if (errno != EINTR || (int) timeout <= 0)
return -1;
return 1;
}
/* select() returned something more interesting than zero, let's
@ -1262,12 +1262,12 @@ int my_connect(my_socket s, const struct sockaddr *name, uint namelen,
s_err=0;
if (getsockopt(s, SOL_SOCKET, SO_ERROR, (char*) &s_err, &s_err_size) != 0)
return(-1);
return(1);
if (s_err)
{ /* getsockopt could succeed */
errno = s_err;
return(-1); /* but return an error... */
return(1); /* but return an error... */
}
return(0); /* It's all good! */
#endif

View file

@ -241,8 +241,8 @@ static void _ftb_init_index_search(FT_INFO *ftb)
{
if (!is_tree_inited(& ftb->no_dupes))
{
init_tree(& ftb->no_dupes,0,0,sizeof(my_off_t),
_ftb_no_dupes_cmp,0,0,0);
init_tree(&ftb->no_dupes,0,0,sizeof(my_off_t),
_ftb_no_dupes_cmp, 0, NULL, NULL);
}
}
}

View file

@ -41,8 +41,8 @@ int ft_init_stopwords(const char **sws)
if(!stopwords3)
{
if(!(stopwords3=(TREE *)my_malloc(sizeof(TREE),MYF(0)))) return -1;
init_tree(stopwords3,0,0,sizeof(FT_STOPWORD),(qsort_cmp2)&FT_STOPWORD_cmp,0,
NULL, NULL);
init_tree(stopwords3,0,0,sizeof(FT_STOPWORD),(qsort_cmp2)&FT_STOPWORD_cmp,
0, NULL, NULL);
}
if(!sws) return 0;

View file

@ -1771,7 +1771,7 @@ int mi_repair_by_sort(MI_CHECK *param, register MI_INFO *info,
File new_file;
MI_SORT_PARAM sort_param;
MYISAM_SHARE *share=info->s;
MI_KEYSEG *keyseg;
HA_KEYSEG *keyseg;
ulong *rec_per_key_part;
char llbuff[22];
SORT_INFO sort_info;
@ -2136,7 +2136,7 @@ int mi_repair_parallel(MI_CHECK *param, register MI_INFO *info,
MI_SORT_PARAM *sort_param=0;
MYISAM_SHARE *share=info->s;
ulong *rec_per_key_part;
MI_KEYSEG *keyseg;
HA_KEYSEG *keyseg;
char llbuff[22];
IO_CACHE_SHARE io_share;
SORT_INFO sort_info;
@ -3080,7 +3080,7 @@ static int sort_key_write(MI_SORT_PARAM *sort_param, const void *a)
{
sort_info->dupp++;
sort_info->info->lastpos=get_record_for_key(sort_info->info,
sort_parm->keyinfo,
sort_param->keyinfo,
(uchar*) a);
mi_check_print_warning(param,
"Duplicate key for record at %10s against record at %10s",

View file

@ -665,7 +665,8 @@ static HUFF_COUNTS *init_huff_count(MI_INFO *info,my_off_t records)
(type == FIELD_NORMAL ||
type == FIELD_SKIP_ZERO))
count[i].max_zero_fill= count[i].field_length;
init_tree(&count[i].int_tree,0,0,-1,(qsort_cmp2) compare_tree,0,NULL,NULL);
init_tree(&count[i].int_tree,0,0,-1,(qsort_cmp2) compare_tree,0, NULL,
NULL);
if (records && type != FIELD_BLOB && type != FIELD_VARCHAR)
count[i].tree_pos=count[i].tree_buff =
my_malloc(count[i].field_length > 1 ? tree_buff_length : 2,

View file

@ -1,5 +1,4 @@
/* Copyright (C) 2000 MySQL AB & Ramil Kalimullin & MySQL Finland AB
& TCX DataKonsult AB
/* Copyright (C) 2000 MySQL AB & Ramil Kalimullin
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@ -22,14 +21,16 @@
#include "rt_mbr.h"
/*
Add key to the page
Result values:
-1 - error
0 - not split
1 - split
Add key to the page
RESULT VALUES
-1 Error
0 Not split
1 Split
*/
int rtree_add_key(MI_INFO *info, MI_KEYDEF *keyinfo, uchar *key,
uint key_length, uchar *page_buf, my_off_t *new_page)
uint key_length, uchar *page_buf, my_off_t *new_page)
{
uint page_size = mi_getint(page_buf);
uint nod_flag = mi_test_if_nod(page_buf);
@ -53,47 +54,39 @@ int rtree_add_key(MI_INFO *info, MI_KEYDEF *keyinfo, uchar *key,
mi_putint(page_buf, page_size, nod_flag);
return 0;
}
else
{
if (rtree_split_page(info, keyinfo, page_buf, key, key_length, new_page))
return -1;
else
return 1;
}
return (rtree_split_page(info, keyinfo, page_buf, key, key_length,
new_page) ? -1 : 0);
}
/*
Delete key from the page
Delete key from the page
*/
int rtree_delete_key(MI_INFO *info, uchar *page_buf, uchar *key,
uint key_length, uint nod_flag)
uint key_length, uint nod_flag)
{
uint16 page_size = mi_getint(page_buf);
uchar *key_start;
key_start= key - nod_flag;
if (nod_flag)
{
key_start = key - nod_flag;
}
else
{
key_start = key;
key_length += info->s->base.rec_reflength;
}
memmove(key_start, key + key_length, page_size - key_length -
(key - page_buf));
page_size -= key_length + nod_flag;
(key - page_buf));
page_size-= key_length + nod_flag;
mi_putint(page_buf, page_size, nod_flag);
return 0;
}
/*
Calculate and store key MBR
Calculate and store key MBR
*/
int rtree_set_key_mbr(MI_INFO *info, MI_KEYDEF *keyinfo, uchar *key,
uint key_length, my_off_t child_page)
uint key_length, my_off_t child_page)
{
uchar *k;
uchar *last;
@ -114,21 +107,25 @@ err1:
return -1;
}
/*
Choose non-leaf better key for insertion
Choose non-leaf better key for insertion
*/
uchar *rtree_choose_key(MI_INFO *info, MI_KEYDEF *keyinfo, uchar *key,
uint key_length, uchar *page_buf, uint nod_flag)
uint key_length, uchar *page_buf, uint nod_flag)
{
double increase;
double best_incr = DBL_MAX;
double area;
double best_area;
uchar *best_key;
uchar *k = rt_PAGE_FIRST_KEY(page_buf, nod_flag);
uchar *last = rt_PAGE_END(page_buf);
LINT_INIT(best_area);
LINT_INIT(best_key);
for (; k < last; k = rt_PAGE_NEXT_KEY(k, key_length, nod_flag))
{
if ((increase = rtree_area_increase(keyinfo->seg, key, k, key_length,

View file

@ -32,7 +32,7 @@ static void print_record(char * record,my_off_t offs,const char * tail);
static int run_test(const char *filename);
int main(int argc,char *argv[])
int main(int argc __attribute__((unused)),char *argv[])
{
MY_INIT(argv[0]);
exit(run_test("rt_test"));
@ -63,7 +63,6 @@ int run_test(const char *filename)
int row_count=0;
char record[MAX_REC_LENGTH];
char read_record[MAX_REC_LENGTH];
int upd=10;
ha_rows hrows;
@ -343,7 +342,10 @@ static int read_with_pos (MI_INFO * file,int silent)
}
static void bprint_record(char * record, my_off_t offs,const char * tail)
#ifdef NOT_USED
static void bprint_record(char * record,
my_off_t offs __attribute__((unused)),
const char * tail)
{
int i;
char * pos;
@ -356,8 +358,12 @@ static void bprint_record(char * record, my_off_t offs,const char * tail)
}
printf("%s",tail);
}
#endif
static void print_record(char * record, my_off_t offs,const char * tail)
static void print_record(char * record,
my_off_t offs __attribute__((unused)),
const char * tail)
{
int i;
char * pos;

View file

@ -1,5 +1,4 @@
/* Copyright (C) 2000 MySQL AB & Ramil Kalimullin & MySQL Finland AB
& TCX DataKonsult AB
/* Copyright (C) 2000 MySQL AB & Ramil Kalimullin
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@ -30,8 +29,9 @@ static int sp_get_geometry_mbr(uchar *(*wkb), uchar *end, uint n_dims,
double *mbr, int top);
static int sp_mbr_from_wkb(uchar (*wkb), uint size, uint n_dims, double *mbr);
uint sp_make_key(register MI_INFO *info, uint keynr, uchar *key,
const byte *record, my_off_t filepos)
const byte *record, my_off_t filepos)
{
HA_KEYSEG *keyseg;
MI_KEYDEF *keyinfo = &info->s->keyinfo[keynr];
@ -91,10 +91,12 @@ static int sp_mbr_from_wkb(uchar *wkb, uint size, uint n_dims, double *mbr)
}
/*
Add one point stored in wkb to mbr
Add one point stored in wkb to mbr
*/
static int sp_add_point_to_mbr(uchar *(*wkb), uchar *end, uint n_dims,
uchar byte_order, double *mbr)
uchar byte_order __attribute__((unused)),
double *mbr)
{
double ord;
double *mbr_end = mbr + n_dims * 2;
@ -115,12 +117,14 @@ static int sp_add_point_to_mbr(uchar *(*wkb), uchar *end, uint n_dims,
return 0;
}
static int sp_get_point_mbr(uchar *(*wkb), uchar *end, uint n_dims,
uchar byte_order, double *mbr)
{
return sp_add_point_to_mbr(wkb, end, n_dims, byte_order, mbr);
}
static int sp_get_linestring_mbr(uchar *(*wkb), uchar *end, uint n_dims,
uchar byte_order, double *mbr)
{
@ -137,6 +141,7 @@ static int sp_get_linestring_mbr(uchar *(*wkb), uchar *end, uint n_dims,
return 0;
}
static int sp_get_polygon_mbr(uchar *(*wkb), uchar *end, uint n_dims,
uchar byte_order, double *mbr)
{

View file

@ -41,7 +41,7 @@ static void rtree_PrintWKB(uchar *wkb, uint n_dims);
static char blob_key[MAX_REC_LENGTH];
int main(int argc,char *argv[])
int main(int argc __attribute__((unused)),char *argv[])
{
MY_INIT(argv[0]);
exit(run_test("sp_test"));
@ -320,7 +320,10 @@ static int read_with_pos (MI_INFO * file,int silent)
}
static void bprint_record(char * record, my_off_t offs,const char * tail)
#ifdef NOT_USED
static void bprint_record(char * record,
my_off_t offs __attribute__((unused)),
const char * tail)
{
int i;
char * pos;
@ -333,6 +336,8 @@ static void bprint_record(char * record, my_off_t offs,const char * tail)
}
printf("%s",tail);
}
#endif
static void print_record(char * record, my_off_t offs,const char * tail)
{
@ -356,6 +361,7 @@ static void print_record(char * record, my_off_t offs,const char * tail)
#ifndef NOT_USED
static void create_point(char *record,uint rownr)
{
uint tmp;
@ -380,6 +386,7 @@ static void create_point(char *record,uint rownr)
ptr=blob_key;
memcpy_fixed(pos,&ptr,sizeof(char*));
}
#endif
static void create_linestring(char *record,uint rownr)

View file

@ -1,6 +1,10 @@
This directory contains a test suite for mysql daemon. To run
the currently existing test cases, simply execute ./mysql-test-run in
this directory. It will fire up the newly built mysqld and test it.
If you want to run the test with a running MySQL server use the --external
option to mysql-test-run.
Note that you do not have to have to do make install, and you could
actually have a co-existing MySQL installation - the tests will not
conflict with it.
@ -13,8 +17,7 @@ http://www.mysql.com/doc/M/y/MySQL_test_suite.html
You can create your own test cases. To create a test case:
cd t
vi test_case_name.test
xeamacs t/test_case_name.test
in the file, put a set of SQL commands that will create some tables,
load test data, run some queries to manipulate it.

View file

@ -171,7 +171,7 @@ USER_TEST=
EXTRA_MASTER_OPT=""
EXTRA_MYSQL_TEST_OPT=""
USE_RUNNING_SERVER=1
USE_RUNNING_SERVER=""
DO_GCOV=""
DO_GDB=""
MANUAL_GDB=""
@ -199,6 +199,7 @@ while test $# -gt 0; do
--slave-binary=*)
SLAVE_MYSQLD=`$ECHO "$1" | $SED -e "s;--slave-binary=;;"` ;;
--local) USE_RUNNING_SERVER="" ;;
--extern) USE_RUNNING_SERVER="1" ;;
--tmpdir=*) MYSQL_TMP_DIR=`$ECHO "$1" | $SED -e "s;--tmpdir=;;"` ;;
--local-master)
MASTER_MYPORT=3306;

View file

@ -4,9 +4,26 @@ begin work;
insert into t1 values (4);
insert into t1 values (5);
rollback;
Warning: Some non-transactional changed tables couldn't be rolled back
Warnings:
Warning 1196 Some non-transactional changed tables couldn't be rolled back
select @@warning_count;
@@warning_count
1
select @@error_count;
@@error_count
0
show warnings;
Level Code Message
Warning 1196 Some non-transactional changed tables couldn't be rolled back
show errors;
Level Code Message
select * from t1;
n
4
5
select @@warning_count;
@@warning_count
0
show warnings;
Level Code Message
drop table t1;

View file

@ -18,24 +18,24 @@ drop table t1;
show binlog events;
Log_name Pos Event_type Server_id Orig_log_pos Info
master-bin.001 4 Start 1 4 Server ver: VERSION, Binlog ver: 3
master-bin.001 79 Query 1 79 use test; create table t1(n int not null auto_increment primary key)
master-bin.001 79 Query 1 79 use `test`; create table t1(n int not null auto_increment primary key)
master-bin.001 172 Intvar 1 172 INSERT_ID=1
master-bin.001 200 Query 1 200 use test; insert into t1 values (NULL)
master-bin.001 263 Query 1 263 use test; drop table t1
master-bin.001 311 Query 1 311 use test; create table t1 (word char(20) not null)
master-bin.001 200 Query 1 200 use `test`; insert into t1 values (NULL)
master-bin.001 263 Query 1 263 use `test`; drop table t1
master-bin.001 311 Query 1 311 use `test`; create table t1 (word char(20) not null)
master-bin.001 386 Create_file 1 386 db=test;table=t1;file_id=1;block_len=81
master-bin.001 556 Exec_load 1 556 ;file_id=1
master-bin.001 579 Query 1 579 use test; drop table t1
master-bin.001 579 Query 1 579 use `test`; drop table t1
show binlog events from 79 limit 1;
Log_name Pos Event_type Server_id Orig_log_pos Info
master-bin.001 79 Query 1 79 use test; create table t1(n int not null auto_increment primary key)
master-bin.001 79 Query 1 79 use `test`; create table t1(n int not null auto_increment primary key)
show binlog events from 79 limit 2;
Log_name Pos Event_type Server_id Orig_log_pos Info
master-bin.001 79 Query 1 79 use test; create table t1(n int not null auto_increment primary key)
master-bin.001 79 Query 1 79 use `test`; create table t1(n int not null auto_increment primary key)
master-bin.001 172 Intvar 1 172 INSERT_ID=1
show binlog events from 79 limit 2,1;
Log_name Pos Event_type Server_id Orig_log_pos Info
master-bin.001 200 Query 1 200 use test; insert into t1 values (NULL)
master-bin.001 200 Query 1 200 use `test`; insert into t1 values (NULL)
flush logs;
create table t1 (n int);
insert into t1 values (1);
@ -43,21 +43,21 @@ drop table t1;
show binlog events;
Log_name Pos Event_type Server_id Orig_log_pos Info
master-bin.001 4 Start 1 4 Server ver: VERSION, Binlog ver: 3
master-bin.001 79 Query 1 79 use test; create table t1(n int not null auto_increment primary key)
master-bin.001 79 Query 1 79 use `test`; create table t1(n int not null auto_increment primary key)
master-bin.001 172 Intvar 1 172 INSERT_ID=1
master-bin.001 200 Query 1 200 use test; insert into t1 values (NULL)
master-bin.001 263 Query 1 263 use test; drop table t1
master-bin.001 311 Query 1 311 use test; create table t1 (word char(20) not null)
master-bin.001 200 Query 1 200 use `test`; insert into t1 values (NULL)
master-bin.001 263 Query 1 263 use `test`; drop table t1
master-bin.001 311 Query 1 311 use `test`; create table t1 (word char(20) not null)
master-bin.001 386 Create_file 1 386 db=test;table=t1;file_id=1;block_len=81
master-bin.001 556 Exec_load 1 556 ;file_id=1
master-bin.001 579 Query 1 579 use test; drop table t1
master-bin.001 579 Query 1 579 use `test`; drop table t1
master-bin.001 627 Rotate 1 627 master-bin.002;pos=4
master-bin.001 668 Stop 1 668
show binlog events in 'master-bin.002';
Log_name Pos Event_type Server_id Orig_log_pos Info
master-bin.002 4 Query 1 4 use test; create table t1 (n int)
master-bin.002 62 Query 1 62 use test; insert into t1 values (1)
master-bin.002 122 Query 1 122 use test; drop table t1
master-bin.002 4 Query 1 4 use `test`; create table t1 (n int)
master-bin.002 62 Query 1 62 use `test`; insert into t1 values (1)
master-bin.002 122 Query 1 122 use `test`; drop table t1
show master logs;
Log_name
master-bin.001
@ -71,9 +71,9 @@ show binlog events in 'slave-bin.001' from 4;
show binlog events in 'slave-bin.002' from 4;
Log_name Pos Event_type Server_id Orig_log_pos Info
slave-bin.002 4 Slave 2 627 host=127.0.0.1,port=MASTER_PORT,log=master-bin.002,pos=4
slave-bin.002 57 Query 1 4 use test; create table t1 (n int)
slave-bin.002 115 Query 1 62 use test; insert into t1 values (1)
slave-bin.002 175 Query 1 122 use test; drop table t1
slave-bin.002 57 Query 1 4 use `test`; create table t1 (n int)
slave-bin.002 115 Query 1 62 use `test`; insert into t1 values (1)
slave-bin.002 175 Query 1 122 use `test`; drop table t1
show slave status;
Master_Host Master_User Master_Port Connect_retry Master_Log_File Read_Master_Log_Pos Relay_Log_File Relay_Log_Pos Relay_Master_Log_File Slave_IO_Running Slave_SQL_Running Replicate_do_db Replicate_ignore_db Last_errno Last_error Skip_counter Exec_master_log_pos Relay_log_space
127.0.0.1 root MASTER_PORT 1 master-bin.002 170 slave-relay-bin.002 916 master-bin.002 Yes Yes 0 0 170 920

View file

View file

@ -8,7 +8,12 @@ create table t1 (n int not null primary key) type=myisam;
begin work;
insert into t1 values (4);
insert into t1 values (5);
# Should give an error
!$1196 rollback;
rollback;
select @@warning_count;
select @@error_count;
show warnings;
show errors;
select * from t1;
select @@warning_count;
show warnings;
drop table t1;

View file

@ -23,6 +23,7 @@ change master to master_log_pos=173;
--replace_result 3306 MASTER_PORT 9306 MASTER_PORT 3334 MASTER_PORT 3336 MASTER_PORT
slave start;
sleep 2;
--replace_result 3306 MASTER_PORT 9306 MASTER_PORT 3334 MASTER_PORT 3336 MASTER_PORT
show slave status;
connection master;
show master status;

View file

@ -35,11 +35,12 @@ static uint calc_hashnr(CHARSET_INFO *cs,const byte *key,uint length);
static uint calc_hashnr_caseup(CHARSET_INFO *cs, const byte *key,uint length);
static int hashcmp(HASH *hash,HASH_LINK *pos,const byte *key,uint length);
my_bool
_hash_init(HASH *hash,CHARSET_INFO *charset,
uint size,uint key_offset,uint key_length,
hash_get_key get_key,
void (*free_element)(void*),uint flags CALLER_INFO_PROTO)
uint size,uint key_offset,uint key_length,
hash_get_key get_key,
void (*free_element)(void*),uint flags CALLER_INFO_PROTO)
{
DBUG_ENTER("hash_init");
DBUG_PRINT("enter",("hash: %lx size: %d",hash,size));

View file

@ -120,7 +120,7 @@ int my_error(int nr,myf MyFlags, ...)
... variable list
*/
int my_printf_error (uint error, const char *format, myf MyFlags, ...)
int my_printf_error(uint error, const char *format, myf MyFlags, ...)
{
va_list args;
char ebuff[ERRMSGSIZE+20];

View file

@ -17,26 +17,33 @@
/*
Code for handling red-black (balanced) binary trees.
key in tree is allocated accrding to following:
1) If free_element function is given to init_tree or size < 0 then tree
will not allocate keys and only a pointer to each key is saved in tree.
key_sizes must be 0 to init and search.
1) If size < 0 then tree will not allocate keys and only a pointer to
each key is saved in tree.
compare and search functions uses and returns key-pointer
2) If size == 0 then there are two options:
- key_size != 0 to tree_insert: The key will be stored in the tree.
- key_size == 0 to tree_insert: A pointer to the key is stored.
compare and search functions uses and returns key-pointer.
2) if key_size is given to init_tree then each node will continue the
3) if key_size is given to init_tree then each node will continue the
key and calls to insert_key may increase length of key.
if key_size > sizeof(pointer) and key_size is a multiple of 8 (double
allign) then key will be put on a 8 alligned adress. Else
the key will be on adress (element+1). This is transparent for user
compare and search functions uses a pointer to given key-argument.
3) If init_tree - keysize is 0 then key_size must be given to tree_insert
and tree_insert will alloc space for key.
compare and search functions uses a pointer to given key-argument.
- If you use a free function for tree-elements and you are freeing
the element itself, you should use key_size = 0 to init_tree and
tree_search
The actual key in TREE_ELEMENT is saved as a pointer or after the
TREE_ELEMENT struct.
If one uses only pointers in tree one can use tree_set_pointer() to
change address of data.
Copyright Monty Program KB.
By monty.
Implemented by monty.
*/
#include "mysys_priv.h"

View file

@ -314,6 +314,7 @@ void Field::store_time(TIME *ltime,timestamp_type type)
store(buff,(uint) length, default_charset_info);
break;
}
}
}
@ -476,7 +477,7 @@ int Field_decimal::store(const char *from, uint len, CHARSET_INFO *cs)
from++;
frac_digits_from= from;
/* Read digits at the right of '.' */
for (;from!=end && my_isdigit(system_charset_info, (*from); from++) ;
for (;from!=end && my_isdigit(system_charset_info, *from); from++) ;
frac_digits_end=from;
// Some exponentiation symbol ?
if (from != end && (*from == 'e' || *from == 'E'))
@ -505,7 +506,8 @@ int Field_decimal::store(const char *from, uint len, CHARSET_INFO *cs)
if (current_thd->count_cuted_fields)
{
for (;from != end && isspace(*from); from++) ; // Read end spaces
// Skip end spaces
for (;from != end && my_isspace(system_charset_info, *from); from++) ;
if (from != end) // If still something left, warn
{
current_thd->cuted_fields++;
@ -736,10 +738,10 @@ int Field_decimal::store(double nr)
#ifdef HAVE_SNPRINTF_
buff[sizeof(buff)-1]=0; // Safety
snprintf(buff,sizeof(buff)-1, "%.*f",(int) dec,nr);
#else
sprintf(buff,"%.*f",dec,nr);
#endif
length=(uint) strlen(buff);
#else
length=(uint) my_sprintf(buff,(buff,"%.*f",dec,nr));
#endif
if (length > field_length)
{
@ -2207,10 +2209,10 @@ String *Field_float::val_str(String *val_buffer,
#ifdef HAVE_SNPRINTF
to[to_length-1]=0; // Safety
snprintf(to,to_length-1,"%.*f",dec,nr);
#else
sprintf(to,"%.*f",dec,nr);
#endif
to=strend(to);
#else
to+= my_sprintf(to,(to,"%.*f",dec,nr));
#endif
#endif
}
#ifdef HAVE_FCONVERT
@ -2468,10 +2470,10 @@ String *Field_double::val_str(String *val_buffer,
#ifdef HAVE_SNPRINTF
to[to_length-1]=0; // Safety
snprintf(to,to_length-1,"%.*f",dec,nr);
#else
sprintf(to,"%.*f",dec,nr);
#endif
to=strend(to);
#else
to+= my_sprintf(to,(to,"%.*f",dec,nr));
#endif
#endif
}
#ifdef HAVE_FCONVERT
@ -2886,8 +2888,10 @@ void Field_timestamp::sort_string(char *to,uint length __attribute__((unused)))
void Field_timestamp::sql_type(String &res) const
{
sprintf((char*) res.ptr(),"timestamp(%d)",(int) field_length);
res.length((uint) strlen(res.ptr()));
ulong length= my_sprintf((char*) res.ptr(),
((char*) res.ptr(),"timestamp(%d)",
(int) field_length));
res.length(length);
}
@ -3026,10 +3030,11 @@ String *Field_time::val_str(String *val_buffer,
tmp= -tmp;
sign= "-";
}
sprintf((char*) val_buffer->ptr(),"%s%02d:%02d:%02d",
sign,(int) (tmp/10000), (int) (tmp/100 % 100),
(int) (tmp % 100));
val_buffer->length((uint) strlen(val_buffer->ptr()));
long length= my_sprintf((char*) val_buffer->ptr(),
((char*) val_buffer->ptr(),"%s%02d:%02d:%02d",
sign,(int) (tmp/10000), (int) (tmp/100 % 100),
(int) (tmp % 100)));
val_buffer->length(length);
return val_buffer;
}
@ -3158,8 +3163,9 @@ String *Field_year::val_str(String *val_buffer,
void Field_year::sql_type(String &res) const
{
sprintf((char*) res.ptr(),"year(%d)",(int) field_length);
res.length((uint) strlen(res.ptr()));
ulong length=my_sprintf((char*) res.ptr(),
((char*) res.ptr(),"year(%d)",(int) field_length));
res.length(length);
}
@ -3852,12 +3858,14 @@ void Field_string::sort_string(char *to,uint length)
void Field_string::sql_type(String &res) const
{
sprintf((char*) res.ptr(),"%s(%d)",
field_length > 3 &&
(table->db_options_in_use & HA_OPTION_PACK_RECORD) ?
"varchar" : "char",
(int) field_length);
res.length((uint) strlen(res.ptr()));
ulong length= my_sprintf((char*) res.ptr(),
((char*) res.ptr(), "%s(%d)",
(field_length > 3 &&
(table->db_options_in_use &
HA_OPTION_PACK_RECORD) ?
"varchar" : "char"),
(int) field_length));
res.length((uint) length);
if (binary_flag)
res.append(" binary");
else
@ -4060,8 +4068,10 @@ void Field_varstring::sort_string(char *to,uint length)
void Field_varstring::sql_type(String &res) const
{
sprintf((char*) res.ptr(),"varchar(%d)",(int) field_length);
res.length((uint) strlen(res.ptr()));
ulong length= my_sprintf((char*) res.ptr(),
((char*) res.ptr(),"varchar(%u)",
field_length));
res.length((uint) length);
if (binary_flag)
res.append(" binary");
else

View file

@ -1036,6 +1036,7 @@ public:
uint decimals,flags,pack_length;
Field::utype unireg_check;
TYPELIB *interval; // Which interval to use
CHARSET_INFO *charset;
Field *field; // For alter table
uint8 row,col,sc_length,interval_id; // For rea_create_table

View file

@ -1,11 +1,19 @@
#ifndef GSTREAM_H
#define GSTREAM_H
/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
#ifdef WITHOUT_MYSQL
#include ".\rtree\myisamdef.h"
#else
#include "mysql_priv.h"
#endif
class GTextReadStream
{
@ -20,9 +28,13 @@ public:
r_bra,
comma,
};
GTextReadStream(const char *buffer, int size) :
m_cur(buffer), m_limit(buffer + size), m_last_text_position(buffer), m_err_msg(NULL) {}
GTextReadStream() : m_cur(NULL), m_limit(NULL), m_err_msg(NULL) {}
GTextReadStream(const char *buffer, int size)
:m_cur(buffer), m_limit(buffer + size), m_last_text_position(buffer),
m_err_msg(NULL)
{}
GTextReadStream(): m_cur(NULL), m_limit(NULL), m_err_msg(NULL)
{}
~GTextReadStream()
{
@ -41,21 +53,17 @@ public:
void set_error_msg(const char *msg);
// caller should free this pointer
// caller should free this pointer
char *get_error_msg()
{
char *err_msg = m_err_msg;
m_err_msg = NULL;
return err_msg;
}
protected:
const char *m_cur;
const char *m_limit;
const char *m_last_text_position;
char *m_err_msg;
};
#endif

View file

@ -3557,7 +3557,7 @@ innodb_show_status(
ut_free(buf);
send_eof(&thd->net);
send_eof(thd);
DBUG_RETURN(0);
}

View file

@ -44,10 +44,10 @@ Item::Item()
current_thd->free_list=this;
}
void Item::set_name(char *str,uint length)
void Item::set_name(const char *str,uint length)
{
if (!length)
name=str; // Used by AS
name= (char*) str; // Used by AS
else
{
while (length && !my_isgraph(system_charset_info,*str))
@ -303,21 +303,13 @@ void Item_param::set_int(longlong i)
item_type = INT_ITEM;
}
void Item_param::set_double(double i)
void Item_param::set_double(double value)
{
double value = (double)i;
real_value=value;
item_result_type = REAL_RESULT;
item_type = REAL_ITEM;
}
void Item_param::set_double(float i)
{
float value = (float)i;
real_value=(double)value;
item_result_type = REAL_RESULT;
item_type = REAL_ITEM;
}
void Item_param::set_value(const char *str, uint length)
{
@ -326,6 +318,7 @@ void Item_param::set_value(const char *str, uint length)
item_type = STRING_ITEM;
}
void Item_param::set_longdata(const char *str, ulong length)
{
/* TODO: Fix this for binary handling by making use of
@ -334,16 +327,11 @@ void Item_param::set_longdata(const char *str, ulong length)
str_value.append(str,length);
}
void Item_param::set_long_end()
{
long_data_supplied = true;
item_result_type = STRING_RESULT;
};
int Item_param::save_in_field(Field *field)
int Item_param::save_in_field(Field *field)
{
if (null_value)
return set_field_to_null(field);
return (int) set_field_to_null(field);
field->set_notnull();
if (item_result_type == INT_RESULT)
@ -357,24 +345,21 @@ int Item_param::save_in_field(Field *field)
return (field->store(nr)) ? -1 : 0;
}
String *result;
CHARSET_INFO *cs=default_charset_info;//fix this
CHARSET_INFO *cs=default_charset_info; //fix this
result=val_str(&str_value);
return (field->store(result->ptr(),result->length(),cs)) ? -1 : 0;
}
void Item_param::make_field(Send_field *tmp_field)
{
init_make_field(tmp_field,FIELD_TYPE_STRING);
}
double Item_param::val()
{
/* Cross check whether we need need this conversions ? or direct
return(real_value) is enough ?
*/
switch(item_result_type) {
switch (item_result_type) {
case STRING_RESULT:
return (double)atof(str_value.ptr());
case INT_RESULT:
@ -384,16 +369,12 @@ double Item_param::val()
}
}
longlong Item_param::val_int()
{
/* Cross check whether we need need this conversions ? or direct
return(int_value) is enough ?
*/
switch(item_result_type) {
switch (item_result_type) {
case STRING_RESULT:
return (longlong)strtoll(str_value.ptr(),(char**) 0,10);
return strtoll(str_value.ptr(),(char**) 0,10);
case REAL_RESULT:
return (longlong) (real_value+(real_value > 0 ? 0.5 : -0.5));
default:
@ -401,14 +382,10 @@ longlong Item_param::val_int()
}
}
String *Item_param::val_str(String* str)
{
/* Cross check whether we need need this conversions ? or direct
return(&str_value) is enough ?
*/
switch(item_result_type) {
switch (item_result_type) {
case INT_RESULT:
str->set(int_value);
return str;
@ -421,6 +398,7 @@ String *Item_param::val_str(String* str)
}
/* End of Item_param related */
void Item_copy_string::copy()
{
String *res=item->val_str(&str_value);
@ -438,7 +416,7 @@ String *Item_copy_string::val_str(String *str)
}
/*
** Functions to convert item to field (for send_fields)
Functions to convert item to field (for send_fields)
*/
/* ARGSUSED */
@ -614,7 +592,7 @@ void Item_field::save_org_in_field(Field *to)
}
}
int Item_field::save_in_field(Field *to)
int Item_field::save_in_field(Field *to)
{
if (result_field->is_null())
{
@ -631,13 +609,13 @@ int Item_field::save_in_field(Field *to)
}
int Item_null::save_in_field(Field *field)
int Item_null::save_in_field(Field *field)
{
return set_field_to_null(field);
}
int Item::save_in_field(Field *field)
int Item::save_in_field(Field *field)
{
int error;
if (result_type() == STRING_RESULT ||
@ -674,7 +652,7 @@ int Item::save_in_field(Field *field)
return (error) ? -1 : 0;
}
int Item_string::save_in_field(Field *field)
int Item_string::save_in_field(Field *field)
{
String *result;
CHARSET_INFO *cs=field->binary()?default_charset_info:((Field_str*)field)->charset();
@ -685,7 +663,7 @@ int Item_string::save_in_field(Field *field)
return (field->store(result->ptr(),result->length(),cs)) ? -1 : 0;
}
int Item_int::save_in_field(Field *field)
int Item_int::save_in_field(Field *field)
{
longlong nr=val_int();
if (null_value)
@ -694,7 +672,7 @@ int Item_int::save_in_field(Field *field)
return (field->store(nr)) ? -1 : 0;
}
int Item_real::save_in_field(Field *field)
int Item_real::save_in_field(Field *field)
{
double nr=val();
if (null_value)
@ -716,7 +694,8 @@ inline uint char_val(char X)
X-'a'+10);
}
Item_varbinary::Item_varbinary(const char *str, uint str_length, CHARSET_INFO *cs)
Item_varbinary::Item_varbinary(const char *str, uint str_length,
CHARSET_INFO *cs)
{
name=(char*) str-2; // Lex makes this start with 0x
max_length=(str_length+1)/2;
@ -748,7 +727,7 @@ longlong Item_varbinary::val_int()
}
int Item_varbinary::save_in_field(Field *field)
int Item_varbinary::save_in_field(Field *field)
{
int error;
CHARSET_INFO *cs=field->binary()?default_charset_info:((Field_str*)field)->charset();

View file

@ -50,7 +50,7 @@ public:
// alloc & destruct is done as start of select using sql_alloc
Item();
virtual ~Item() { name=0; } /*lint -e1509 */
void set_name(char* str,uint length=0);
void set_name(const char *str,uint length=0);
void init_make_field(Send_field *tmp_field,enum enum_field_types type);
virtual bool fix_fields(THD *, struct st_table_list *, Item **);
virtual int save_in_field(Field *field);
@ -82,7 +82,6 @@ public:
virtual bool get_date(TIME *ltime,bool fuzzydate);
virtual bool get_time(TIME *ltime);
virtual bool is_null() { return 0; }
virtual unsigned int size_of()= 0;
};
@ -100,7 +99,6 @@ public:
field_name(field_name_par), depended_from(0)
{ name = (char*) field_name_par; }
const char *full_name() const;
unsigned int size_of() { return sizeof(*this);}
};
@ -141,7 +139,6 @@ public:
bool get_date(TIME *ltime,bool fuzzydate);
bool get_time(TIME *ltime);
bool is_null() { return field->is_null(); }
unsigned int size_of() { return sizeof(*this);}
};
@ -163,7 +160,6 @@ public:
bool basic_const_item() const { return 1; }
Item *new_item() { return new Item_null(name); }
bool is_null() { return 1; }
unsigned int size_of() { return sizeof(*this);}
};
class Item_param :public Item
@ -176,10 +172,12 @@ public:
enum enum_field_types buffer_type;
my_bool long_data_supplied;
Item_param(char *name_par=0){
Item_param(char *name_par=0)
{
name= name_par ? name_par : (char*) "?";
long_data_supplied = false;
item_type = STRING_ITEM; item_result_type = STRING_RESULT;
item_type = STRING_ITEM;
item_result_type = STRING_RESULT;
}
enum Type type() const { return item_type; }
double val();
@ -189,13 +187,13 @@ public:
int save_in_field(Field *field);
void set_null();
void set_int(longlong i);
void set_double(float i);
void set_double(double i);
void set_value(const char *str, uint length);
void set_long_str(const char *str, ulong length);
void set_long_binary(const char *str, ulong length);
void set_longdata(const char *str, ulong length);
void set_long_end();
void reset() {}
enum Item_result result_type () const
{ return item_result_type; }
Item *new_item() { return new Item_param(name); }
@ -227,7 +225,6 @@ public:
bool basic_const_item() const { return 1; }
Item *new_item() { return new Item_int(name,value,max_length); }
void print(String *str);
unsigned int size_of() { return sizeof(*this);}
};
@ -242,7 +239,6 @@ public:
void make_field(Send_field *field);
Item *new_item() { return new Item_uint(name,max_length); }
void print(String *str);
unsigned int size_of() { return sizeof(*this);}
};
@ -273,7 +269,6 @@ public:
void make_field(Send_field *field);
bool basic_const_item() const { return 1; }
Item *new_item() { return new Item_real(name,value,decimals,max_length); }
unsigned int size_of() { return sizeof(*this);}
};
@ -285,7 +280,6 @@ public:
decimals=NOT_FIXED_DEC;
max_length=DBL_DIG+8;
}
unsigned int size_of() { return sizeof(*this);}
};
class Item_string :public Item
@ -319,7 +313,6 @@ public:
String *const_string() { return &str_value; }
inline void append(char *str,uint length) { str_value.append(str,length); }
void print(String *str);
unsigned int size_of() { return sizeof(*this);}
};
@ -331,7 +324,7 @@ public:
Item_default() { name= (char*) "DEFAULT"; }
enum Type type() const { return DEFAULT_ITEM; }
void make_field(Send_field *field) {}
bool save_in_field(Field *field)
int save_in_field(Field *field)
{
field->set_default();
return 0;
@ -340,7 +333,6 @@ public:
virtual longlong val_int() { return 0; }
virtual String *val_str(String *str) { return 0; }
bool basic_const_item() const { return 1; }
unsigned int size_of() { return sizeof(*this);}
};
@ -352,7 +344,6 @@ public:
Item_datetime(const char *item_name): Item_string(item_name,"",0,default_charset_info)
{ max_length=19;}
void make_field(Send_field *field);
unsigned int size_of() { return sizeof(*this);}
};
class Item_empty_string :public Item_string
@ -360,7 +351,6 @@ class Item_empty_string :public Item_string
public:
Item_empty_string(const char *header,uint length) :Item_string("",0,default_charset_info)
{ name=(char*) header; max_length=length;}
unsigned int size_of() { return sizeof(*this);}
};
class Item_varbinary :public Item
@ -375,7 +365,6 @@ public:
int save_in_field(Field *field);
void make_field(Send_field *field);
enum Item_result result_type () const { return INT_RESULT; }
unsigned int size_of() { return sizeof(*this);}
};
@ -388,7 +377,6 @@ public:
Field *tmp_table_field(TABLE *t_arg=(TABLE *)0) { return result_field; }
table_map used_tables() const { return 1; }
virtual void fix_length_and_dec()=0;
unsigned int size_of() { return sizeof(*this);}
};
@ -438,7 +426,6 @@ public:
void save_org_in_field(Field *field) { (*ref)->save_org_in_field(field); }
enum Item_result result_type () const { return (*ref)->result_type(); }
table_map used_tables() const { return (*ref)->used_tables(); }
unsigned int size_of() { return sizeof(*this);}
};
@ -458,10 +445,10 @@ public:
{
return ref->save_in_field(field);
}
unsigned int size_of() { return sizeof(*this);}
};
#include "gstream.h"
#include "spatial.h"
#include "item_sum.h"
#include "item_func.h"
@ -495,7 +482,6 @@ public:
table_map used_tables() const { return (table_map) 1L; }
bool const_item() const { return 0; }
bool is_null() { return null_value; }
unsigned int size_of() { return sizeof(*this);}
};
@ -506,7 +492,6 @@ public:
Item_buff() :null_value(0) {}
virtual bool cmp(void)=0;
virtual ~Item_buff(); /*line -e1509 */
unsigned int size_of() { return sizeof(*this);}
};
class Item_str_buff :public Item_buff
@ -517,7 +502,6 @@ public:
Item_str_buff(Item *arg) :item(arg),value(arg->max_length) {}
bool cmp(void);
~Item_str_buff(); // Deallocate String:s
unsigned int size_of() { return sizeof(*this);}
};
@ -528,7 +512,6 @@ class Item_real_buff :public Item_buff
public:
Item_real_buff(Item *item_par) :item(item_par),value(0.0) {}
bool cmp(void);
unsigned int size_of() { return sizeof(*this);}
};
class Item_int_buff :public Item_buff
@ -538,7 +521,6 @@ class Item_int_buff :public Item_buff
public:
Item_int_buff(Item *item_par) :item(item_par),value(0) {}
bool cmp(void);
unsigned int size_of() { return sizeof(*this);}
};
@ -555,7 +537,6 @@ public:
buff= (char*) sql_calloc(length=field->pack_length());
}
bool cmp(void);
unsigned int size_of() { return sizeof(*this);}
};
extern Item_buff *new_Item_buff(Item *item);

View file

@ -22,14 +22,13 @@
#endif
#include "mysql_priv.h"
#include "slave.h" // for wait_for_master_pos
#include <m_ctype.h>
#include <hash.h>
#include <time.h>
#include <ft_global.h>
#include <zlib.h>
#include "slave.h" // for wait_for_master_pos
#include "gstream.h"
#include <assert.h>
/* return TRUE if item is a constant */
@ -231,9 +230,11 @@ Field *Item_func::tmp_table_field(TABLE *t_arg)
break;
case STRING_RESULT:
if (max_length > 255)
res= new Field_blob(max_length, maybe_null, name, t_arg, binary);
res= new Field_blob(max_length, maybe_null, name, t_arg, binary,
str_value.charset());
else
res= new Field_string(max_length, maybe_null, name, t_arg, binary);
res= new Field_string(max_length, maybe_null, name, t_arg, binary,
str_value.charset());
break;
}
return res;
@ -2390,18 +2391,19 @@ longlong Item_func_bit_xor::val_int()
Item *get_system_var(enum_var_type var_type, LEX_STRING name)
{
if (!my_strcasecmp(name.str,"VERSION"))
return new Item_string("@@VERSION",server_version,
(uint) strlen(server_version));
if (!my_strcasecmp(system_charset_info, name.str, "VERSION"))
return new Item_string("@@VERSION", server_version,
(uint) strlen(server_version),
system_charset_info);
THD *thd=current_thd;
Item *item;
sys_var *var;
char buff[MAX_SYS_VAR_LENGTH+3];
if (!(var= find_sys_var(name.str)))
if (!(var= find_sys_var(name.str, name.length)))
{
net_printf(&thd->net, ER_UNKNOWN_SYSTEM_VARIABLE, name.str);
net_printf(thd, ER_UNKNOWN_SYSTEM_VARIABLE, name.str);
return 0;
}
if (!(item=var->item(thd, var_type)))
@ -2415,6 +2417,23 @@ Item *get_system_var(enum_var_type var_type, LEX_STRING name)
}
Item *get_system_var(enum_var_type var_type, const char *var_name, uint length,
const char *item_name)
{
THD *thd=current_thd;
Item *item;
sys_var *var;
var= find_sys_var(var_name, length);
DBUG_ASSERT(var != 0);
if (!(item=var->item(thd, var_type)))
return 0; // Impossible
thd->safe_to_cache_query=0;
item->set_name(item_name); // Will use original name
return item;
}
/*
Check a user level lock.

View file

@ -39,7 +39,7 @@ public:
enum Functype { UNKNOWN_FUNC,EQ_FUNC,EQUAL_FUNC,NE_FUNC,LT_FUNC,LE_FUNC,
GE_FUNC,GT_FUNC,FT_FUNC,
LIKE_FUNC,NOTLIKE_FUNC,ISNULL_FUNC,ISNOTNULL_FUNC,
COND_AND_FUNC, COND_OR_FUNC, CONX_XOR_FUNC, BETWEEN, IN_FUNC,
COND_AND_FUNC, COND_OR_FUNC, COND_XOR_FUNC, BETWEEN, IN_FUNC,
INTERVAL_FUNC,
SP_EQUALS_FUNC, SP_DISJOINT_FUNC,SP_INTERSECTS_FUNC,
SP_TOUCHES_FUNC,SP_CROSSES_FUNC,SP_WITHIN_FUNC,

View file

@ -2394,8 +2394,6 @@ null:
General functions for spatial objects
********************************************************/
#include "gstream.h"
String *Item_func_geometry_from_text::val_str(String *str)
{
Geometry geom;
@ -2715,7 +2713,7 @@ String *Item_func_spatial_collection::val_str(String *str)
}
}
if (str->length() > max_allowed_packet)
if (str->length() > current_thd->variables.max_allowed_packet)
goto ret;
null_value = 0;

View file

@ -70,7 +70,6 @@ public:
void print(String *str);
void fix_num_length_and_dec();
virtual bool setup(THD *thd) {return 0;}
unsigned int size_of() { return sizeof(*this);}
};
@ -85,7 +84,6 @@ public:
longlong val_int() { return (longlong) val(); } /* Real as default */
String *val_str(String*str);
void reset_field();
unsigned int size_of() { return sizeof(*this);}
};
@ -100,7 +98,6 @@ public:
double val() { return (double) val_int(); }
String *val_str(String*str);
enum Item_result result_type () const { return INT_RESULT; }
unsigned int size_of() { return sizeof(*this);}
};
@ -118,7 +115,6 @@ class Item_sum_sum :public Item_sum_num
void reset_field();
void update_field(int offset);
const char *func_name() const { return "sum"; }
unsigned int size_of() { return sizeof(*this);}
};
@ -141,7 +137,6 @@ class Item_sum_count :public Item_sum_int
void reset_field();
void update_field(int offset);
const char *func_name() const { return "count"; }
unsigned int size_of() { return sizeof(*this);}
};
@ -193,7 +188,6 @@ class Item_sum_count_distinct :public Item_sum_int
void update_field(int offset) { return ; } // Never called
const char *func_name() const { return "count_distinct"; }
bool setup(THD *thd);
unsigned int size_of() { return sizeof(*this);}
};
@ -213,7 +207,6 @@ public:
String *val_str(String*);
void make_field(Send_field *field);
void fix_length_and_dec() {}
unsigned int size_of() { return sizeof(*this);}
};
@ -235,7 +228,6 @@ class Item_sum_avg :public Item_sum_num
Item *result_item(Field *field)
{ return new Item_avg_field(this); }
const char *func_name() const { return "avg"; }
unsigned int size_of() { return sizeof(*this);}
};
class Item_sum_std;
@ -252,7 +244,6 @@ public:
bool is_null() { (void) val_int(); return null_value; }
void make_field(Send_field *field);
void fix_length_and_dec() {}
unsigned int size_of() { return sizeof(*this);}
};
class Item_sum_std :public Item_sum_num
@ -273,7 +264,6 @@ class Item_sum_std :public Item_sum_num
Item *result_item(Field *field)
{ return new Item_std_field(this); }
const char *func_name() const { return "std"; }
unsigned int size_of() { return sizeof(*this);}
};
@ -316,7 +306,6 @@ class Item_sum_hybrid :public Item_sum
void min_max_update_str_field(int offset);
void min_max_update_real_field(int offset);
void min_max_update_int_field(int offset);
unsigned int size_of() { return sizeof(*this);}
};
@ -328,7 +317,6 @@ public:
bool add();
const char *func_name() const { return "min"; }
unsigned int size_of() { return sizeof(*this);}
};
@ -340,7 +328,6 @@ public:
bool add();
const char *func_name() const { return "max"; }
unsigned int size_of() { return sizeof(*this);}
};
@ -356,7 +343,6 @@ class Item_sum_bit :public Item_sum_int
void reset();
longlong val_int();
void reset_field();
unsigned int size_of() { return sizeof(*this);}
};
@ -367,7 +353,6 @@ class Item_sum_or :public Item_sum_bit
bool add();
void update_field(int offset);
const char *func_name() const { return "bit_or"; }
unsigned int size_of() { return sizeof(*this);}
};
@ -378,7 +363,6 @@ class Item_sum_and :public Item_sum_bit
bool add();
void update_field(int offset);
const char *func_name() const { return "bit_and"; }
unsigned int size_of() { return sizeof(*this);}
};
/*
@ -409,7 +393,6 @@ public:
bool add();
void reset_field() {};
void update_field(int offset_arg) {};
unsigned int size_of() { return sizeof(*this);}
};

View file

@ -477,11 +477,10 @@ void Item_func_curtime::fix_length_and_dec()
value=(longlong) ((ulong) ((uint) start->tm_hour)*10000L+
(ulong) (((uint) start->tm_min)*100L+
(uint) start->tm_sec));
sprintf(buff,"%02d:%02d:%02d",
(int) start->tm_hour,
(int) start->tm_min,
(int) start->tm_sec);
buff_length=(uint) strlen(buff);
buff_length= my_sprintf(buff, (buff,"%02d:%02d:%02d",
(int) start->tm_hour,
(int) start->tm_min,
(int) start->tm_sec));
}
void Item_func_now::fix_length_and_dec()
@ -497,14 +496,13 @@ void Item_func_now::fix_length_and_dec()
(longlong) ((ulong) ((uint) start->tm_hour)*10000L+
(ulong) (((uint) start->tm_min)*100L+
(uint) start->tm_sec)));
sprintf(buff,"%04d-%02d-%02d %02d:%02d:%02d",
((int) (start->tm_year+1900)) % 10000,
(int) start->tm_mon+1,
(int) start->tm_mday,
(int) start->tm_hour,
(int) start->tm_min,
(int) start->tm_sec);
buff_length=(uint) strlen(buff);
buff_length= (uint) my_sprintf(buff, (buff,"%04d-%02d-%02d %02d:%02d:%02d",
((int) (start->tm_year+1900)) % 10000,
(int) start->tm_mon+1,
(int) start->tm_mday,
(int) start->tm_hour,
(int) start->tm_min,
(int) start->tm_sec));
/* For getdate */
ltime.year= start->tm_year+1900;
ltime.month= start->tm_mon+1;
@ -538,6 +536,7 @@ String *Item_func_sec_to_time::val_str(String *str)
char buff[23];
const char *sign="";
longlong seconds=(longlong) args[0]->val_int();
ulong length;
if ((null_value=args[0]->null_value))
return (String*) 0;
if (seconds < 0)
@ -546,9 +545,9 @@ String *Item_func_sec_to_time::val_str(String *str)
sign= "-";
}
uint sec= (uint) ((ulonglong) seconds % 3600);
sprintf(buff,"%s%02lu:%02u:%02u",sign,(long) (seconds/3600),
sec/60, sec % 60);
str->copy(buff,(uint) strlen(buff));
length= my_sprintf(buff,(buff,"%s%02lu:%02u:%02u",sign,(long) (seconds/3600),
sec/60, sec % 60));
str->copy(buff, length);
return str;
}
@ -658,6 +657,7 @@ String *Item_func_date_format::val_str(String *str)
TIME l_time;
char intbuff[15];
uint size,weekday;
ulong length;
if (!date_or_time)
{
@ -750,40 +750,39 @@ String *Item_func_date_format::val_str(String *str)
null_value=1;
return 0;
}
sprintf(intbuff,"%d",l_time.day);
str->append(intbuff);
length= my_sprintf(intbuff, (intbuff,"%d",l_time.day));
str->append(intbuff, length);
if (l_time.day >= 10 && l_time.day <= 19)
str->append("th");
else
{
switch (l_time.day %10)
{
switch (l_time.day %10) {
case 1:
str->append("st");
str->append("st",2);
break;
case 2:
str->append("nd");
str->append("nd",2);
break;
case 3:
str->append("rd");
str->append("rd",2);
break;
default:
str->append("th");
str->append("th",2);
break;
}
}
break;
case 'Y':
sprintf(intbuff,"%04d",l_time.year);
str->append(intbuff);
str->append(intbuff,4);
break;
case 'y':
sprintf(intbuff,"%02d",l_time.year%100);
str->append(intbuff);
str->append(intbuff,2);
break;
case 'm':
sprintf(intbuff,"%02d",l_time.month);
str->append(intbuff);
str->append(intbuff,2);
break;
case 'c':
sprintf(intbuff,"%d",l_time.month);
@ -791,7 +790,7 @@ String *Item_func_date_format::val_str(String *str)
break;
case 'd':
sprintf(intbuff,"%02d",l_time.day);
str->append(intbuff);
str->append(intbuff,2);
break;
case 'e':
sprintf(intbuff,"%d",l_time.day);
@ -799,16 +798,16 @@ String *Item_func_date_format::val_str(String *str)
break;
case 'H':
sprintf(intbuff,"%02d",l_time.hour);
str->append(intbuff);
str->append(intbuff,2);
break;
case 'h':
case 'I':
sprintf(intbuff,"%02d", (l_time.hour+11)%12+1);
str->append(intbuff);
str->append(intbuff,2);
break;
case 'i': /* minutes */
sprintf(intbuff,"%02d",l_time.minute);
str->append(intbuff);
str->append(intbuff,2);
break;
case 'j':
if (date_or_time)
@ -819,7 +818,7 @@ String *Item_func_date_format::val_str(String *str)
sprintf(intbuff,"%03d",
(int) (calc_daynr(l_time.year,l_time.month,l_time.day) -
calc_daynr(l_time.year,1,1)) + 1);
str->append(intbuff);
str->append(intbuff,3);
break;
case 'k':
sprintf(intbuff,"%d",l_time.hour);
@ -830,7 +829,7 @@ String *Item_func_date_format::val_str(String *str)
str->append(intbuff);
break;
case 'p':
str->append(l_time.hour < 12 ? "AM" : "PM");
str->append(l_time.hour < 12 ? "AM" : "PM",2);
break;
case 'r':
sprintf(intbuff,(l_time.hour < 12) ? "%02d:%02d:%02d AM" :
@ -844,7 +843,8 @@ String *Item_func_date_format::val_str(String *str)
str->append(intbuff);
break;
case 'T':
sprintf(intbuff,"%02d:%02d:%02d",l_time.hour,l_time.minute,l_time.second);
sprintf(intbuff,"%02d:%02d:%02d", l_time.hour, l_time.minute,
l_time.second);
str->append(intbuff);
break;
case 'U':
@ -852,7 +852,7 @@ String *Item_func_date_format::val_str(String *str)
{
uint year;
sprintf(intbuff,"%02d",calc_week(&l_time, 0, (*ptr) == 'U', &year));
str->append(intbuff);
str->append(intbuff,2);
}
break;
case 'v':
@ -860,7 +860,7 @@ String *Item_func_date_format::val_str(String *str)
{
uint year;
sprintf(intbuff,"%02d",calc_week(&l_time, 1, (*ptr) == 'V', &year));
str->append(intbuff);
str->append(intbuff,2);
}
break;
case 'x':
@ -869,13 +869,13 @@ String *Item_func_date_format::val_str(String *str)
uint year;
(void) calc_week(&l_time, 1, (*ptr) == 'X', &year);
sprintf(intbuff,"%04d",year);
str->append(intbuff);
str->append(intbuff,4);
}
break;
case 'w':
weekday=calc_weekday(calc_daynr(l_time.year,l_time.month,l_time.day),1);
sprintf(intbuff,"%01d",weekday);
str->append(intbuff);
sprintf(intbuff,"%d",weekday);
str->append(intbuff,1);
break;
default:
str->append(*ptr);

View file

@ -176,7 +176,6 @@ public:
const char *func_name() const { return "weekday"; }
enum Item_result result_type () const { return INT_RESULT; }
void fix_length_and_dec() { decimals=0; max_length=1; maybe_null=1; }
unsigned int size_of() { return sizeof(*this);}
};
class Item_func_dayname :public Item_func_weekday
@ -202,7 +201,6 @@ public:
{
decimals=0; max_length=10;
}
unsigned int size_of() { return sizeof(*this);}
};
@ -240,7 +238,6 @@ public:
{
return (!t_arg) ? result_field : new Field_date(maybe_null, name, t_arg);
}
unsigned int size_of() { return sizeof(*this);}
};
@ -259,7 +256,6 @@ public:
return (!t_arg) ? result_field : new Field_datetime(maybe_null, name,
t_arg);
}
unsigned int size_of() { return sizeof(*this);}
};
@ -286,7 +282,6 @@ public:
{
return (!t_arg) ? result_field : new Field_time(maybe_null, name, t_arg);
}
unsigned int size_of() { return sizeof(*this);}
};
@ -300,7 +295,6 @@ public:
const char *func_name() const { return "curdate"; }
void fix_length_and_dec(); /* Retrieves curtime */
bool get_date(TIME *res,bool fuzzy_date);
unsigned int size_of() { return sizeof(*this);}
};
@ -322,7 +316,6 @@ public:
const char *func_name() const { return "now"; }
void fix_length_and_dec();
bool get_date(TIME *res,bool fuzzy_date);
unsigned int size_of() { return sizeof(*this);}
};
@ -347,7 +340,6 @@ public:
const char *func_name() const { return "date_format"; }
void fix_length_and_dec();
uint format_length(const String *format);
unsigned int size_of() { return sizeof(*this);}
};
@ -407,7 +399,6 @@ public:
double val() { return (double) val_int(); }
longlong val_int();
bool get_date(TIME *res,bool fuzzy_date);
unsigned int size_of() { return sizeof(*this);}
};
class Item_extract :public Item_int_func
@ -421,7 +412,6 @@ class Item_extract :public Item_int_func
longlong val_int();
const char *func_name() const { return "extract"; }
void fix_length_and_dec();
unsigned int size_of() { return sizeof(*this);}
};
class Item_typecast :public Item_str_func

View file

@ -29,9 +29,9 @@ public:
:Item_real_func(list) {}
double val() { return 0.0; }
void fix_length_and_dec() { decimals=0; max_length=6; }
unsigned int size_of() { return sizeof(*this);}
};
class Item_sum_unique_users :public Item_sum_num
{
public:

View file

@ -327,7 +327,6 @@ static SYMBOL symbols[] = {
{ "SQL_BUFFER_RESULT", SYM(SQL_BUFFER_RESULT),0,0},
{ "SQL_CACHE", SYM(SQL_CACHE_SYM), 0, 0},
{ "SQL_CALC_FOUND_ROWS", SYM(SQL_CALC_FOUND_ROWS),0,0},
{ "SQL_ERROR_COUNT", SYM(SQL_ERROR_COUNT),0,0},
{ "SQL_NO_CACHE", SYM(SQL_NO_CACHE_SYM), 0, 0},
{ "SQL_SMALL_RESULT", SYM(SQL_SMALL_RESULT),0,0},
{ "SQL_THREAD", SYM(SQL_THREAD),0,0},

View file

@ -215,15 +215,18 @@ bool MYSQL_LOG::open(const char *log_name, enum_log_type log_type_arg,
time_t skr=time(NULL);
struct tm tm_tmp;
localtime_r(&skr,&tm_tmp);
sprintf(buff,"# %s, Version: %s at %02d%02d%02d %2d:%02d:%02d\n",
my_progname,server_version,
tm_tmp.tm_year % 100,
tm_tmp.tm_mon+1,
tm_tmp.tm_mday,
tm_tmp.tm_hour,
tm_tmp.tm_min,
tm_tmp.tm_sec);
if (my_b_write(&log_file, (byte*) buff,(uint) strlen(buff)) ||
ulong length;
length= my_sprintf(buff,
(buff,
"# %s, Version: %s at %02d%02d%02d %2d:%02d:%02d\n",
my_progname,server_version,
tm_tmp.tm_year % 100,
tm_tmp.tm_mon+1,
tm_tmp.tm_mday,
tm_tmp.tm_hour,
tm_tmp.tm_min,
tm_tmp.tm_sec));
if (my_b_write(&log_file, (byte*) buff, length) ||
flush_io_cache(&log_file))
goto err;
break;
@ -931,7 +934,8 @@ bool MYSQL_LOG::write(THD *thd,enum enum_server_command command,
{
if (is_open() && (what_to_log & (1L << (uint) command)))
{
int error=0;
uint length;
int error= 0;
VOID(pthread_mutex_lock(&LOCK_log));
/* Test if someone closed after the is_open test */
@ -965,6 +969,7 @@ bool MYSQL_LOG::write(THD *thd,enum enum_server_command command,
last_time=skr;
struct tm tm_tmp;
struct tm *start;
ulong length;
localtime_r(&skr,&tm_tmp);
start=&tm_tmp;
/* Note that my_b_write() assumes it knows the length for this */
@ -980,8 +985,10 @@ bool MYSQL_LOG::write(THD *thd,enum enum_server_command command,
}
else if (my_b_write(&log_file, (byte*) "\t\t",2) < 0)
error=errno;
sprintf(buff,"%7ld %-11.11s", id,command_name[(uint) command]);
if (my_b_write(&log_file, (byte*) buff,strlen(buff)))
length=my_sprintf(buff,
(buff, "%7ld %-11.11s", id,
command_name[(uint) command]));
if (my_b_write(&log_file, (byte*) buff,length))
error=errno;
if (format)
{
@ -1218,11 +1225,7 @@ err:
/*
Write update log in a format suitable for incremental backup
NOTE
- This code should be deleted in MySQL 5,0 as the binary log
is a full replacement for the update log.
This is also used by the slow query log.
*/
bool MYSQL_LOG::write(THD *thd,const char *query, uint query_length,

View file

@ -1516,9 +1516,12 @@ void Append_block_log_event::print(FILE* file, bool short_form,
#ifndef MYSQL_CLIENT
void Append_block_log_event::pack_info(String* packet)
{
char buf1[256];
sprintf(buf1, ";file_id=%u;block_len=%u", file_id, block_len);
net_store_data(packet, buf1);
char buf[256];
uint length;
length= (uint) my_sprintf(buf,
(buf, ";file_id=%u;block_len=%u", file_id,
block_len));
net_store_data(packet, buf, length);
}
@ -1560,9 +1563,10 @@ void Delete_file_log_event::print(FILE* file, bool short_form,
#ifndef MYSQL_CLIENT
void Delete_file_log_event::pack_info(String* packet)
{
char buf1[64];
sprintf(buf1, ";file_id=%u", (uint) file_id);
net_store_data(packet, buf1);
char buf[64];
uint length;
length= (uint) my_sprintf(buf, (buf, ";file_id=%u", (uint) file_id));
net_store_data(packet, buf, length);
}
#endif
@ -1607,8 +1611,9 @@ void Execute_load_log_event::print(FILE* file, bool short_form,
void Execute_load_log_event::pack_info(String* packet)
{
char buf[64];
sprintf(buf, ";file_id=%u", (uint) file_id);
net_store_data(packet, buf);
uint length;
length= (uint) my_sprintf(buf, (buf, ";file_id=%u", (uint) file_id));
net_store_data(packet, buf, length);
}
#endif

View file

@ -40,6 +40,7 @@
#include "mysql_version.h"
#include "mysqld_error.h"
#include "errmsg.h"
#include <assert.h>
#if defined( OS2) && defined(MYSQL_SERVER)
#undef ER
@ -124,7 +125,7 @@ HANDLE create_named_pipe(NET *net, uint connect_timeout, char **arg_host,
if (!host || !strcmp(host,LOCAL_HOST))
host=LOCAL_HOST_NAMEDPIPE;
sprintf( szPipeName, "\\\\%s\\pipe\\%s", host, unix_socket);
sprintf(szPipeName, "\\\\%s\\pipe\\%s", host, unix_socket);
DBUG_PRINT("info",("Server name: '%s'. Named Pipe: %s",
host, unix_socket));
@ -456,15 +457,14 @@ mc_simple_command(MYSQL *mysql,enum enum_server_command command,
if (!arg)
arg="";
if (net_write_command(net,(uchar) command,arg,
length ? length :(uint) strlen(arg)))
if (net_write_command(net, (uchar) command, NullS, 0, arg, length))
{
DBUG_PRINT("error",("Can't send command to server. Error: %d",socket_errno));
DBUG_PRINT("error",("Can't send command to server. Error: %d",
socket_errno));
mc_end_server(mysql);
if (mc_mysql_reconnect(mysql))
goto end;
if (net_write_command(net,(uchar) command,arg,
length ? length :(uint) strlen(arg)))
if (net_write_command(net,(uchar) command, NullS, 0, arg, length))
{
net->last_errno=CR_SERVER_GONE_ERROR;
strmov(net->last_error,ER(net->last_errno));
@ -1027,18 +1027,19 @@ get_info:
DBUG_RETURN(0);
}
int mc_mysql_query(MYSQL *mysql, const char *query, uint length)
int mc_mysql_query(MYSQL *mysql, const char *query, uint length)
{
DBUG_ENTER("mysql_real_query");
DBUG_ENTER("mc_mysql_query");
DBUG_PRINT("enter",("handle: %lx",mysql));
DBUG_PRINT("query",("Query = \"%s\"",query));
if (!length)
length = strlen(query);
DBUG_ASSERT(length == strlen(query));
if (mc_simple_command(mysql,COM_QUERY,query,length,1))
DBUG_RETURN(-1);
DBUG_RETURN(mc_mysql_read_query_result(mysql));
}
static int mc_send_file_to_server(MYSQL *mysql, const char *filename)
{
int fd, readcount, result= -1;

View file

@ -294,7 +294,7 @@ inline THD *_current_thd(void)
#define prepare_execute(A) ((A)->command == COM_EXECUTE)
int mysql_create_db(THD *thd, char *db, HA_CREATE_INFO *create, bool silent);
int mysql_alter_db(THD *thd, char *db, HA_CREATE_INFO *create, bool silent);
int mysql_alter_db(THD *thd, const char *db, HA_CREATE_INFO *create);
int mysql_rm_db(THD *thd,char *db,bool if_exists, bool silent);
void mysql_binlog_send(THD* thd, char* log_ident, my_off_t pos, ushort flags);
int mysql_rm_table(THD *thd,TABLE_LIST *tables, my_bool if_exists);
@ -308,8 +308,13 @@ int quick_rm_table(enum db_type base,const char *db,
bool mysql_rename_tables(THD *thd, TABLE_LIST *table_list);
bool mysql_change_db(THD *thd,const char *name);
void mysql_parse(THD *thd,char *inBuf,uint length);
void free_items(Item *item);
bool alloc_query(THD *thd, char *packet, ulong packet_length);
void mysql_init_select(LEX *lex);
void mysql_init_query(THD *thd);
void mysql_reset_errors(THD *thd);
bool mysql_new_select(LEX *lex, bool move_down);
void create_select_for_variable(const char *var_name);
void mysql_init_multi_delete(LEX *lex);
void init_max_user_conn(void);
void free_max_user_conn(void);
@ -318,7 +323,7 @@ pthread_handler_decl(handle_bootstrap,arg);
sig_handler end_thread_signal(int sig);
void end_thread(THD *thd,bool put_in_cache);
void flush_thread_cache();
void mysql_execute_command(void);
void mysql_execute_command(THD *thd);
bool do_command(THD *thd);
bool dispatch_command(enum enum_server_command command, THD *thd,
char* packet, uint packet_length);
@ -349,11 +354,12 @@ int mysql_optimize_table(THD* thd, TABLE_LIST* table_list,
bool check_simple_select();
/* net_pkg.c */
void send_warning(NET *net, uint sql_errno, const char *err=0);
void net_printf(NET *net,uint sql_errno, ...);
void send_ok(NET *net,ha_rows affected_rows=0L,ulonglong id=0L,
void send_warning(THD *thd, uint sql_errno, const char *err=0);
void net_printf(THD *thd,uint sql_errno, ...);
void send_ok(THD *thd, ha_rows affected_rows=0L, ulonglong id=0L,
const char *info=0);
void send_eof(NET *net,bool no_flush=0);
void send_eof(THD *thd, bool no_flush=0);
void net_send_error(NET *net, uint sql_errno, const char *err);
char *net_store_length(char *packet,ulonglong length);
char *net_store_length(char *packet,uint length);
char *net_store_data(char *to,const char *from);
@ -391,7 +397,7 @@ Field *create_tmp_field(THD *thd, TABLE *table,Item *item, Item::Type type,
int mysql_create_table(THD *thd,const char *db, const char *table_name,
HA_CREATE_INFO *create_info,
List<create_field> &fields, List<Key> &keys,
bool tmp_table, bool no_log);
bool tmp_table, bool no_log, uint select_field_count);
TABLE *create_table_from_items(THD *thd, HA_CREATE_INFO *create_info,
const char *db, const char *name,
List<create_field> *extra_fields,
@ -491,20 +497,19 @@ int mysqld_show_privileges(THD *thd);
int mysqld_show_column_types(THD *thd);
/* sql_prepare.cc */
void mysql_com_prepare(THD *thd,char*packet,uint packet_length);
void mysql_init_query(THD *thd);/* sql_parse. cc */
void mysql_com_execute(THD *thd);
void mysql_com_longdata(THD *thd);
int compare_prep_stmt(PREP_STMT *a, PREP_STMT *b, void *not_used);
void free_prep_stmt(PREP_STMT *stmt, TREE_FREE mode, void *not_used);
bool mysql_stmt_prepare(THD *thd, char *packet, uint packet_length);
void mysql_stmt_execute(THD *thd, char *packet);
void mysql_stm_close(THD *thd, char *packet);
void mysql_stmt_get_longdata(THD *thd, char *pos, ulong packet_length);
int check_insert_fields(THD *thd,TABLE *table,List<Item> &fields,
List<Item> &values, ulong counter);
/* sql_error.cc */
void push_error(uint code, const char *msg);
void push_warning(uint code, const char *msg);
int mysqld_show_warnings(THD *thd);
int mysqld_show_errors(THD *thd);
int mysqld_show_warnings_count(THD *thd);
int mysqld_show_errors_count(THD *);
void push_warning(THD *thd, MYSQL_ERROR::enum_warning_level level, uint code,
const char *msg);
my_bool mysqld_show_warnings(THD *thd, ulong levels_to_show);
/* sql_handler.cc */
int mysql_ha_open(THD *thd, TABLE_LIST *tables);
@ -682,13 +687,13 @@ extern char f_fyllchar;
extern MYSQL_LOG mysql_log,mysql_update_log,mysql_slow_log,mysql_bin_log;
extern FILE *bootstrap_file;
extern pthread_key(MEM_ROOT*,THR_MALLOC);
extern pthread_key(NET*, THR_NET);
extern pthread_mutex_t LOCK_mysql_create_db,LOCK_Acl,LOCK_open,
LOCK_thread_count,LOCK_mapped_file,LOCK_user_locks, LOCK_status,
LOCK_grant, LOCK_error_log, LOCK_delayed_insert,
LOCK_error_log, LOCK_delayed_insert,
LOCK_delayed_status, LOCK_delayed_create, LOCK_crypt, LOCK_timezone,
LOCK_slave_list, LOCK_active_mi, LOCK_manager,
LOCK_global_system_variables;
extern rw_lock_t LOCK_grant;
extern pthread_cond_t COND_refresh, COND_thread_count, COND_manager;
extern pthread_attr_t connection_attrib;
extern I_List<THD> threads;
@ -737,7 +742,7 @@ bool wait_for_locked_table_names(THD *thd, TABLE_LIST *table_list);
void unireg_init(ulong options);
void unireg_end(int signal);
int rea_create_table(my_string file_name,HA_CREATE_INFO *create_info,
int rea_create_table(THD *thd, my_string file_name,HA_CREATE_INFO *create_info,
List<create_field> &create_field,
uint key_count,KEY *key_info);
int format_number(uint inputflag,uint max_length,my_string pos,uint length,
@ -818,6 +823,8 @@ extern int sql_cache_hit(THD *thd, char *inBuf, uint length);
/* item.cc */
Item *get_system_var(enum_var_type var_type, LEX_STRING name);
Item *get_system_var(enum_var_type var_type, const char *var_name, uint length,
const char *item_name);
/* Some inline functions for more speed */

View file

@ -240,6 +240,8 @@ SHOW_COMP_OPTION have_query_cache=SHOW_OPTION_YES;
SHOW_COMP_OPTION have_query_cache=SHOW_OPTION_NO;
#endif
const char *show_comp_option_name[]= {"YES", "NO", "DISABLED"};
bool opt_large_files= sizeof(my_off_t) > 4;
/*
@ -413,15 +415,14 @@ my_bool use_temp_pool=0;
pthread_key(MEM_ROOT*,THR_MALLOC);
pthread_key(THD*, THR_THD);
pthread_key(NET*, THR_NET);
pthread_mutex_t LOCK_mysql_create_db, LOCK_Acl, LOCK_open, LOCK_thread_count,
LOCK_mapped_file, LOCK_status, LOCK_grant,
LOCK_mapped_file, LOCK_status,
LOCK_error_log,
LOCK_delayed_insert, LOCK_delayed_status, LOCK_delayed_create,
LOCK_crypt, LOCK_bytes_sent, LOCK_bytes_received,
LOCK_global_system_variables,
LOCK_user_conn, LOCK_slave_list, LOCK_active_mi;
rw_lock_t LOCK_grant;
pthread_cond_t COND_refresh,COND_thread_count, COND_slave_stopped,
COND_slave_start;
pthread_cond_t COND_thread_cache,COND_flush_thread_cache;
@ -1042,7 +1043,7 @@ static void server_init(void)
if (Service.IsNT() && mysql_unix_port[0] && !opt_bootstrap &&
opt_enable_named_pipe)
{
sprintf( szPipeName, "\\\\.\\pipe\\%s", mysql_unix_port );
sprintf(szPipeName, "\\\\.\\pipe\\%s", mysql_unix_port );
ZeroMemory( &saPipeSecurity, sizeof(saPipeSecurity) );
ZeroMemory( &sdPipeDescriptor, sizeof(sdPipeDescriptor) );
if ( !InitializeSecurityDescriptor(&sdPipeDescriptor,
@ -1127,12 +1128,12 @@ static void server_init(void)
void yyerror(const char *s)
{
NET *net=my_pthread_getspecific_ptr(NET*,THR_NET);
char *yytext=(char*) current_lex->tok_start;
THD *thd=current_thd;
char *yytext=(char*) thd->lex.tok_start;
if (!strcmp(s,"parse error"))
s=ER(ER_SYNTAX_ERROR);
net_printf(net,ER_PARSE_ERROR, s, yytext ? (char*) yytext : "",
current_lex->yylineno);
net_printf(thd,ER_PARSE_ERROR, s, yytext ? (char*) yytext : "",
thd->lex.yylineno);
}
@ -1148,7 +1149,7 @@ void close_connection(NET *net,uint errcode,bool lock)
if ((vio=net->vio) != 0)
{
if (errcode)
send_error(net,errcode,ER(errcode)); /* purecov: inspected */
net_send_error(net,errcode,ER(errcode)); /* purecov: inspected */
vio_close(vio); /* vio is freed in delete thd */
}
if (lock)
@ -1541,8 +1542,8 @@ static void *signal_hand(void *arg __attribute__((unused)))
if ((pidFile = my_create(pidfile_name,0664, O_WRONLY, MYF(MY_WME))) >= 0)
{
char buff[21];
sprintf(buff,"%lu",(ulong) getpid());
(void) my_write(pidFile, buff,strlen(buff),MYF(MY_WME));
ulong length= my_sprintf(buff, (buff,"%lu",(ulong) getpid()));
(void) my_write(pidFile, buff, length, MYF(MY_WME));
(void) my_close(pidFile,MYF(0));
}
}
@ -1640,11 +1641,12 @@ static void *signal_hand(void *arg __attribute__((unused)))
static int my_message_sql(uint error, const char *str,
myf MyFlags __attribute__((unused)))
{
NET *net;
THD *thd;
DBUG_ENTER("my_message_sql");
DBUG_PRINT("error",("Message: '%s'",str));
if ((net=my_pthread_getspecific_ptr(NET*,THR_NET)))
if ((thd=current_thd))
{
NET *net= &thd->net;
if (!net->last_error[0]) // Return only first message
{
strmake(net->last_error,str,sizeof(net->last_error)-1);
@ -1853,7 +1855,6 @@ int main(int argc, char **argv)
(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_grant,MY_MUTEX_INIT_FAST);
(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);
@ -1871,6 +1872,7 @@ int main(int argc, char **argv)
(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);
@ -2027,7 +2029,7 @@ int main(int argc, char **argv)
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_NET,NULL) ||
if (pthread_key_create(&THR_THD,NULL) ||
pthread_key_create(&THR_MALLOC,NULL))
{
sql_print_error("Can't create thread-keys");
@ -2481,7 +2483,7 @@ static void create_new_thread(THD *thd)
thread_count--;
thd->killed=1; // Safety
(void) pthread_mutex_unlock(&LOCK_thread_count);
net_printf(net,ER_CANT_CREATE_THREAD,error);
net_printf(thd,ER_CANT_CREATE_THREAD,error);
(void) pthread_mutex_lock(&LOCK_thread_count);
close_connection(net,0,0);
delete thd;
@ -2886,6 +2888,7 @@ enum options {
OPT_MAX_JOIN_SIZE, OPT_MAX_SORT_LENGTH,
OPT_MAX_TMP_TABLES, OPT_MAX_USER_CONNECTIONS,
OPT_MAX_WRITE_LOCK_COUNT, OPT_BULK_INSERT_BUFFER_SIZE,
OPT_MAX_ERROR_COUNT, OPT_MAX_PREP_STMT,
OPT_MYISAM_BLOCK_SIZE, OPT_MYISAM_MAX_EXTRA_SORT_FILE_SIZE,
OPT_MYISAM_MAX_SORT_FILE_SIZE, OPT_MYISAM_SORT_BUFFER_SIZE,
OPT_NET_BUFFER_LENGTH, OPT_NET_RETRY_COUNT,
@ -3506,6 +3509,11 @@ struct my_option my_long_options[] =
"Don't start more than this number of threads to handle INSERT DELAYED statements.",
(gptr*) &max_insert_delayed_threads, (gptr*) &max_insert_delayed_threads,
0, GET_ULONG, REQUIRED_ARG, 20, 1, 16384, 0, 1, 0},
{"max_error_count", OPT_MAX_ERROR_COUNT,
"Max number of errors/warnings to store for a statement",
(gptr*) &global_system_variables.max_error_count,
(gptr*) &max_system_variables.max_error_count,
0, GET_ULONG, REQUIRED_ARG, DEFAULT_ERROR_COUNT, 1, 65535, 0, 1, 0},
{"max_heap_table_size", OPT_MAX_HEP_TABLE_SIZE,
"Don't allow creation of heap tables bigger than this.",
(gptr*) &global_system_variables.max_heap_table_size,
@ -3516,6 +3524,11 @@ struct my_option my_long_options[] =
(gptr*) &global_system_variables.max_join_size,
(gptr*) &max_system_variables.max_join_size, 0, GET_ULONG, REQUIRED_ARG,
~0L, 1, ~0L, 0, 1, 0},
{"max_prepared_statements", OPT_MAX_PREP_STMT,
"Max number of prepared_statements for a thread",
(gptr*) &global_system_variables.max_prep_stmt_count,
(gptr*) &max_system_variables.max_prep_stmt_count, 0, GET_ULONG,
REQUIRED_ARG, DEFAULT_PREP_STMT_COUNT, 0, ~0L, 0, 1, 0},
{"max_sort_length", OPT_MAX_SORT_LENGTH,
"The number of bytes to use when sorting BLOB or TEXT values (only the first max_sort_length bytes of each value are used; the rest are ignored).",
(gptr*) &global_system_variables.max_sort_length,

View file

@ -20,19 +20,17 @@
/* Send a error string to client */
void send_error(NET *net, uint sql_errno, const char *err)
void send_error(THD *thd, uint sql_errno, const char *err)
{
uint length;
char buff[MYSQL_ERRMSG_SIZE+2];
THD *thd=current_thd;
NET *net= &thd->net;
DBUG_ENTER("send_error");
DBUG_PRINT("enter",("sql_errno: %d err: %s", sql_errno,
err ? err : net->last_error[0] ?
net->last_error : "NULL"));
query_cache_abort(net);
if (thd)
thd->query_error = 1; // needed to catch query errors during replication
if (!err)
{
if (sql_errno)
@ -48,10 +46,9 @@ void send_error(NET *net, uint sql_errno, const char *err)
}
}
}
push_error(sql_errno, err);
if (net->vio == 0)
{
if (thd && thd->bootstrap)
if (thd->bootstrap)
{
/* In bootstrap it's ok to print on stderr */
fprintf(stderr,"ERROR: %d %s\n",sql_errno,err);
@ -68,53 +65,73 @@ void send_error(NET *net, uint sql_errno, const char *err)
else
{
length=(uint) strlen(err);
set_if_smaller(length,MYSQL_ERRMSG_SIZE);
set_if_smaller(length,MYSQL_ERRMSG_SIZE-1);
}
VOID(net_write_command(net,(uchar) 255,(char*) err,length));
if (thd)
thd->fatal_error=0; // Error message is given
VOID(net_write_command(net,(uchar) 255, "", 0, (char*) err,length));
thd->fatal_error=0; // Error message is given
DBUG_VOID_RETURN;
}
/*
At some point we need to be able to distinguish between warnings and
errors; The following function will help make this easier.
Send an error to the client when a connection is forced close
This is used by mysqld.cc, which doesn't have a THD
*/
void send_warning(NET *net, uint sql_errno, const char *err)
void net_send_error(NET *net, uint sql_errno, const char *err)
{
char buff[2];
uint length;
DBUG_ENTER("send_net_error");
int2store(buff,sql_errno);
length=(uint) strlen(err);
set_if_smaller(length,MYSQL_ERRMSG_SIZE-1);
net_write_command(net,(uchar) 255, buff, 2, err, length);
DBUG_VOID_RETURN;
}
/*
Send a warning to the end user
SYNOPSIS
send_warning()
thd Thread handler
sql_errno Warning number (error message)
err Error string. If not set, use ER(sql_errno)
DESCRIPTION
Register the warning so that the user can get it with mysql_warnings()
Send an ok (+ warning count) to the end user.
*/
void send_warning(THD *thd, uint sql_errno, const char *err)
{
DBUG_ENTER("send_warning");
push_warning(sql_errno, err ? err : ER(sql_errno));
/*
TODO :
Try to return ok with warning status to client, instead
of returning error ..
*/
send_error(net,sql_errno,err);
push_warning(thd, MYSQL_ERROR::WARN_LEVEL_WARN, sql_errno,
err ? err : ER(sql_errno));
send_ok(thd);
DBUG_VOID_RETURN;
}
/*
Write error package and flush to client
It's a little too low level, but I don't want to allow another buffer
It's a little too low level, but I don't want to use another buffer for
this
*/
/* VARARGS3 */
void
net_printf(NET *net, uint errcode, ...)
net_printf(THD *thd, uint errcode, ...)
{
va_list args;
uint length,offset;
const char *format,*text_pos;
int head_length= NET_HEADER_SIZE;
THD *thd=current_thd;
NET *net= &thd->net;
DBUG_ENTER("net_printf");
DBUG_PRINT("enter",("message: %u",errcode));
if (thd)
thd->query_error = 1; // if we are here, something is wrong :-)
query_cache_abort(net); // Safety
va_start(args,errcode);
/*
@ -132,10 +149,9 @@ net_printf(NET *net, uint errcode, ...)
length=sizeof(net->last_error)-1; /* purecov: inspected */
va_end(args);
push_error(errcode, text_pos);
if (net->vio == 0)
{
if (thd && thd->bootstrap)
if (thd->bootstrap)
{
/* In bootstrap it's ok to print on stderr */
fprintf(stderr,"ERROR: %d %s\n",errcode,text_pos);
@ -150,16 +166,42 @@ net_printf(NET *net, uint errcode, ...)
if (offset)
int2store(text_pos-2, errcode);
VOID(net_real_write(net,(char*) net->buff,length+head_length+1+offset));
if (thd)
thd->fatal_error=0; // Error message is given
thd->fatal_error=0; // Error message is given
DBUG_VOID_RETURN;
}
/*
Return ok to the client.
SYNOPSIS
send_ok()
thd Thread handler
affected_rows Number of rows changed by statement
id Auto_increment id for first row (if used)
message Message to send to the client (Used by mysql_status)
DESCRIPTION
The ok packet has the following structure
0 Marker (1 byte)
affected_rows Stored in 1-9 bytes
id Stored in 1-9 bytes
server_status Copy of thd->server_status; Can be used by client
to check if we are inside an transaction
New in 4.0 protocol
warning_count Stored in 2 bytes; New in 4.1 protocol
message Stored as packed length (1-9 bytes) + message
Is not stored if no message
If net->no_send_ok return without sending packet
*/
void
send_ok(NET *net,ha_rows affected_rows,ulonglong id,const char *message)
send_ok(THD *thd, ha_rows affected_rows, ulonglong id, const char *message)
{
if (net->no_send_ok) // hack for re-parsing queries
NET *net= &thd->net;
if (net->no_send_ok || !net->vio) // hack for re-parsing queries
return;
char buff[MYSQL_ERRMSG_SIZE+10],*pos;
@ -167,31 +209,75 @@ send_ok(NET *net,ha_rows affected_rows,ulonglong id,const char *message)
buff[0]=0; // No fields
pos=net_store_length(buff+1,(ulonglong) affected_rows);
pos=net_store_length(pos, (ulonglong) id);
if (net->return_status)
if (thd->client_capabilities & CLIENT_PROTOCOL_41)
{
int2store(pos,*net->return_status);
int2store(pos,thd->server_status);
pos+=2;
/* We can only return up to 65535 warnings in two bytes */
uint tmp= min(thd->total_warn_count, 65535);
int2store(pos, tmp);
pos+= 2;
}
else if (net->return_status) // For 4.0 protocol
{
int2store(pos,thd->server_status);
pos+=2;
}
if (message)
pos=net_store_data((char*) pos,message);
if (net->vio != 0)
{
VOID(my_net_write(net,buff,(uint) (pos-buff)));
VOID(net_flush(net));
}
VOID(my_net_write(net,buff,(uint) (pos-buff)));
VOID(net_flush(net));
DBUG_VOID_RETURN;
}
/*
Send eof (= end of result set) to the client
SYNOPSIS
send_eof()
thd Thread handler
no_flush Set to 1 if there will be more data to the client,
like in send_fields().
DESCRIPTION
The eof packet has the following structure
254 Marker (1 byte)
warning_count Stored in 2 bytes; New in 4.1 protocol
status_flag Stored in 2 bytes;
For flags like SERVER_STATUS_MORE_RESULTS
Note that the warning count will not be sent if 'no_flush' is set as
we don't want to report the warning count until all data is sent to the
client.
*/
void
send_eof(NET *net,bool no_flush)
send_eof(THD *thd, bool no_flush)
{
static char eof_buff[1]= { (char) 254 }; /* Marker for end of fields */
NET *net= &thd->net;
DBUG_ENTER("send_eof");
if (net->vio != 0)
{
VOID(my_net_write(net,eof_buff,1));
if (!no_flush)
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;
}

View file

@ -75,12 +75,12 @@ extern pthread_mutex_t LOCK_bytes_sent , LOCK_bytes_received;
#define TEST_BLOCKING 8
#define MAX_THREE_BYTES 255L*255L*255L
static int net_write_buff(NET *net,const char *packet,ulong len);
static my_bool net_write_buff(NET *net,const char *packet,ulong len);
/* Init with packet info */
int my_net_init(NET *net, Vio* vio)
my_bool my_net_init(NET *net, Vio* vio)
{
DBUG_ENTER("my_net_init");
my_net_local_init(net); /* Set some limits */
@ -127,7 +127,7 @@ void net_end(NET *net)
/* Realloc the packet buffer */
static my_bool net_realloc(NET *net, ulong length)
my_bool net_realloc(NET *net, ulong length)
{
uchar *buff;
ulong pkt_length;
@ -184,14 +184,14 @@ void net_clear(NET *net)
/* Flush write_buffer if not empty. */
int net_flush(NET *net)
my_bool net_flush(NET *net)
{
int error=0;
my_bool error= 0;
DBUG_ENTER("net_flush");
if (net->buff != net->write_pos)
{
error=net_real_write(net,(char*) net->buff,
(ulong) (net->write_pos - net->buff));
error=test(net_real_write(net,(char*) net->buff,
(ulong) (net->write_pos - net->buff)));
net->write_pos=net->buff;
}
/* Sync packet number if using compression */
@ -212,7 +212,7 @@ int net_flush(NET *net)
** NOTE: If compression is used the original package is modified!
*/
int
my_bool
my_net_write(NET *net,const char *packet,ulong len)
{
uchar buff[NET_HEADER_SIZE];
@ -242,17 +242,38 @@ my_net_write(NET *net,const char *packet,ulong len)
/*
Send a command to the server.
As the command is part of the first data packet, we have to do some data
juggling to put the command in there, without having to create a new
packet.
This function will split big packets into sub-packets if needed.
(Each sub packet can only be 2^24 bytes)
SYNOPSIS
net_write_command()
net NET handler
command Command in MySQL server (enum enum_server_command)
header Header to write after command
head_len Length of header
packet Query or parameter to query
len Length of packet
DESCRIPTION
The reason for having both header and packet is so that libmysql
can easy add a header to a special command (like prepared statements)
without having to re-alloc the string.
As the command is part of the first data packet, we have to do some data
juggling to put the command in there, without having to create a new
packet.
This function will split big packets into sub-packets if needed.
(Each sub packet can only be 2^24 bytes)
RETURN VALUES
0 ok
1 error
*/
int
net_write_command(NET *net,uchar command,const char *packet,ulong len)
my_bool
net_write_command(NET *net,uchar command,
const char *header, ulong head_len,
const char *packet, ulong len)
{
ulong length=len+1; /* 1 extra byte for command */
ulong length=len+1+head_len; /* 1 extra byte for command */
uchar buff[NET_HEADER_SIZE+1];
uint header_size=NET_HEADER_SIZE+1;
buff[4]=command; /* For first packet */
@ -260,25 +281,28 @@ net_write_command(NET *net,uchar command,const char *packet,ulong len)
if (length >= MAX_THREE_BYTES)
{
/* Take into account that we have the command in the first header */
len= MAX_THREE_BYTES -1;
len= MAX_THREE_BYTES - 1 - head_len;
do
{
int3store(buff, MAX_THREE_BYTES);
buff[3]= (uchar) net->pkt_nr++;
if (net_write_buff(net,(char*) buff, header_size) ||
net_write_buff(net,packet,len))
net_write_buff(net, header, head_len) ||
net_write_buff(net, packet, len))
return 1;
packet+= len;
length-= MAX_THREE_BYTES;
len=MAX_THREE_BYTES;
head_len=0;
header_size=NET_HEADER_SIZE;
} while (length >= MAX_THREE_BYTES);
len=length; /* Data left to be written */
}
int3store(buff,length);
buff[3]= (uchar) net->pkt_nr++;
return test(net_write_buff(net,(char*) buff,header_size) ||
net_write_buff(net,packet,len) || net_flush(net));
return test(net_write_buff(net, (char*) buff, header_size) ||
(head_len && net_write_buff(net, (char*) header, head_len)) ||
net_write_buff(net, packet, len) || net_flush(net));
}
/*
@ -286,7 +310,7 @@ net_write_command(NET *net,uchar command,const char *packet,ulong len)
One can force the buffer to be flushed with 'net_flush'.
*/
static int
static my_bool
net_write_buff(NET *net,const char *packet,ulong len)
{
ulong left_length=(ulong) (net->buff_end - net->write_pos);
@ -815,13 +839,3 @@ my_net_read(NET *net)
#endif /* HAVE_COMPRESS */
return len;
}
bool net_request_file(NET* net, const char* fname)
{
char tmp [FN_REFLEN+1],*end;
DBUG_ENTER("net_request_file");
tmp[0] = (char) 251; /* NULL_LENGTH */
end=strnmov(tmp+1,fname,sizeof(tmp)-2);
DBUG_RETURN(my_net_write(net,tmp,(uint) (end-tmp)) ||
net_flush(net));
}

View file

@ -186,7 +186,7 @@ err:
my_message(ER_UNKNOWN_ERROR, "Wrong parameters to function register_slave",
MYF(0));
err2:
send_error(&thd->net);
send_error(thd);
return 1;
}
@ -425,10 +425,10 @@ int show_new_master(THD* thd)
if (translate_master(thd, lex_mi, errmsg))
{
if (errmsg[0])
net_printf(&thd->net, ER_ERROR_WHEN_EXECUTING_COMMAND,
net_printf(thd, ER_ERROR_WHEN_EXECUTING_COMMAND,
"SHOW NEW MASTER", errmsg);
else
send_error(&thd->net, 0);
send_error(thd, 0);
DBUG_RETURN(1);
}
@ -444,7 +444,7 @@ int show_new_master(THD* thd)
net_store_data(packet, (longlong)lex_mi->pos);
if (my_net_write(&thd->net, packet->ptr(), packet->length()))
DBUG_RETURN(-1);
send_eof(&thd->net);
send_eof(thd);
DBUG_RETURN(0);
}
}
@ -459,7 +459,7 @@ int update_slave_list(MYSQL* mysql)
int port_ind;
DBUG_ENTER("update_slave_list");
if (mc_mysql_query(mysql,"SHOW SLAVE HOSTS",0) ||
if (mc_mysql_query(mysql,"SHOW SLAVE HOSTS",16) ||
!(res = mc_mysql_store_result(mysql)))
{
error = "Query error";
@ -623,7 +623,7 @@ int show_slave_hosts(THD* thd)
}
}
pthread_mutex_unlock(&LOCK_slave_list);
send_eof(net);
send_eof(thd);
DBUG_RETURN(0);
}
@ -709,7 +709,7 @@ int load_master_data(THD* thd)
(error=terminate_slave_threads(active_mi,restart_thread_mask,
1 /*skip lock*/)))
{
send_error(&thd->net,error);
send_error(thd,error);
unlock_slave_threads(active_mi);
UNLOCK_ACTIVE_MI;
return 1;
@ -717,7 +717,7 @@ int load_master_data(THD* thd)
if (connect_to_master(thd, &mysql, active_mi))
{
net_printf(&thd->net, error= ER_CONNECT_TO_MASTER,
net_printf(thd, error= ER_CONNECT_TO_MASTER,
mc_mysql_error(&mysql));
goto err;
}
@ -727,10 +727,10 @@ int load_master_data(THD* thd)
MYSQL_RES *db_res, **table_res, **table_res_end, **cur_table_res;
uint num_dbs;
if (mc_mysql_query(&mysql, "show databases", 0) ||
if (mc_mysql_query(&mysql, "SHOW DATABASES", 14) ||
!(db_res = mc_mysql_store_result(&mysql)))
{
net_printf(&thd->net, error = ER_QUERY_ON_MASTER,
net_printf(thd, error = ER_QUERY_ON_MASTER,
mc_mysql_error(&mysql));
goto err;
}
@ -744,7 +744,7 @@ int load_master_data(THD* thd)
if (!(table_res = (MYSQL_RES**)thd->alloc(num_dbs * sizeof(MYSQL_RES*))))
{
net_printf(&thd->net, error = ER_OUTOFMEMORY);
net_printf(thd, error = ER_OUTOFMEMORY);
goto err;
}
@ -754,11 +754,11 @@ int load_master_data(THD* thd)
we wait to issue FLUSH TABLES WITH READ LOCK for as long as we
can to minimize the lock time.
*/
if (mc_mysql_query(&mysql, "FLUSH TABLES WITH READ LOCK", 0) ||
mc_mysql_query(&mysql, "SHOW MASTER STATUS",0) ||
if (mc_mysql_query(&mysql, "FLUSH TABLES WITH READ LOCK", 27) ||
mc_mysql_query(&mysql, "SHOW MASTER STATUS",18) ||
!(master_status_res = mc_mysql_store_result(&mysql)))
{
net_printf(&thd->net, error = ER_QUERY_ON_MASTER,
net_printf(thd, error = ER_QUERY_ON_MASTER,
mc_mysql_error(&mysql));
goto err;
}
@ -798,16 +798,16 @@ int load_master_data(THD* thd)
if (mysql_rm_db(thd, db, 1,1) ||
mysql_create_db(thd, db, 0, 1))
{
send_error(&thd->net, 0, 0);
send_error(thd, 0, 0);
cleanup_mysql_results(db_res, cur_table_res - 1, table_res);
goto err;
}
if (mc_mysql_select_db(&mysql, db) ||
mc_mysql_query(&mysql, "show tables", 0) ||
mc_mysql_query(&mysql, "SHOW TABLES", 11) ||
!(*cur_table_res = mc_mysql_store_result(&mysql)))
{
net_printf(&thd->net, error = ER_QUERY_ON_MASTER,
net_printf(thd, error = ER_QUERY_ON_MASTER,
mc_mysql_error(&mysql));
cleanup_mysql_results(db_res, cur_table_res - 1, table_res);
goto err;
@ -848,9 +848,9 @@ int load_master_data(THD* thd)
mc_mysql_free_result(master_status_res);
}
if (mc_mysql_query(&mysql, "UNLOCK TABLES", 0))
if (mc_mysql_query(&mysql, "UNLOCK TABLES", 13))
{
net_printf(&thd->net, error = ER_QUERY_ON_MASTER,
net_printf(thd, error = ER_QUERY_ON_MASTER,
mc_mysql_error(&mysql));
goto err;
}
@ -860,7 +860,7 @@ int load_master_data(THD* thd)
0 /* not only reset, but also reinit */,
&errmsg))
{
send_error(&thd->net, 0, "Failed purging old relay logs");
send_error(thd, 0, "Failed purging old relay logs");
unlock_slave_threads(active_mi);
UNLOCK_ACTIVE_MI;
return 1;
@ -888,7 +888,7 @@ err:
mc_mysql_close(&mysql); // safe to call since we always do mc_mysql_init()
if (!error)
send_ok(&thd->net);
send_ok(thd);
return error;
}

View file

@ -24,8 +24,9 @@
- Use one of the 'sys_var... classes from set_var.h or write a specific
one for the variable type.
- Define it in the 'variable definition list' in this file.
- If the variable should be changeable, it should be added to the
'list of all variables' list in this file.
- If the variable should be changeable or one should be able to access it
with @@variable_name, it should be added to the 'list of all variables'
list in this file.
- If the variable should be changed from the command line, add a definition
of it in the my_option structure list in mysqld.dcc
- If the variable should show up in 'show variables' add it to the
@ -82,6 +83,8 @@ static void fix_net_retry_count(THD *thd, enum_var_type type);
static void fix_max_join_size(THD *thd, enum_var_type type);
static void fix_query_cache_size(THD *thd, enum_var_type type);
static void fix_key_buffer_size(THD *thd, enum_var_type type);
static byte *get_error_count(THD *thd);
static byte *get_warning_count(THD *thd);
/*
Variable definition list
@ -147,6 +150,8 @@ sys_var_long_ptr sys_max_connect_errors("max_connect_errors",
&max_connect_errors);
sys_var_long_ptr sys_max_delayed_threads("max_delayed_threads",
&max_insert_delayed_threads);
sys_var_thd_ulong sys_max_error_count("max_error_count",
&SV::max_error_count);
sys_var_thd_ulong sys_max_heap_table_size("max_heap_table_size",
&SV::max_heap_table_size);
sys_var_thd_ulong sys_max_join_size("max_join_size",
@ -157,6 +162,8 @@ sys_var_thd_ulong sys_sql_max_join_size("sql_max_join_size",
&SV::max_join_size,
fix_max_join_size);
#endif
sys_var_thd_ulong sys_max_prep_stmt_count("max_prepared_statements",
&SV::max_prep_stmt_count);
sys_var_thd_ulong sys_max_sort_length("max_sort_length",
&SV::max_sort_length);
sys_var_long_ptr sys_max_user_connections("max_user_connections",
@ -220,8 +227,6 @@ sys_var_thd_ulong sys_tmp_table_size("tmp_table_size",
&SV::tmp_table_size);
sys_var_thd_ulong sys_net_wait_timeout("wait_timeout",
&SV::net_wait_timeout);
/*
Variables that are bits in THD
*/
@ -283,6 +288,15 @@ static sys_var_timestamp sys_timestamp("timestamp");
static sys_var_last_insert_id sys_last_insert_id("last_insert_id");
static sys_var_last_insert_id sys_identity("identity");
static sys_var_insert_id sys_insert_id("insert_id");
static sys_var_readonly sys_error_count("error_count",
OPT_SESSION,
SHOW_LONG,
get_error_count);
static sys_var_readonly sys_warning_count("warning_count",
OPT_SESSION,
SHOW_LONG,
get_warning_count);
/* alias for last_insert_id() to be compatible with Sybase */
static sys_var_slave_skip_counter sys_slave_skip_counter("sql_slave_skip_counter");
@ -311,6 +325,7 @@ sys_var *sys_variables[]=
&sys_delayed_insert_limit,
&sys_delayed_insert_timeout,
&sys_delayed_queue_size,
&sys_error_count,
&sys_flush,
&sys_flush_time,
&sys_foreign_key_checks,
@ -333,8 +348,10 @@ sys_var *sys_variables[]=
&sys_max_connect_errors,
&sys_max_connections,
&sys_max_delayed_threads,
&sys_max_error_count,
&sys_max_heap_table_size,
&sys_max_join_size,
&sys_max_prep_stmt_count,
&sys_max_sort_length,
&sys_max_tmp_tables,
&sys_max_user_connections,
@ -375,7 +392,8 @@ sys_var *sys_variables[]=
&sys_timestamp,
&sys_tmp_table_size,
&sys_tx_isolation,
&sys_unique_checks
&sys_unique_checks,
&sys_warning_count
};
@ -465,9 +483,11 @@ struct show_var_st init_vars[]= {
{sys_max_binlog_size.name, (char*) &sys_max_binlog_size, SHOW_SYS},
{sys_max_connections.name, (char*) &sys_max_connections, SHOW_SYS},
{sys_max_connect_errors.name, (char*) &sys_max_connect_errors, SHOW_SYS},
{sys_max_error_count.name, (char*) &sys_max_error_count, SHOW_SYS},
{sys_max_delayed_threads.name,(char*) &sys_max_delayed_threads, SHOW_SYS},
{sys_max_heap_table_size.name,(char*) &sys_max_heap_table_size, SHOW_SYS},
{sys_max_join_size.name, (char*) &sys_max_join_size, SHOW_SYS},
{sys_max_prep_stmt_count.name,(char*) &sys_max_prep_stmt_count, SHOW_SYS},
{sys_max_sort_length.name, (char*) &sys_max_sort_length, SHOW_SYS},
{sys_max_user_connections.name,(char*) &sys_max_user_connections, SHOW_SYS},
{sys_max_tmp_tables.name, (char*) &sys_max_tmp_tables, SHOW_SYS},
@ -793,7 +813,7 @@ byte *sys_var_thd_bool::value_ptr(THD *thd, enum_var_type type)
bool sys_var::check_enum(THD *thd, set_var *var, TYPELIB *enum_names)
{
char buff[80], *value;
String str(buff,sizeof(buff)), *res;
String str(buff, sizeof(buff), system_charset_info), *res;
if (var->value->result_type() == STRING_RESULT)
{
@ -831,6 +851,10 @@ err:
We have to use netprintf() instead of my_error() here as this is
called on the parsing stage.
TODO:
With prepared statements/stored procedures this has to be fixed
to create an item that gets the current value at fix_fields() stage.
*/
Item *sys_var::item(THD *thd, enum_var_type var_type)
@ -839,7 +863,7 @@ Item *sys_var::item(THD *thd, enum_var_type var_type)
{
if (var_type != OPT_DEFAULT)
{
net_printf(&thd->net,
net_printf(thd,
var_type == OPT_GLOBAL ? ER_LOCAL_VARIABLE :
ER_GLOBAL_VARIABLE, name);
return 0;
@ -857,10 +881,10 @@ Item *sys_var::item(THD *thd, enum_var_type var_type)
case SHOW_CHAR:
{
char *str= (char*) value_ptr(thd, var_type);
return new Item_string(str,strlen(str));
return new Item_string(str, strlen(str), system_charset_info);
}
default:
net_printf(&thd->net, ER_VAR_CANT_BE_READ, name);
net_printf(thd, ER_VAR_CANT_BE_READ, name);
}
return 0;
}
@ -918,7 +942,7 @@ bool sys_var_thd_conv_charset::check(THD *thd, set_var *var)
{
CONVERT *tmp;
char buff[80];
String str(buff,sizeof(buff)), *res;
String str(buff,sizeof(buff), system_charset_info), *res;
if (!var->value) // Default value
{
@ -1100,6 +1124,21 @@ static bool set_log_update(THD *thd, set_var *var)
return 0;
}
static byte *get_warning_count(THD *thd)
{
thd->sys_var_tmp.long_value=
(thd->warn_count[(uint) MYSQL_ERROR::WARN_LEVEL_NOTE] +
thd->warn_count[(uint) MYSQL_ERROR::WARN_LEVEL_WARN]);
return (byte*) &thd->sys_var_tmp.long_value;
}
static byte *get_error_count(THD *thd)
{
thd->sys_var_tmp.long_value=
thd->warn_count[(uint) MYSQL_ERROR::WARN_LEVEL_ERROR];
return (byte*) &thd->sys_var_tmp.long_value;
}
/****************************************************************************
Main handling of variables:
@ -1161,7 +1200,8 @@ void set_var_init()
{
extern struct my_option my_long_options[]; // From mysqld
hash_init(&system_variable_hash,array_elements(sys_variables),0,0,
hash_init(&system_variable_hash, system_charset_info,
array_elements(sys_variables),0,0,
(hash_get_key) get_sys_var_length,0, HASH_CASE_INSENSITIVE);
sys_var **var, **end;
for (var= sys_variables, end= sys_variables+array_elements(sys_variables) ;
@ -1212,7 +1252,7 @@ sys_var *find_sys_var(const char *str, uint length)
length ? length :
strlen(str));
if (!var)
net_printf(&current_thd->net, ER_UNKNOWN_SYSTEM_VARIABLE, (char*) str);
net_printf(current_thd, ER_UNKNOWN_SYSTEM_VARIABLE, (char*) str);
return var;
}
@ -1286,7 +1326,7 @@ bool set_var::check(THD *thd)
return 0;
}
if (value->fix_fields(thd,0))
if (value->fix_fields(thd, 0, &value))
return 1;
if (var->check_update_type(value->result_type()))
{
@ -1315,7 +1355,7 @@ bool set_var::update(THD *thd)
bool set_var_user::check(THD *thd)
{
return user_var_item->fix_fields(thd,0);
return user_var_item->fix_fields(thd,0, (Item**) 0);
}
@ -1324,7 +1364,7 @@ bool set_var_user::update(THD *thd)
if (user_var_item->update())
{
/* Give an error if it's not given already */
send_error(&thd->net, ER_SET_CONSTANTS_ONLY);
send_error(thd, ER_SET_CONSTANTS_ONLY);
return 1;
}
return 0;

View file

@ -39,6 +39,7 @@ typedef bool (*sys_check_func)(THD *, set_var *);
typedef bool (*sys_update_func)(THD *, set_var *);
typedef void (*sys_after_update_func)(THD *,enum_var_type);
typedef void (*sys_set_default_func)(THD *, enum_var_type);
typedef byte *(*sys_value_ptr_func)(THD *thd);
class sys_var
{
@ -350,6 +351,31 @@ public:
};
/* Variable that you can only read from */
class sys_var_readonly: public sys_var
{
public:
enum_var_type var_type;
SHOW_TYPE show_type;
sys_value_ptr_func value_ptr_func;
sys_var_readonly(const char *name_arg, enum_var_type type,
SHOW_TYPE show_type_arg,
sys_value_ptr_func value_ptr_func_arg)
:sys_var(name_arg), var_type(type),
show_type(show_type_arg), value_ptr_func(value_ptr_func_arg)
{}
bool update(THD *thd, set_var *var) { return 1; }
bool check_default(enum_var_type type) { return 1; }
bool check_type(enum_var_type type) { return type != var_type; }
bool check_update_type(Item_result type) { return 1; }
byte *value_ptr(THD *thd, enum_var_type type)
{
return (*value_ptr_func)(thd);
}
SHOW_TYPE type() { return show_type; }
};
/****************************************************************************
Classes for parsing of the SET command
****************************************************************************/
@ -388,7 +414,8 @@ public:
if (value_arg && value_arg->type() == Item::FIELD_ITEM)
{
Item_field *item= (Item_field*) value_arg;
if (!(value=new Item_string(item->field_name, strlen(item->field_name))))
if (!(value=new Item_string(item->field_name, strlen(item->field_name),
system_charset_info)))
value=value_arg; /* Give error message later */
}
else

View file

@ -206,7 +206,7 @@
"Nezn-Bámá systémová promìnná '%-.64s'",
"Tabulka '%-.64s' je ozna-Bèena jako poru¹ená a mìla by být opravena",
"Tabulka '%-.64s' je ozna-Bèena jako poru¹ená a poslední (automatická?) oprava se nezdaøila",
"Warning: Some non-transactional changed tables couldn't be rolled back",
"Some non-transactional changed tables couldn't be rolled back",
"Multi-statement transaction required more than 'max_binlog_cache_size' bytes of storage. Increase this mysqld variable and try again',
"This operation cannot be performed with a running slave, run SLAVE STOP first",
"This operation requires a running slave, configure slave and do SLAVE START",

View file

@ -197,7 +197,7 @@
"Unknown system variable '%-.64s'",
"Table '%-.64s' is marked as crashed and should be repaired",
"Table '%-.64s' is marked as crashed and last (automatic?) repair failed",
"Warning: Some non-transactional changed tables couldn't be rolled back",
"Some non-transactional changed tables couldn't be rolled back",
"Multi-statement transaction required more than 'max_binlog_cache_size' bytes of storage. Increase this mysqld variable and try again',
"This operation cannot be performed with a running slave, run SLAVE STOP first",
"This operation requires a running slave, configure slave and do SLAVE START",
@ -242,3 +242,4 @@
"Key reference and table reference doesn't match",
"Subselect return more than 1 field",
"Subselect return more than 1 record",
"Unknown prepared statement handler (%ld) given to %s",

View file

@ -197,7 +197,7 @@
"Unknown system variable '%-.64s'",
"Table '%-.64s' is marked as crashed and should be repaired",
"Table '%-.64s' is marked as crashed and last (automatic?) repair failed",
"Warning: Some non-transactional changed tables couldn't be rolled back",
"Some non-transactional changed tables couldn't be rolled back",
"Multi-statement transaction required more than 'max_binlog_cache_size' bytes of storage. Increase this mysqld variable and try again',
"This operation cannot be performed with a running slave, run SLAVE STOP first",
"This operation requires a running slave, configure slave and do SLAVE START",

View file

@ -199,7 +199,7 @@
"Unknown system variable '%-.64s'",
"Table '%-.64s' is marked as crashed and should be repaired",
"Table '%-.64s' is marked as crashed and last (automatic?) repair failed",
"Warning: Some non-transactional changed tables couldn't be rolled back",
"Some non-transactional changed tables couldn't be rolled back",
"Multi-statement transaction required more than 'max_binlog_cache_size' bytes of storage. Increase this mysqld variable and try again',
"This operation cannot be performed with a running slave, run SLAVE STOP first",
"This operation requires a running slave, configure slave and do SLAVE START",

View file

@ -199,7 +199,7 @@
"Unknown system variable '%-.64s'",
"Table '%-.64s' is marked as crashed and should be repaired",
"Table '%-.64s' is marked as crashed and last (automatic?) repair failed",
"Warning: Some non-transactional changed tables couldn't be rolled back",
"Some non-transactional changed tables couldn't be rolled back",
"Multi-statement transaction required more than 'max_binlog_cache_size' bytes of storage. Increase this mysqld variable and try again',
"This operation cannot be performed with a running slave, run SLAVE STOP first",
"This operation requires a running slave, configure slave and do SLAVE START",

View file

@ -197,7 +197,7 @@
"Unknown system variable '%-.64s'",
"Table '%-.64s' is marked as crashed and should be repaired",
"Table '%-.64s' is marked as crashed and last (automatic?) repair failed",
"Warning: Some non-transactional changed tables couldn't be rolled back",
"Some non-transactional changed tables couldn't be rolled back",
"Multi-statement transaction required more than 'max_binlog_cache_size' bytes of storage. Increase this mysqld variable and try again',
"This operation cannot be performed with a running slave, run SLAVE STOP first",
"This operation requires a running slave, configure slave and do SLAVE START",

View file

@ -199,7 +199,7 @@
"Unknown system variable '%-.64s'",
"Table '%-.64s' is marked as crashed and should be repaired",
"Table '%-.64s' is marked as crashed and last (automatic?) repair failed",
"Warning: Some non-transactional changed tables couldn't be rolled back",
"Some non-transactional changed tables couldn't be rolled back",
"Multi-statement transaction required more than 'max_binlog_cache_size' bytes of storage. Increase this mysqld variable and try again',
"This operation cannot be performed with a running slave, run SLAVE STOP first",
"This operation requires a running slave, configure slave and do SLAVE START",

View file

@ -199,7 +199,7 @@
"Unknown system variable '%-.64s'",
"Table '%-.64s' is marked as crashed and should be repaired",
"Table '%-.64s' is marked as crashed and last (automatic?) repair failed",
"Warning: Some non-transactional changed tables couldn't be rolled back",
"Some non-transactional changed tables couldn't be rolled back",
"Multi-statement transaction required more than 'max_binlog_cache_size' bytes of storage. Increase this mysqld variable and try again',
"This operation cannot be performed with a running slave, run SLAVE STOP first",
"This operation requires a running slave, configure slave and do SLAVE START",

View file

@ -201,7 +201,7 @@
"Unknown system variable '%-.64s'",
"Table '%-.64s' is marked as crashed and should be repaired",
"Table '%-.64s' is marked as crashed and last (automatic?) repair failed",
"Warning: Some non-transactional changed tables couldn't be rolled back",
"Some non-transactional changed tables couldn't be rolled back",
"Multi-statement transaction required more than 'max_binlog_cache_size' bytes of storage. Increase this mysqld variable and try again',
"This operation cannot be performed with a running slave, run SLAVE STOP first",
"This operation requires a running slave, configure slave and do SLAVE START",

View file

@ -201,7 +201,7 @@
"Unknown system variable '%-.64s'",
"Table '%-.64s' is marked as crashed and should be repaired",
"Table '%-.64s' is marked as crashed and last (automatic?) repair failed",
"Warning: Some non-transactional changed tables couldn't be rolled back",
"Some non-transactional changed tables couldn't be rolled back",
"Multi-statement transaction required more than 'max_binlog_cache_size' bytes of storage. Increase this mysqld variable and try again',
"This operation cannot be performed with a running slave, run SLAVE STOP first",
"This operation requires a running slave, configure slave and do SLAVE START",

View file

@ -205,7 +205,7 @@
"Unknown system variable '%-.64s'",
"Table '%-.64s' is marked as crashed and should be repaired",
"Table '%-.64s' is marked as crashed and last (automatic?) repair failed",
"Warning: Some non-transactional changed tables couldn't be rolled back",
"Some non-transactional changed tables couldn't be rolled back",
"Multi-statement transaction required more than 'max_binlog_cache_size' bytes of storage. Increase this mysqld variable and try again',
"This operation cannot be performed with a running slave, run SLAVE STOP first",
"This operation requires a running slave, configure slave and do SLAVE START",

View file

@ -197,7 +197,7 @@
"Okänd system variabel '%-.64s'",
"Tabell '%-.64s' är crashad och bör repareras med REPAIR TABLE",
"Tabell '%-.64s' är crashad och senast (automatiska?) reparation misslyckades",
"Warning: Några icke transaktionella tabeller kunde inte återställas vid ROLLBACK",
"Några icke transaktionella tabeller kunde inte återställas vid ROLLBACK",
"Transaktionen krävde mera än 'max_binlog_cache_size' minne. Utöka denna mysqld variabel och försök på nytt",
"Denna operation kan inte göras under replikering; Gör SLAVE STOP först",
"Denna operation kan endast göras under replikering; Konfigurera slaven och gör SLAVE START",

View file

@ -56,7 +56,6 @@ static int events_till_disconnect = -1;
typedef enum { SLAVE_THD_IO, SLAVE_THD_SQL} SLAVE_THD_TYPE;
void skip_load_data_infile(NET* net);
static int process_io_rotate(MASTER_INFO* mi, Rotate_log_event* rev);
static int process_io_create_file(MASTER_INFO* mi, Create_file_log_event* cev);
static bool wait_for_relay_log_space(RELAY_LOG_INFO* rli);
@ -723,13 +722,22 @@ void slave_print_error(RELAY_LOG_INFO* rli, int err_code, const char* msg, ...)
rli->last_slave_errno = err_code;
}
/*
This is used to tell a 3.23 master to break send_file()
*/
void skip_load_data_infile(NET* net)
void skip_load_data_infile(NET *net)
{
(void)my_net_write(net, "\xfb/dev/null", 10);
(void)net_flush(net);
(void)my_net_read(net); // discard response
send_ok(net); // the master expects it
(void)net_request_file(net, "/dev/null");
(void)my_net_read(net); // discard response
(void)net_write_command(net, 0, "", 0, "", 0); // Send ok
}
bool net_request_file(NET* net, const char* fname)
{
DBUG_ENTER("net_request_file");
DBUG_RETURN(net_write_command(net, 251, fname, strlen(fname), "", 0));
}
@ -875,13 +883,13 @@ static int create_table_from_dump(THD* thd, NET* net, const char* db,
if (packet_len == packet_error)
{
send_error(&thd->net, ER_MASTER_NET_READ);
send_error(thd, ER_MASTER_NET_READ);
return 1;
}
if (net->read_pos[0] == 255) // error from master
{
net->read_pos[packet_len] = 0;
net_printf(&thd->net, ER_MASTER, net->read_pos + 3);
net_printf(thd, ER_MASTER, net->read_pos + 3);
return 1;
}
thd->command = COM_TABLE_DUMP;
@ -889,7 +897,7 @@ static int create_table_from_dump(THD* thd, NET* net, const char* db,
if (!thd->query)
{
sql_print_error("create_table_from_dump: out of memory");
net_printf(&thd->net, ER_GET_ERRNO, "Out of memory");
net_printf(thd, ER_GET_ERRNO, "Out of memory");
return 1;
}
memcpy(thd->query, net->read_pos, packet_len);
@ -919,7 +927,7 @@ static int create_table_from_dump(THD* thd, NET* net, const char* db,
thd->proc_info = "Opening master dump table";
if (!open_ltable(thd, &tables, TL_WRITE))
{
send_error(&thd->net,0,0); // Send error from open_ltable
send_error(thd,0,0); // Send error from open_ltable
sql_print_error("create_table_from_dump: could not open created table");
goto err;
}
@ -928,7 +936,7 @@ static int create_table_from_dump(THD* thd, NET* net, const char* db,
thd->proc_info = "Reading master dump table data";
if (file->net_read_dump(net))
{
net_printf(&thd->net, ER_MASTER_NET_READ);
net_printf(thd, ER_MASTER_NET_READ);
sql_print_error("create_table_from_dump::failed in\
handler::net_read_dump()");
goto err;
@ -947,7 +955,7 @@ static int create_table_from_dump(THD* thd, NET* net, const char* db,
error=file->repair(thd,&check_opt) != 0;
thd->net.vio = save_vio;
if (error)
net_printf(&thd->net, ER_INDEX_REBUILD,tables.table->real_name);
net_printf(thd, ER_INDEX_REBUILD,tables.table->real_name);
err:
close_thread_tables(thd);
@ -969,12 +977,12 @@ int fetch_master_table(THD *thd, const char *db_name, const char *table_name,
{
if (!(mysql = mc_mysql_init(NULL)))
{
send_error(&thd->net); // EOM
send_error(thd); // EOM
DBUG_RETURN(1);
}
if (connect_to_master(thd, mysql, mi))
{
net_printf(&thd->net, ER_CONNECT_TO_MASTER, mc_mysql_error(mysql));
net_printf(thd, ER_CONNECT_TO_MASTER, mc_mysql_error(mysql));
mc_mysql_close(mysql);
DBUG_RETURN(1);
}
@ -998,7 +1006,7 @@ int fetch_master_table(THD *thd, const char *db_name, const char *table_name,
if (!called_connected)
mc_mysql_close(mysql);
if (errmsg && thd->net.vio)
send_error(&thd->net, error, errmsg);
send_error(thd, error, errmsg);
DBUG_RETURN(test(error)); // Return 1 on error
}
@ -1440,7 +1448,7 @@ int show_master_info(THD* thd, MASTER_INFO* mi)
if (my_net_write(&thd->net, (char*)thd->packet.ptr(), packet->length()))
DBUG_RETURN(-1);
}
send_eof(&thd->net);
send_eof(thd);
DBUG_RETURN(0);
}
@ -2222,8 +2230,8 @@ static int process_io_create_file(MASTER_INFO* mi, Create_file_log_event* cev)
int error = 1;
ulong num_bytes;
bool cev_not_written;
THD* thd;
NET* net = &mi->mysql->net;
THD *thd = mi->io_thd;
NET *net = &mi->mysql->net;
DBUG_ENTER("process_io_create_file");
if (unlikely(!cev->is_valid()))
@ -2237,7 +2245,6 @@ static int process_io_create_file(MASTER_INFO* mi, Create_file_log_event* cev)
DBUG_RETURN(0);
}
DBUG_ASSERT(cev->inited_from_old);
thd = mi->io_thd;
thd->file_id = cev->file_id = mi->file_id++;
thd->server_id = cev->server_id;
cev_not_written = 1;
@ -2266,7 +2273,7 @@ static int process_io_create_file(MASTER_INFO* mi, Create_file_log_event* cev)
}
if (unlikely(!num_bytes)) /* eof */
{
send_ok(net); /* 3.23 master wants it */
net_write_command(net, 0, "", 0, "", 0);/* 3.23 master wants it */
Execute_load_log_event xev(thd);
xev.log_pos = mi->master_log_pos;
if (unlikely(mi->rli.relay_log.append(&xev)))

View file

@ -1,8 +1,22 @@
/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
#ifndef _spatial_h
#define _spatial_h
#include "gstream.h"
const uint POINT_DATA_SIZE = 8+8;
const uint WKB_HEADER_SIZE = 1+4;
@ -30,7 +44,8 @@ struct MBR
ymax=-DBL_MAX;
}
MBR(const double &_xmin, const double &_ymin, const double &_xmax, const double &_ymax)
MBR(const double &_xmin, const double &_ymin,
const double &_xmax, const double &_ymax)
{
xmin=_xmin;
ymin=_ymin;
@ -52,7 +67,8 @@ struct MBR
double ymax;
void add_xy(double x, double y)
{ /* Not using "else" for proper one point MBR calculation */
{
/* Not using "else" for proper one point MBR calculation */
if (x<xmin)
{
xmin=x;
@ -72,10 +88,11 @@ struct MBR
}
void add_xy(const char *px, const char *py)
{ /* Not using "else" for proper one point MBR calculation */
{
double x, y;
float8get(x, px);
float8get(y, py);
/* Not using "else" for proper one point MBR calculation */
if (x<xmin)
{
xmin=x;
@ -116,12 +133,14 @@ struct MBR
int equals(const MBR *mbr)
{
return (mbr->xmin==xmin)&&(mbr->ymin==ymin)&&(mbr->xmax==xmax)&&(mbr->ymax==ymax);
return ((mbr->xmin == xmin) && (mbr->ymin == ymin) &&
(mbr->xmax == xmax) && (mbr->ymax == ymax));
}
int disjoint(const MBR *mbr)
{
return (mbr->xmin>xmax)||(mbr->ymin>ymax)||(mbr->xmax<xmin)||(mbr->ymax<ymin);
return ((mbr->xmin > xmax) || (mbr->ymin > ymax) ||
(mbr->xmax < xmin) || (mbr->ymax < ymin));
}
int intersects(const MBR *mbr)
@ -131,24 +150,24 @@ struct MBR
int touches(const MBR *mbr)
{
return (((mbr->xmin==xmax) || (mbr->xmax==xmin)) &&
((mbr->ymin>=ymin) && (mbr->ymin<=ymax) ||
(mbr->ymax>=ymin) && (mbr->ymax<=ymax))) ||
(((mbr->ymin==ymax) || (mbr->ymax==ymin)) &&
((mbr->xmin>=xmin) && (mbr->xmin<=xmax) ||
(mbr->xmax>=xmin)&&(mbr->xmax<=xmax)));
return ((((mbr->xmin == xmax) || (mbr->xmax == xmin)) &&
((mbr->ymin >= ymin) && (mbr->ymin <= ymax) ||
(mbr->ymax >= ymin) && (mbr->ymax <= ymax))) ||
(((mbr->ymin == ymax) || (mbr->ymax == ymin)) &&
((mbr->xmin >= xmin) && (mbr->xmin <= xmax) ||
(mbr->xmax >= xmin) && (mbr->xmax <= xmax))));
}
int within(const MBR *mbr)
{
return (mbr->xmin<=xmin) && (mbr->ymin<=ymin) &&
(mbr->xmax>=xmax) && (mbr->ymax>=ymax);
return ((mbr->xmin <= xmin) && (mbr->ymin <= ymin) &&
(mbr->xmax >= xmax) && (mbr->ymax >= ymax));
}
int contains(const MBR *mbr)
{
return (mbr->xmin>=xmin) && (mbr->ymin>=ymin) &&
(mbr->xmax<=xmax) && (mbr->ymax<=ymax);
return ((mbr->xmin >= xmin) && (mbr->ymin >= ymin) &&
(mbr->xmax <= xmax) && (mbr->ymax <= ymax));
}
bool inner_point(double x, double y) const
@ -245,45 +264,46 @@ public:
size_t get_data_size() const { return (this->*m_vmt->get_data_size)(); }
int init_from_text(GTextReadStream *trs, String *wkb)
{ return (this->*m_vmt->init_from_text)(trs, wkb); }
{ return (this->*m_vmt->init_from_text)(trs, wkb); }
int get_data_as_text(String *txt) const
{ return (this->*m_vmt->get_data_as_text)(txt); }
{ return (this->*m_vmt->get_data_as_text)(txt); }
int get_mbr(MBR *mbr) const { return (this->*m_vmt->get_mbr)(mbr); }
int dimension(uint32 *dim) const
{ return (this->*m_vmt->dimension)(dim); }
{ return (this->*m_vmt->dimension)(dim); }
int get_x(double *x) const { return (this->*m_vmt->get_x)(x); }
int get_y(double *y) const { return (this->*m_vmt->get_y)(y); }
int length(double *len) const { return (this->*m_vmt->length)(len); }
int area(double *ar) const { return (this->*m_vmt->area)(ar); }
int is_closed(int *closed) const { return (this->*m_vmt->is_closed)(closed); }
int is_closed(int *closed) const
{ return (this->*m_vmt->is_closed)(closed); }
int num_interior_ring(uint32 *n_int_rings) const
{ return (this->*m_vmt->num_interior_ring)(n_int_rings); }
{ return (this->*m_vmt->num_interior_ring)(n_int_rings); }
int num_points(uint32 *n_points) const
{ return (this->*m_vmt->num_points)(n_points); }
{ return (this->*m_vmt->num_points)(n_points); }
int num_geometries(uint32 *num) const
{ return (this->*m_vmt->num_geometries)(num); }
{ return (this->*m_vmt->num_geometries)(num); }
int start_point(String *point) const
{ return (this->*m_vmt->start_point)(point); }
{ return (this->*m_vmt->start_point)(point); }
int end_point(String *point) const
{ return (this->*m_vmt->end_point)(point); }
{ return (this->*m_vmt->end_point)(point); }
int exterior_ring(String *ring) const
{ return (this->*m_vmt->exterior_ring)(ring); }
{ return (this->*m_vmt->exterior_ring)(ring); }
int centroid(String *point) const
{ return (this->*m_vmt->centroid)(point); }
{ return (this->*m_vmt->centroid)(point); }
int point_n(uint32 num, String *result) const
{ return (this->*m_vmt->point_n)(num, result); }
{ return (this->*m_vmt->point_n)(num, result); }
int interior_ring_n(uint32 num, String *result) const
{ return (this->*m_vmt->interior_ring_n)(num, result); }
{ return (this->*m_vmt->interior_ring_n)(num, result); }
int geometry_n(uint32 num, String *result) const
{ return (this->*m_vmt->geometry_n)(num, result); }
{ return (this->*m_vmt->geometry_n)(num, result); }
public:
int create_from_wkb(const char *data, uint32 data_len);
@ -301,11 +321,11 @@ public:
int as_wkt(String *wkt) const
{
if(wkt->reserve(strlen(get_class_info()->m_name) + 2, 512))
if (wkt->reserve(strlen(get_class_info()->m_name) + 2, 512))
return 1;
wkt->qs_append(get_class_info()->m_name);
wkt->qs_append('(');
if(get_data_as_text(wkt))
if (get_data_as_text(wkt))
return 1;
wkt->qs_append(')');
return 0;
@ -330,35 +350,37 @@ protected:
bool no_data(const char *cur_data, uint32 data_amount) const
{
return cur_data + data_amount > m_data_end;
return (cur_data + data_amount > m_data_end);
}
const char *m_data;
const char *m_data_end;
};
#define SIZEOF_STORED_DOUBLE 8
/***************************** Point *******************************/
class GPoint: public Geometry
{
public:
size_t get_data_size() const;
int init_from_text(GTextReadStream *trs, String *wkb);
int get_data_as_text(String *txt) const;
int get_mbr(MBR *mbr) const;
size_t get_data_size() const;
int init_from_text(GTextReadStream *trs, String *wkb);
int get_data_as_text(String *txt) const;
int get_mbr(MBR *mbr) const;
int get_xy(double *x, double *y) const
{
const char *data = m_data;
if(no_data(data, sizeof(double)) * 2) return 1;
if (no_data(data, SIZEOF_STORED_DOUBLE * 2)) return 1;
float8get(*x, data);
float8get(*y, data + sizeof(double));
float8get(*y, data + SIZEOF_STORED_DOUBLE);
return 0;
}
int get_x(double *x) const
{
if(no_data(m_data, sizeof(double))) return 1;
if (no_data(m_data, SIZEOF_STORED_DOUBLE)) return 1;
float8get(*x, m_data);
return 0;
}
@ -366,8 +388,8 @@ public:
int get_y(double *y) const
{
const char *data = m_data;
if(no_data(data, sizeof(double)) * 2) return 1;
float8get(*y, data + sizeof(double));
if (no_data(data, SIZEOF_STORED_DOUBLE * 2)) return 1;
float8get(*y, data + SIZEOF_STORED_DOUBLE);
return 0;
}
@ -399,10 +421,10 @@ public:
class GPolygon: public Geometry
{
public:
size_t get_data_size() const;
int init_from_text(GTextReadStream *trs, String *wkb);
int get_data_as_text(String *txt) const;
int get_mbr(MBR *mbr) const;
size_t get_data_size() const;
int init_from_text(GTextReadStream *trs, String *wkb);
int get_data_as_text(String *txt) const;
int get_mbr(MBR *mbr) const;
int area(double *ar) const;
int exterior_ring(String *result) const;
@ -431,10 +453,10 @@ public:
class GMultiLineString: public Geometry
{
public:
size_t get_data_size() const;
int init_from_text(GTextReadStream *trs, String *wkb);
int get_data_as_text(String *txt) const;
int get_mbr(MBR *mbr) const;
size_t get_data_size() const;
int init_from_text(GTextReadStream *trs, String *wkb);
int get_data_as_text(String *txt) const;
int get_mbr(MBR *mbr) const;
int length(double *len) const;
int is_closed(int *closed) const;
@ -446,10 +468,10 @@ public:
class GMultiPolygon: public Geometry
{
public:
size_t get_data_size() const;
int init_from_text(GTextReadStream *trs, String *wkb);
int get_data_as_text(String *txt) const;
int get_mbr(MBR *mbr) const;
size_t get_data_size() const;
int init_from_text(GTextReadStream *trs, String *wkb);
int get_data_as_text(String *txt) const;
int get_mbr(MBR *mbr) const;
int area(double *ar) const;
int centroid(String *result) const;
@ -462,14 +484,13 @@ public:
class GGeometryCollection: public Geometry
{
public:
size_t get_data_size() const;
int init_from_text(GTextReadStream *trs, String *wkb);
int get_data_as_text(String *txt) const;
int get_mbr(MBR *mbr) const;
size_t get_data_size() const;
int init_from_text(GTextReadStream *trs, String *wkb);
int get_data_as_text(String *txt) const;
int get_mbr(MBR *mbr) const;
int num_geometries(uint32 *num) const;
int geometry_n(uint32 num, String *result) const;
int dimension(uint32 *dim) const;
};

View file

@ -997,7 +997,7 @@ bool check_change_password(THD *thd, const char *host, const char *user)
{
if (!initialized)
{
send_error(&thd->net, ER_PASSWORD_NOT_ALLOWED); /* purecov: inspected */
send_error(thd, ER_PASSWORD_NOT_ALLOWED); /* purecov: inspected */
return(1); /* purecov: inspected */
}
if (!thd->slave_thread &&
@ -1009,7 +1009,7 @@ bool check_change_password(THD *thd, const char *host, const char *user)
}
if (!thd->slave_thread && !thd->user[0])
{
send_error(&thd->net, ER_PASSWORD_ANONYMOUS_USER);
send_error(thd, ER_PASSWORD_ANONYMOUS_USER);
return(1);
}
return(0);
@ -1036,7 +1036,7 @@ bool change_password(THD *thd, const char *host, const char *user,
ACL_USER *acl_user;
if (!(acl_user= find_acl_user(host,user)))
{
send_error(&thd->net, ER_PASSWORD_NO_MATCH);
send_error(thd, ER_PASSWORD_NO_MATCH);
VOID(pthread_mutex_unlock(&acl_cache->lock));
DBUG_RETURN(1);
}
@ -1046,7 +1046,7 @@ bool change_password(THD *thd, const char *host, const char *user,
new_password))
{
VOID(pthread_mutex_unlock(&acl_cache->lock)); /* purecov: deadcode */
send_error(&thd->net,0); /* purecov: deadcode */
send_error(thd,0); /* purecov: deadcode */
DBUG_RETURN(1); /* purecov: deadcode */
}
get_salt_from_password(acl_user->salt,new_password);
@ -1960,7 +1960,7 @@ int mysql_table_grant (THD *thd, TABLE_LIST *table_list,
if (!initialized)
{
send_error(&(thd->net), ER_UNKNOWN_COM_ERROR); /* purecov: inspected */
send_error(thd, ER_UNKNOWN_COM_ERROR); /* purecov: inspected */
return 1; /* purecov: inspected */
}
if (rights & ~TABLE_ACLS)
@ -2026,7 +2026,7 @@ int mysql_table_grant (THD *thd, TABLE_LIST *table_list,
if (!revoke_grant)
create_new_users= test_if_create_new_users(thd);
int result=0;
pthread_mutex_lock(&LOCK_grant);
rw_wrlock(&LOCK_grant);
MEM_ROOT *old_root=my_pthread_getspecific_ptr(MEM_ROOT*,THR_MALLOC);
my_pthread_setspecific_ptr(THR_MALLOC,&memex);
@ -2135,9 +2135,9 @@ int mysql_table_grant (THD *thd, TABLE_LIST *table_list,
}
grant_option=TRUE;
my_pthread_setspecific_ptr(THR_MALLOC,old_root);
pthread_mutex_unlock(&LOCK_grant);
rw_unlock(&LOCK_grant);
if (!result)
send_ok(&thd->net);
send_ok(thd);
/* Tables are automatically closed */
DBUG_RETURN(result);
}
@ -2155,8 +2155,8 @@ int mysql_grant (THD *thd, const char *db, List <LEX_USER> &list,
if (!initialized)
{
send_error(&(thd->net), ER_UNKNOWN_COM_ERROR); /* purecov: tested */
return 1; /* purecov: tested */
send_error(thd, ER_UNKNOWN_COM_ERROR); /* purecov: tested */
return 1; /* purecov: tested */
}
if (lower_case_table_names && db)
@ -2185,7 +2185,7 @@ int mysql_grant (THD *thd, const char *db, List <LEX_USER> &list,
create_new_users= test_if_create_new_users(thd);
// go through users in user_list
pthread_mutex_lock(&LOCK_grant);
rw_wrlock(&LOCK_grant);
VOID(pthread_mutex_lock(&acl_cache->lock));
grant_version++;
@ -2218,11 +2218,11 @@ int mysql_grant (THD *thd, const char *db, List <LEX_USER> &list,
}
}
VOID(pthread_mutex_unlock(&acl_cache->lock));
pthread_mutex_unlock(&LOCK_grant);
rw_unlock(&LOCK_grant);
close_thread_tables(thd);
if (!result)
send_ok(&thd->net);
send_ok(thd);
DBUG_RETURN(result);
}
@ -2341,7 +2341,7 @@ void grant_reload(void)
// Locked tables are checked by acl_init and doesn't have to be checked here
pthread_mutex_lock(&LOCK_grant);
rw_wrlock(&LOCK_grant);
grant_version++;
old_hash_tables=hash_tables;
old_grant_option = grant_option;
@ -2359,7 +2359,7 @@ void grant_reload(void)
hash_free(&old_hash_tables);
free_root(&old_mem,MYF(0));
}
pthread_mutex_unlock(&LOCK_grant);
rw_unlock(&LOCK_grant);
DBUG_VOID_RETURN;
}
@ -2379,7 +2379,7 @@ bool check_grant(THD *thd, ulong want_access, TABLE_LIST *tables,
if (!want_access)
return 0; // ok
pthread_mutex_lock(&LOCK_grant);
rw_rdlock(&LOCK_grant);
for (table=tables; table ;table=table->next)
{
if (!(~table->grant.privilege & want_access))
@ -2413,11 +2413,11 @@ bool check_grant(THD *thd, ulong want_access, TABLE_LIST *tables,
goto err; // impossible
}
}
pthread_mutex_unlock(&LOCK_grant);
rw_unlock(&LOCK_grant);
return 0;
err:
pthread_mutex_unlock(&LOCK_grant);
rw_unlock(&LOCK_grant);
if (!no_errors) // Not a silent skip of table
{
const char *command="";
@ -2439,7 +2439,7 @@ bool check_grant(THD *thd, ulong want_access, TABLE_LIST *tables,
command = "index";
else if (want_access & GRANT_ACL)
command = "grant";
net_printf(&thd->net,ER_TABLEACCESS_DENIED_ERROR,
net_printf(thd,ER_TABLEACCESS_DENIED_ERROR,
command,
thd->priv_user,
thd->host_or_ip,
@ -2459,7 +2459,7 @@ bool check_grant_column (THD *thd,TABLE *table, const char *name,
if (!want_access)
return 0; // Already checked
pthread_mutex_lock(&LOCK_grant);
rw_rdlock(&LOCK_grant);
// reload table if someone has modified any grants
@ -2477,20 +2477,20 @@ bool check_grant_column (THD *thd,TABLE *table, const char *name,
grant_column=column_hash_search(grant_table, name, length);
if (grant_column && !(~grant_column->rights & want_access))
{
pthread_mutex_unlock(&LOCK_grant);
rw_unlock(&LOCK_grant);
return 0;
}
#ifdef NOT_USED
if (show_tables && (grant_column || table->grant.privilege & COL_ACLS))
{
pthread_mutex_unlock(&LOCK_grant); /* purecov: deadcode */
rw_unlock(&LOCK_grant); /* purecov: deadcode */
return 0; /* purecov: deadcode */
}
#endif
/* We must use my_printf_error() here! */
err:
pthread_mutex_unlock(&LOCK_grant);
rw_unlock(&LOCK_grant);
if (!show_tables)
{
char command[128];
@ -2518,7 +2518,7 @@ bool check_grant_all_columns(THD *thd, ulong want_access, TABLE *table)
if (!want_access)
return 0; // Already checked
pthread_mutex_lock(&LOCK_grant);
rw_rdlock(&LOCK_grant);
// reload table if someone has modified any grants
@ -2541,12 +2541,12 @@ bool check_grant_all_columns(THD *thd, ulong want_access, TABLE *table)
if (!grant_column || (~grant_column->rights & want_access))
goto err;
}
pthread_mutex_unlock(&LOCK_grant);
rw_unlock(&LOCK_grant);
return 0;
/* We must use my_printf_error() here! */
err:
pthread_mutex_unlock(&LOCK_grant);
rw_unlock(&LOCK_grant);
const char *command="";
if (want_access & SELECT_ACL)
@ -2578,7 +2578,7 @@ bool check_grant_db(THD *thd,const char *db)
bool error=1;
len = (uint) (strmov(strmov(helping,thd->priv_user)+1,db)-helping)+ 1;
pthread_mutex_lock(&LOCK_grant);
rw_rdlock(&LOCK_grant);
for (uint idx=0 ; idx < hash_tables.records ; idx++)
{
@ -2594,7 +2594,7 @@ bool check_grant_db(THD *thd,const char *db)
break;
}
}
pthread_mutex_unlock(&LOCK_grant);
rw_unlock(&LOCK_grant);
return error;
}
@ -2608,14 +2608,14 @@ ulong get_table_grant(THD *thd, TABLE_LIST *table)
const char *db = table->db ? table->db : thd->db;
GRANT_TABLE *grant_table;
pthread_mutex_lock(&LOCK_grant);
rw_rdlock(&LOCK_grant);
grant_table = table_hash_search(thd->host,thd->ip,db,user,
table->real_name,0);
table->grant.grant_table=grant_table; // Remember for column test
table->grant.version=grant_version;
if (grant_table)
table->grant.privilege|= grant_table->privs;
pthread_mutex_unlock(&LOCK_grant);
rw_unlock(&LOCK_grant);
return table->grant.privilege;
}
@ -2626,7 +2626,7 @@ ulong get_column_grant(THD *thd, TABLE_LIST *table, Field *field)
GRANT_COLUMN *grant_column;
ulong priv;
pthread_mutex_lock(&LOCK_grant);
rw_rdlock(&LOCK_grant);
// reload table if someone has modified any grants
if (table->grant.version != grant_version)
{
@ -2648,7 +2648,7 @@ ulong get_column_grant(THD *thd, TABLE_LIST *table, Field *field)
else
priv=table->grant.privilege | grant_column->rights;
}
pthread_mutex_unlock(&LOCK_grant);
rw_unlock(&LOCK_grant);
return priv;
}
@ -2683,7 +2683,7 @@ int mysql_show_grants(THD *thd,LEX_USER *lex_user)
LINT_INIT(acl_user);
if (!initialized)
{
send_error(&(thd->net), ER_UNKNOWN_COM_ERROR);
send_error(thd, ER_UNKNOWN_COM_ERROR);
DBUG_RETURN(-1);
}
if (!lex_user->host.str)
@ -2990,7 +2990,7 @@ int mysql_show_grants(THD *thd,LEX_USER *lex_user)
}
end:
VOID(pthread_mutex_unlock(&acl_cache->lock));
send_eof(&thd->net);
send_eof(thd);
DBUG_RETURN(error);
}

View file

@ -89,21 +89,21 @@ proc_analyse_init(THD *thd, ORDER *param, select_result *result,
if ((*param->item)->type() != Item::INT_ITEM ||
(*param->item)->val() < 0)
{
net_printf(&thd->net, ER_WRONG_PARAMETERS_TO_PROCEDURE, proc_name);
net_printf(thd, ER_WRONG_PARAMETERS_TO_PROCEDURE, proc_name);
DBUG_RETURN(0);
}
pc->max_tree_elements = (uint) (*param->item)->val_int();
param = param->next;
if (param->next) // no third parameter possible
{
net_printf(&thd->net, ER_WRONG_PARAMCOUNT_TO_PROCEDURE, proc_name);
net_printf(thd, ER_WRONG_PARAMCOUNT_TO_PROCEDURE, proc_name);
DBUG_RETURN(0);
}
// second parameter
if ((*param->item)->type() != Item::INT_ITEM ||
(*param->item)->val() < 0)
{
net_printf(&thd->net, ER_WRONG_PARAMETERS_TO_PROCEDURE, proc_name);
net_printf(thd, ER_WRONG_PARAMETERS_TO_PROCEDURE, proc_name);
DBUG_RETURN(0);
}
pc->max_treemem = (uint) (*param->item)->val_int();
@ -111,7 +111,7 @@ proc_analyse_init(THD *thd, ORDER *param, select_result *result,
else if ((*param->item)->type() != Item::INT_ITEM ||
(*param->item)->val() < 0)
{
net_printf(&thd->net, ER_WRONG_PARAMETERS_TO_PROCEDURE, proc_name);
net_printf(thd, ER_WRONG_PARAMETERS_TO_PROCEDURE, proc_name);
DBUG_RETURN(0);
}
// if only one parameter was given, it will be the value of max_tree_elements
@ -387,8 +387,7 @@ void field_real::add()
if ((decs = decimals()) == NOT_FIXED_DEC)
{
sprintf(buff, "%g", num);
length = (uint) strlen(buff);
length= my_sprintf(buff, (buff, "%g", num));
if (rint(num) != num)
max_notzero_dec_len = 1;
}
@ -397,11 +396,11 @@ void field_real::add()
#ifdef HAVE_SNPRINTF
buff[sizeof(buff)-1]=0; // Safety
snprintf(buff, sizeof(buff)-1, "%-.*f", (int) decs, num);
length = (uint) strlen(buff);
#else
sprintf(buff, "%-.*f", (int) decs, num);
length= my_sprintf(buff, (buff, "%-.*f", (int) decs, num));
#endif
length = (uint) strlen(buff);
// We never need to check further than this
end = buff + length - 1 - decs + max_notzero_dec_len;

View file

@ -224,7 +224,7 @@ send_convert_fields(THD *thd,List<Item> &list,CONVERT *convert,uint flag)
char buff[80];
String tmp((char*) buff,sizeof(buff),default_charset_info);
String *res,*packet= &thd->packet;
DBUG_ENTER("send_fields");
DBUG_ENTER("send_convert_fields");
while ((item=it++))
{
@ -286,10 +286,10 @@ send_convert_fields(THD *thd,List<Item> &list,CONVERT *convert,uint flag)
if (my_net_write(&thd->net, (char*) packet->ptr(),packet->length()))
break; /* purecov: inspected */
}
return 0;
DBUG_RETURN(0);
err:
return 1;
DBUG_RETURN(1);
}
@ -406,7 +406,8 @@ send_non_convert_fields(THD *thd,List<Item> &list,uint flag)
bool
send_fields(THD *thd, List<Item> &list, uint flag)
{
CONVERT *convert= (flag & 4) ? (CONVERT*) 0 : thd->convert_set;
char buff[9]; // Big enough for store_length
CONVERT *convert= (flag & 4) ? (CONVERT*) 0 : thd->variables.convert_set;
DBUG_ENTER("send_fields");
if (thd->fatal_error) // We have got an error
@ -414,7 +415,7 @@ send_fields(THD *thd, List<Item> &list, uint flag)
if (flag & 1)
{ // Packet with number of elements
char *pos=net_store_length(buff,(uint) list.elements);
char *pos=net_store_length(buff, (uint) list.elements);
(void) my_net_write(&thd->net, buff,(uint) (pos-buff));
}
@ -430,11 +431,11 @@ send_fields(THD *thd, List<Item> &list, uint flag)
else if (send_non_convert_fields(thd, list, flag))
goto err;
send_eof(&thd->net);
return 0;
send_eof(thd);
DBUG_RETURN(0);
err:
send_error(&thd->net,ER_OUT_OF_RESOURCES); /* purecov: inspected */
send_error(thd,ER_OUT_OF_RESOURCES); /* purecov: inspected */
DBUG_RETURN(1); /* purecov: inspected */
}

View file

@ -77,14 +77,15 @@ static void free_var(user_var_entry *entry)
** Thread specific functions
****************************************************************************/
THD::THD():user_time(0),fatal_error(0),last_insert_id_used(0),
THD::THD():user_time(0), fatal_error(0),
last_insert_id_used(0),
insert_id_used(0), in_lock_tables(0),
global_read_lock(0), bootstrap(0)
{
host=user=priv_user=db=query=ip=0;
host_or_ip="unknown ip";
locked=killed=count_cuted_fields=some_tables_deleted=no_errors=password=
query_start_used=safe_to_cache_query=0;
query_start_used=safe_to_cache_query=prepare_command=0;
pthread_mutex_lock(&LOCK_global_system_variables);
variables= global_system_variables;
pthread_mutex_unlock(&LOCK_global_system_variables);
@ -96,7 +97,7 @@ THD::THD():user_time(0),fatal_error(0),last_insert_id_used(0),
tmp_table=0;
lock=locked_tables=0;
used_tables=0;
cuted_fields=sent_row_count=0L;
cuted_fields= sent_row_count= current_stmt_id= 0L;
start_time=(time_t) 0;
current_linfo = 0;
slave_thread = 0;
@ -142,10 +143,21 @@ THD::THD():user_time(0),fatal_error(0),last_insert_id_used(0),
bzero((char*) &mem_root,sizeof(mem_root));
bzero((char*) &transaction.mem_root,sizeof(transaction.mem_root));
bzero((char*) &con_root,sizeof(con_root));
bzero((char*) &warn_root,sizeof(warn_root));
init_alloc_root(&warn_root, 1024, 0);
bzero((char*) warn_count, sizeof(warn_count));
warn_list.empty();
user_connect=(USER_CONN *)0;
hash_init(&user_vars, system_charset_info, USER_VARS_HASH_SIZE, 0, 0,
(hash_get_key) get_var_key,
(void (*)(void*)) free_var,0);
/* Prepared statements */
last_prepared_stmt= 0;
init_tree(&prepared_statements, 0, 0, sizeof(PREP_STMT),
(qsort_cmp2) compare_prep_stmt, 1,
(tree_element_free) free_prep_stmt, 0);
#ifdef USING_TRANSACTIONS
bzero((char*) &transaction,sizeof(transaction));
if (opt_using_transactions)
@ -222,7 +234,9 @@ THD::~THD()
safeFree(ip);
free_root(&mem_root,MYF(0));
free_root(&con_root,MYF(0));
free_root(&warn_root,MYF(0));
free_root(&transaction.mem_root,MYF(0));
delete_tree(&prepared_statements);
mysys_var=0; // Safety (shouldn't be needed)
pthread_mutex_destroy(&LOCK_delete);
#ifndef DBUG_OFF
@ -272,8 +286,7 @@ void THD::awake(bool prepare_to_die)
bool THD::store_globals()
{
return (my_pthread_setspecific_ptr(THR_THD, this) ||
my_pthread_setspecific_ptr(THR_MALLOC, &mem_root) ||
my_pthread_setspecific_ptr(THR_NET, &net));
my_pthread_setspecific_ptr(THR_MALLOC, &mem_root));
}
@ -424,7 +437,7 @@ bool select_send::send_eof()
{
mysql_unlock_tables(thd, thd->lock); thd->lock=0;
}
::send_eof(&thd->net);
::send_eof(thd);
return 0;
}
@ -649,7 +662,7 @@ err:
void select_export::send_error(uint errcode,const char *err)
{
::send_error(&thd->net,errcode,err);
::send_error(thd,errcode,err);
(void) end_io_cache(&cache);
(void) my_close(file,MYF(0));
file= -1;
@ -662,9 +675,9 @@ bool select_export::send_eof()
if (my_close(file,MYF(MY_WME)))
error=1;
if (error)
::send_error(&thd->net);
::send_error(thd);
else
::send_ok(&thd->net,row_count);
::send_ok(thd,row_count);
file= -1;
return error;
}
@ -761,7 +774,7 @@ err:
void select_dump::send_error(uint errcode,const char *err)
{
::send_error(&thd->net,errcode,err);
::send_error(thd,errcode,err);
(void) end_io_cache(&cache);
(void) my_close(file,MYF(0));
(void) my_delete(path,MYF(0)); // Delete file on error
@ -774,9 +787,9 @@ bool select_dump::send_eof()
if (my_close(file,MYF(MY_WME)))
error=1;
if (error)
::send_error(&thd->net);
::send_error(thd);
else
::send_ok(&thd->net,row_count);
::send_ok(thd,row_count);
file= -1;
return error;
}

View file

@ -292,31 +292,43 @@ public:
i_string_pair():key(0),val(0) { }
i_string_pair(char* key_arg, char* val_arg) : key(key_arg),val(val_arg) {}
};
#define MYSQL_DEFAULT_ERROR_COUNT 500
class mysql_st_error
class MYSQL_ERROR: public Sql_alloc
{
public:
uint code;
char msg[MYSQL_ERRMSG_SIZE+1];
char query[NAME_LEN+1];
enum enum_warning_level
{ WARN_LEVEL_NOTE, WARN_LEVEL_WARN, WARN_LEVEL_ERROR, WARN_LEVEL_END};
static void *operator new(size_t size)
uint code;
enum_warning_level level;
char *msg;
MYSQL_ERROR(uint code_arg, enum_warning_level level_arg,
const char *msg_arg)
:code(code_arg), level(level_arg)
{
return (void*)my_malloc((uint)size, MYF(MY_WME | MY_FAE));
}
static void operator delete(void* ptr_arg, size_t size)
{
my_free((gptr)ptr_arg, MYF(MY_WME|MY_ALLOW_ZERO_PTR));
}
mysql_st_error(uint ecode, const char *emsg, const char *equery)
{
code = ecode;
strmov(msg, emsg);
strnmov(query, equery ? equery : "", NAME_LEN);
msg=sql_strdup(msg_arg);
}
};
/* This is a struct as it's allocated in tree_insert */
typedef struct st_prep_stmt
{
THD *thd;
Item_param *param;
Item *free_list;
MEM_ROOT mem_root;
ulong stmt_id;
uint param_count;
uint last_errno;
char last_error[MYSQL_ERRMSG_SIZE];
bool error_in_prepare, long_data_used;
} PREP_STMT;
class delayed_insert;
#define THD_SENTRY_MAGIC 0xfeedd1ff
@ -332,27 +344,27 @@ struct system_variables
ulong join_buff_size;
ulong long_query_time;
ulong max_allowed_packet;
ulong max_heap_table_size;
ulong max_sort_length;
ulong max_join_size;
ulong max_tmp_tables;
ulong max_error_count;
ulong max_warning_count;
ulong max_heap_table_size;
ulong max_join_size;
ulong max_prep_stmt_count;
ulong max_sort_length;
ulong max_tmp_tables;
ulong myisam_sort_buff_size;
ulong net_buffer_length;
ulong net_interactive_timeout;
ulong net_read_timeout;
ulong net_retry_count;
ulong net_wait_timeout;
ulong net_write_timeout;
ulong net_retry_count;
ulong query_cache_type;
ulong read_buff_size;
ulong read_rnd_buff_size;
ulong select_limit;
ulong sortbuff_size;
ulong table_type;
ulong tmp_table_size;
ulong tx_isolation;
ulong table_type;
my_bool log_warnings;
my_bool low_priority_updates;
@ -372,7 +384,9 @@ public:
LEX lex; // parse tree descriptor
MEM_ROOT mem_root; // 1 command-life memory pool
MEM_ROOT con_root; // connection-life memory
MEM_ROOT warn_root; // For warnings and errors
HASH user_vars; // hash for user variables
TREE prepared_statements;
String packet; // dynamic buffer for network I/O
struct sockaddr_in remote; // client socket address
struct rand_struct rand; // used for authentication
@ -408,7 +422,6 @@ public:
ulong master_access; /* Global privileges from mysql.user */
ulong db_access; /* Privileges for current db */
/*
open_tables - list of regular tables in use by this thread
temporary_tables - list of temp tables in use by this thread
@ -417,9 +430,10 @@ public:
*/
TABLE *open_tables,*temporary_tables, *handler_tables;
// TODO: document the variables below
MYSQL_LOCK *lock; /* Current locks */
MYSQL_LOCK *locked_tables; /* Tables locked with LOCK */
ULL *ull;
MYSQL_LOCK *lock; /* Current locks */
MYSQL_LOCK *locked_tables; /* Tables locked with LOCK */
ULL *ull;
PREP_STMT *last_prepared_stmt;
#ifndef DBUG_OFF
uint dbug_sentry; // watch out for memory corruption
#endif
@ -466,8 +480,11 @@ public:
table_map used_tables;
USER_CONN *user_connect;
CHARSET_INFO *db_charset;
List <MYSQL_ERROR> warn_list;
uint warn_count[(uint) MYSQL_ERROR::WARN_LEVEL_END];
uint total_warn_count, old_total_warn_count;
ulong query_id, version, options, thread_id, col_access;
ulong param_count,current_param_number;
ulong current_stmt_id;
long dbug_thread_id;
pthread_t real_id;
uint current_tablenr,tmp_table,cond_count;
@ -480,16 +497,15 @@ public:
uint8 query_cache_type; // type of query cache processing
bool slave_thread;
bool set_query_id,locked,count_cuted_fields,some_tables_deleted;
bool no_errors, allow_sum_func, password, fatal_error;
bool no_errors, allow_sum_func, password;
bool fatal_error;
bool query_start_used,last_insert_id_used,insert_id_used;
bool system_thread,in_lock_tables,global_read_lock;
bool query_error, bootstrap, cleanup_done;
bool safe_to_cache_query;
bool volatile killed;
bool prepare_command;
Error<mysql_st_error> err_list;
Error<mysql_st_error> warn_list;
Item_param *current_param;
Item_param *params; // Pointer to array of params
/*
If we do a purge of binary logs, log index info of the threads
@ -638,7 +654,7 @@ public:
class JOIN;
void send_error(NET *net,uint sql_errno=0, const char *err=0);
void send_error(THD *thd, uint sql_errno=0, const char *err=0);
class select_result :public Sql_alloc {
protected:
@ -657,7 +673,7 @@ public:
virtual void initialize_tables (JOIN *join=0) {}
virtual void send_error(uint errcode,const char *err)
{
::send_error(&thd->net,errcode,err);
::send_error(thd,errcode,err);
}
virtual bool send_eof()=0;
virtual void abort() {}

View file

@ -25,112 +25,138 @@
#include <direct.h>
#endif
#define MY_DB_OPT_FILE ".db.opt"
#define MY_DB_OPT_FILE "db.opt"
const char *del_exts[]= {".frm", ".BAK", ".TMD",".opt", NullS};
static TYPELIB deletable_extentions=
{array_elements(del_exts)-1,"del_exts", del_exts};
const char *known_exts[]=
{".ISM",".ISD",".ISM",".MRG",".MYI",".MYD",".db",NullS};
static TYPELIB known_extentions=
{array_elements(known_exts)-1,"known_exts", known_exts};
static long mysql_rm_known_files(THD *thd, MY_DIR *dirp,
const char *db, const char *path,
uint level);
/*
Create database options file:
Currently databse default charset is only stored there.
Create database options file:
DESCRIPTION
Currently database default charset is only stored there.
RETURN VALUES
0 ok
1 Could not create file or write to it. Error sent through my_error()
*/
static int write_db_opt(THD *thd,const char *db,HA_CREATE_INFO *create,char *fn)
static bool write_db_opt(const char *path, HA_CREATE_INFO *create)
{
register File file;
char buf[256]; // Should be enough
int error=0;
char buf[256]; // Should be enough for one option
bool error=1;
if ((file=my_create(fn,CREATE_MODE,O_RDWR | O_TRUNC,MYF(MY_WME))) >= 0)
if ((file=my_create(path, CREATE_MODE,O_RDWR | O_TRUNC,MYF(MY_WME))) >= 0)
{
sprintf(buf,"default-character-set=%s\n",
(create && create->table_charset) ?
create->table_charset->name : "DEFAULT");
ulong length;
length= my_sprintf(buf,(buf, "default-character-set=%s\n",
(create && create->table_charset) ?
create->table_charset->name : "DEFAULT"));
if (my_write(file,(byte*)buf,strlen(buf),MYF(MY_NABP+MY_WME)))
{
// QQ : should we send more suitable error message?
my_error(ER_CANT_CREATE_DB,MYF(0),db,my_errno);
error = -1;
goto exit;
}
/* Error is written by my_write */
if (!my_write(file,(byte*) buf, length, MYF(MY_NABP+MY_WME)))
error=0;
my_close(file,MYF(0));
}
else
{
// QQ : should we send more suitable error message?
my_error(ER_CANT_CREATE_DB,MYF(0),db,my_errno);
error = -1;
goto exit;
}
exit:
return error;
}
/*
Load database options file:
*/
static int load_db_opt(THD *thd,const char *db,HA_CREATE_INFO *create,char *fn)
/*
Load database options file
load_db_opt()
path Path for option file
create Where to store the read options
DESCRIPTION
For now, only default-character-set is read.
RETURN VALUES
0 File found
1 No database file or could not open it
*/
static bool load_db_opt(const char *path, HA_CREATE_INFO *create)
{
register File file;
char buf[256]="";
File file;
char buf[256];
DBUG_ENTER("load_db_opt");
bool error=1;
uint nbytes;
if ((file=my_open(fn,O_RDWR|O_BINARY,MYF(MY_WME))) >= 0)
bzero((char*) create,sizeof(*create));
if ((file=my_open(path, O_RDONLY | O_SHARE, MYF(0))) >= 0)
{
int nbytes=my_read(file,(byte*)buf,sizeof(buf)-1,MYF(0));
if ( nbytes >= 0 )
IO_CACHE cache;
init_io_cache(&cache, file, IO_SIZE, READ_CACHE, 0, 0, MYF(0));
while ((int) (nbytes= my_b_gets(&cache, (byte*) buf, sizeof(buf))) > 0)
{
char *ln=buf;
char *pe=buf+nbytes;
buf[nbytes]='\0';
for ( ln=buf; ln<pe; )
char *pos= buf+nbytes-1;
/* Remove end space and control characters */
while (pos > buf && !my_isgraph(system_charset_info, pos[-1]))
pos--;
*pos=0;
if ((pos= strchr(buf, '=')))
{
char *le,*val;
for ( le=ln, val=0 ; le<pe ; le++ )
if (!strncmp(buf,"default-character-set", (pos-buf)))
{
switch(le[0])
if (!(create->table_charset=get_charset_by_name(pos+1, MYF(0))))
{
case '=':
le[0]='\0';
val=le+1;
le++;
break;
case '\r':
case '\n':
le[0]='\0';
le++;
for( ; (le[0]=='\r' || le[0]=='\n') ; le++);
if (!strcmp(ln,"default-character-set") && val && val[0])
{
create->table_charset=get_charset_by_name(val, MYF(0));
}
goto cnt;
break;
sql_print_error(ER(ER_UNKNOWN_CHARACTER_SET),
pos+1);
}
}
cnt:
ln=le;
}
}
error=0;
end_io_cache(&cache);
my_close(file,MYF(0));
}
return 0;
DBUG_RETURN(error);
}
/* db-name is already validated when we come here */
int mysql_create_db(THD *thd, char *db, HA_CREATE_INFO *create_info, bool silent)
/*
Create a database
SYNOPSIS
mysql_create_db()
thd Thread handler
db Name of database to create
Function assumes that this is already validated.
create_info Database create options (like character set)
silent Used by replication when internally creating a database.
In this case the entry should not be logged.
RETURN VALUES
0 ok
-1 Error
*/
int mysql_create_db(THD *thd, char *db, HA_CREATE_INFO *create_info,
bool silent)
{
char path[FN_REFLEN+16];
MY_DIR *dirp;
long result=1;
int error = 0;
uint create_options = create_info ? create_info->options : 0;
DBUG_ENTER("mysql_create_db");
VOID(pthread_mutex_lock(&LOCK_mysql_create_db));
@ -167,34 +193,49 @@ int mysql_create_db(THD *thd, char *db, HA_CREATE_INFO *create_info, bool silent
}
}
strcat(path,"/");
unpack_dirname(path,path);
unpack_dirname(path, path);
strcat(path,MY_DB_OPT_FILE);
if ((error=write_db_opt(thd,db,create_info,path)))
goto exit;
if (write_db_opt(path, create_info))
{
/*
Could not create options file.
Restore things to beginning.
*/
if (rmdir(path) >= 0)
{
error= -1;
goto exit;
}
/*
We come here when we managed to create the database, but not the option
file. In this case it's best to just continue as if nothing has
happened. (This is a very unlikely senario)
*/
}
if (!silent)
{
if (!thd->query)
char *query;
uint query_length;
if (!thd->query) // Only in replication
{
thd->query = path;
thd->query_length = (uint) (strxmov(path,"create database ", db, NullS)-
path);
query= path;
query_length= (uint) (strxmov(path,"create database ", db, NullS) -
path);
}
else
{
mysql_update_log.write(thd,thd->query, thd->query_length);
if (mysql_bin_log.is_open())
{
Query_log_event qinfo(thd, thd->query);
mysql_bin_log.write(&qinfo);
}
query= thd->query;
query_length= thd->query_length;
}
if (thd->query == path)
mysql_update_log.write(thd, query, query_length);
if (mysql_bin_log.is_open())
{
thd->query = 0; // just in case
thd->query_length = 0;
Query_log_event qinfo(thd, query, query_length);
mysql_bin_log.write(&qinfo);
}
send_ok(&thd->net, result);
send_ok(thd, result);
}
exit:
@ -207,15 +248,15 @@ exit2:
/* db-name is already validated when we come here */
int mysql_alter_db(THD *thd, char *db, HA_CREATE_INFO *create_info, bool silent)
int mysql_alter_db(THD *thd, const char *db, HA_CREATE_INFO *create_info)
{
char path[FN_REFLEN+16];
char path[FN_REFLEN+16];
MY_DIR *dirp;
long result=1;
int error = 0;
DBUG_ENTER("mysql_create_db");
register File file;
uint create_options = create_info ? create_info->options : 0;
DBUG_ENTER("mysql_alter_db");
VOID(pthread_mutex_lock(&LOCK_mysql_create_db));
@ -227,45 +268,27 @@ int mysql_alter_db(THD *thd, char *db, HA_CREATE_INFO *create_info, bool silent)
}
/* Check directory */
(void)sprintf(path,"%s/%s", mysql_data_home, db);
strcat(path,"/");
unpack_dirname(path,path); // Convert if not unix
strcat(path,MY_DB_OPT_FILE);
if ((error=write_db_opt(thd,db,create_info,path)))
(void)sprintf(path,"%s/%s/%s", mysql_data_home, db, MY_DB_OPT_FILE);
fn_format(path, path, "", "", MYF(MY_UNPACK_FILENAME));
if ((error=write_db_opt(path, create_info)))
goto exit;
/*
Change options if current
database is being altered
Change options if current database is being altered
TODO: Delete this code
*/
if (thd->db && !strcmp(thd->db,db))
{
thd->db_charset= create_info ? create_info->table_charset : NULL;
}
if (!silent)
mysql_update_log.write(thd,thd->query, thd->query_length);
if (mysql_bin_log.is_open())
{
if (!thd->query)
{
thd->query = path;
thd->query_length = (uint) (strxmov(path,"alter database ", db, NullS)-
path);
}
{
mysql_update_log.write(thd,thd->query, thd->query_length);
if (mysql_bin_log.is_open())
{
Query_log_event qinfo(thd, thd->query, thd->query_length);
mysql_bin_log.write(&qinfo);
}
}
if (thd->query == path)
{
thd->query = 0; // just in case
thd->query_length = 0;
}
send_ok(&thd->net, result);
Query_log_event qinfo(thd, thd->query, thd->query_length);
mysql_bin_log.write(&qinfo);
}
send_ok(thd, result);
exit:
start_waiting_global_read_lock(thd);
@ -275,18 +298,6 @@ exit2:
}
const char *del_exts[]= {".frm", ".BAK", ".TMD",".opt", NullS};
static TYPELIB deletable_extentions=
{array_elements(del_exts)-1,"del_exts", del_exts};
const char *known_exts[]=
{".ISM",".ISD",".ISM",".MRG",".MYI",".MYD",".db",NullS};
static TYPELIB known_extentions=
{array_elements(known_exts)-1,"known_exts", known_exts};
/*
Drop all tables in a database.
@ -324,7 +335,7 @@ int mysql_rm_db(THD *thd,char *db,bool if_exists, bool silent)
my_error(ER_DB_DROP_EXISTS,MYF(0),db);
}
else if (!silent)
send_ok(&thd->net,0);
send_ok(thd,0);
goto exit;
}
pthread_mutex_lock(&LOCK_open);
@ -355,7 +366,7 @@ int mysql_rm_db(THD *thd,char *db,bool if_exists, bool silent)
thd->query = 0; // just in case
thd->query_length = 0;
}
send_ok(&thd->net,(ulong) deleted);
send_ok(thd,(ulong) deleted);
}
error = 0;
}
@ -503,30 +514,47 @@ static long mysql_rm_known_files(THD *thd, MY_DIR *dirp, const char *db,
}
bool mysql_change_db(THD *thd,const char *name)
/*
Change default database.
SYNOPSIS
mysql_change_db()
thd Thread handler
name Databasename
DESCRIPTION
Becasue the database name may have been given directly from the
communication packet (in case of 'connect' or 'COM_INIT_DB')
we have to do end space removal in this function.
RETURN VALUES
0 ok
1 error
*/
bool mysql_change_db(THD *thd, const char *name)
{
int length, db_length;
char *dbname=my_strdup((char*) name,MYF(MY_WME));
char path[FN_REFLEN];
uint db_access;
HA_CREATE_INFO create;
DBUG_ENTER("mysql_change_db");
if (!dbname || !(db_length=strip_sp(dbname)))
{
x_free(dbname); /* purecov: inspected */
send_error(&thd->net,ER_NO_DB_ERROR); /* purecov: inspected */
send_error(thd,ER_NO_DB_ERROR); /* purecov: inspected */
DBUG_RETURN(1); /* purecov: inspected */
}
if ((db_length > NAME_LEN) || check_db_name(dbname))
{
net_printf(&thd->net,ER_WRONG_DB_NAME, dbname);
net_printf(thd,ER_WRONG_DB_NAME, dbname);
x_free(dbname);
DBUG_RETURN(1);
}
if (lower_case_table_names)
casedn_str(dbname);
my_casedn_str(system_charset_info, dbname);
DBUG_PRINT("info",("Use database: %s", dbname));
if (test_all_bits(thd->master_access,DB_ACLS))
db_access=DB_ACLS;
@ -536,7 +564,7 @@ bool mysql_change_db(THD *thd,const char *name)
thd->master_access);
if (!(db_access & DB_ACLS) && (!grant_option || check_grant_db(thd,dbname)))
{
net_printf(&thd->net,ER_DBACCESS_DENIED_ERROR,
net_printf(thd,ER_DBACCESS_DENIED_ERROR,
thd->priv_user,
thd->host_or_ip,
dbname);
@ -554,49 +582,37 @@ bool mysql_change_db(THD *thd,const char *name)
path[length-1]=0; // remove ending '\'
if (access(path,F_OK))
{
net_printf(&thd->net,ER_BAD_DB_ERROR,dbname);
net_printf(thd,ER_BAD_DB_ERROR,dbname);
my_free(dbname,MYF(0));
DBUG_RETURN(1);
}
send_ok(&thd->net);
send_ok(thd);
x_free(thd->db);
thd->db=dbname;
thd->db=dbname; // THD::~THD will free this
thd->db_length=db_length;
thd->db_access=db_access;
strcat(path,"/");
unpack_dirname(path,path);
strcat(path,MY_DB_OPT_FILE);
bzero(&create,sizeof(create));
load_db_opt(thd,name,&create,path);
strmov(path+unpack_dirname(path,path), MY_DB_OPT_FILE);
load_db_opt(path, &create);
thd->db_charset=create.table_charset;
DBUG_RETURN(0);
}
int mysqld_show_create_db(THD *thd,const char *name)
int mysqld_show_create_db(THD *thd, const char *dbname)
{
int length, db_length;
char *dbname=my_strdup((char*) name,MYF(MY_WME));
char path[FN_REFLEN];
char path[FN_REFLEN], *to;
uint db_access;
bool found_libchar;
HA_CREATE_INFO create;
CONVERT *convert=thd->convert_set;
CONVERT *convert=thd->variables.convert_set;
DBUG_ENTER("mysql_show_create_db");
if (!dbname || !(db_length=strip_sp(dbname)))
if (check_db_name(dbname))
{
x_free(dbname); /* purecov: inspected */
send_error(&thd->net,ER_NO_DB_ERROR); /* purecov: inspected */
DBUG_RETURN(1); /* purecov: inspected */
}
if ((db_length > NAME_LEN) || check_db_name(dbname))
{
net_printf(&thd->net,ER_WRONG_DB_NAME, dbname);
x_free(dbname);
net_printf(thd,ER_WRONG_DB_NAME, dbname);
DBUG_RETURN(1);
}
@ -608,7 +624,7 @@ int mysqld_show_create_db(THD *thd,const char *name)
thd->master_access);
if (!(db_access & DB_ACLS) && (!grant_option || check_grant_db(thd,dbname)))
{
net_printf(&thd->net,ER_DBACCESS_DENIED_ERROR,
net_printf(thd,ER_DBACCESS_DENIED_ERROR,
thd->priv_user,
thd->host_or_ip,
dbname);
@ -616,26 +632,26 @@ int mysqld_show_create_db(THD *thd,const char *name)
thd->priv_user,
thd->host_or_ip,
dbname);
my_free(dbname,MYF(0));
DBUG_RETURN(1);
}
(void) sprintf(path,"%s/%s",mysql_data_home,dbname);
(void) sprintf(path,"%s/%s",mysql_data_home, dbname);
length=unpack_dirname(path,path); // Convert if not unix
found_libchar= 0;
if (length && path[length-1] == FN_LIBCHAR)
{
found_libchar= 1;
path[length-1]=0; // remove ending '\'
}
if (access(path,F_OK))
{
net_printf(&thd->net,ER_BAD_DB_ERROR,dbname);
my_free(dbname,MYF(0));
net_printf(thd,ER_BAD_DB_ERROR,dbname);
DBUG_RETURN(1);
}
strcat(path,"/");
unpack_dirname(path,path);
strcat(path,MY_DB_OPT_FILE);
bzero(&create,sizeof(create));
load_db_opt(thd,name,&create,path);
if (found_libchar)
path[length-1]= FN_LIBCHAR;
strmov(path+length, MY_DB_OPT_FILE);
load_db_opt(path, &create);
List<Item> field_list;
field_list.push_back(new Item_empty_string("Database",NAME_LEN));
@ -646,19 +662,16 @@ int mysqld_show_create_db(THD *thd,const char *name)
String *packet = &thd->packet;
packet->length(0);
net_store_data(packet, convert, name);
sprintf(path, "CREATE DATABASE %s", name);
net_store_data(packet, convert, dbname);
to= strxmov(path, "CREATE DATABASE `", dbname, "`", NullS);
if (create.table_charset)
{
strcat(path," DEFAULT CHARACTER SET ");
strcat(path,create.table_charset->name);
}
net_store_data(packet, convert, path);
to= strxmov(to," DEFAULT CHARACTER SET ", create.table_charset->name,
NullS);
net_store_data(packet, convert, path, (uint) (to-path));
if (my_net_write(&thd->net,(char*) packet->ptr(),packet->length()))
if (my_net_write(&thd->net,(char*) packet->ptr(), packet->length()))
DBUG_RETURN(1);
send_eof(&thd->net);
send_eof(thd);
DBUG_RETURN(0);
}

View file

@ -43,7 +43,7 @@ int mysql_delete(THD *thd, TABLE_LIST *table_list, COND *conds, ORDER *order,
table_list->db=thd->db;
if ((thd->options & OPTION_SAFE_UPDATES) && !conds)
{
send_error(&thd->net,ER_UPDATE_WITHOUT_KEY_IN_SAFE_MODE);
send_error(thd,ER_UPDATE_WITHOUT_KEY_IN_SAFE_MODE);
DBUG_RETURN(1);
}
@ -83,7 +83,7 @@ int mysql_delete(THD *thd, TABLE_LIST *table_list, COND *conds, ORDER *order,
!limit)
{
delete select;
send_ok(&thd->net,0L);
send_ok(thd,0L);
DBUG_RETURN(0); // Nothing to delete
}
@ -94,7 +94,7 @@ int mysql_delete(THD *thd, TABLE_LIST *table_list, COND *conds, ORDER *order,
if ((thd->options & OPTION_SAFE_UPDATES) && limit == HA_POS_ERROR)
{
delete select;
send_error(&thd->net,ER_UPDATE_WITHOUT_KEY_IN_SAFE_MODE);
send_error(thd,ER_UPDATE_WITHOUT_KEY_IN_SAFE_MODE);
DBUG_RETURN(1);
}
}
@ -188,10 +188,10 @@ cleanup:
}
delete select;
if (error >= 0) // Fatal error
send_error(&thd->net,thd->killed ? ER_SERVER_SHUTDOWN: 0);
send_error(thd,thd->killed ? ER_SERVER_SHUTDOWN: 0);
else
{
send_ok(&thd->net,deleted);
send_ok(thd,deleted);
DBUG_PRINT("info",("%d records deleted",deleted));
}
DBUG_RETURN(0);
@ -354,7 +354,7 @@ void multi_delete::send_error(uint errcode,const char *err)
DBUG_ENTER("multi_delete::send_error");
/* First send error what ever it is ... */
::send_error(&thd->net,errcode,err);
::send_error(thd,errcode,err);
/* If nothing deleted return */
if (!deleted)
@ -456,7 +456,7 @@ bool multi_delete::send_eof()
thd->proc_info="end";
if (error)
{
::send_error(&thd->net);
::send_error(thd);
return 1;
}
@ -483,7 +483,7 @@ bool multi_delete::send_eof()
{
query_cache_invalidate3(thd, delete_tables, 1);
}
::send_ok(&thd->net,deleted);
::send_ok(thd,deleted);
return 0;
}
@ -580,7 +580,7 @@ end:
Query_log_event qinfo(thd, thd->query, thd->query_length);
mysql_bin_log.write(&qinfo);
}
send_ok(&thd->net); // This should return record count
send_ok(thd); // This should return record count
}
VOID(pthread_mutex_lock(&LOCK_open));
unlock_table_name(thd, table_list);

View file

@ -120,7 +120,7 @@ int mysql_derived(THD *thd, LEX *lex, SELECT_LEX_UNIT *unit, TABLE_LIST *t)
exit:
close_thread_tables(thd);
if (res > 0)
send_error(&thd->net, ER_UNKNOWN_COM_ERROR); // temporary only ...
send_error(thd, ER_UNKNOWN_COM_ERROR); // temporary only ...
}
DBUG_RETURN(res);
}

View file

@ -29,6 +29,6 @@ int mysql_do(THD *thd, List<Item> &values)
DBUG_RETURN(-1);
while ((value = li++))
value->val_int();
send_ok(&thd->net);
send_ok(thd);
DBUG_RETURN(0);
}

View file

@ -18,202 +18,136 @@
/**********************************************************************
This file contains the implementation of error and warnings related
- Whenever an error or warning occured, it pushes the same to
the respective list along with sending it to client.
- Whenever an error or warning occurred, it pushes it to a warning list
that the user can retrieve with SHOW WARNINGS or SHOW ERRORS.
- For each statement, we return the number of warnings generated from this
command. Note that this can be different from @@warning_count as
we reset the warning list only for questions that uses a table.
This is done to allow on to do:
INSERT ...;
SELECT @@warning_count;
SHOW WARNINGS;
(If we would reset after each command, we could not retrieve the number
of warnings)
- When client requests the information using SHOW command, then
server processes from this list and returns back in the form of
resultset.
syntax : SHOW [COUNT(*)] ERRORS [LIMIT [offset,] rows]
SHOW [COUNT(*)] WARNINGS [LIMIT [offset,] rows]
Supported syntaxes:
SHOW [COUNT(*)] ERRORS [LIMIT [offset,] rows]
SHOW [COUNT(*)] WARNINGS [LIMIT [offset,] rows]
SELECT @@warning_count, @@error_count;
***********************************************************************/
/* Handles errors and warnings .. */
#include "mysql_priv.h"
/*
Push the error to error list
Reset all warnings for the thread
SYNOPSIS
mysql_reset_errors()
thd Thread handle
*/
void push_error(uint code, const char *msg)
void mysql_reset_errors(THD *thd)
{
THD *thd=current_thd;
mysql_st_error *err = new mysql_st_error(code,msg,(const char*)thd->query);
if (thd->err_list.elements >= thd->max_error_count)
{
/* Remove the old elements and always maintain the max size
equal to sql_error_count.
If one max_error_count using sets sql_error_count less than
the current list size, then make sure it always grows upto
sql_error_count size only
** BUG ** : Doesn't work in removing the old one
from the list, and thus SET SQL_ERROR_COUNT=x doesn't work
*/
for (uint count=thd->err_list.elements-1;
count <= thd->max_error_count-1; count++)
{
thd->err_list.remove_last();
}
}
thd->err_list.push_front(err);
free_root(&thd->warn_root,MYF(0));
bzero((char*) thd->warn_count, sizeof(thd->warn_count));
thd->warn_list.empty();
}
/*
Push the warning to warning list
Push the warning/error to error list if there is still room in the list
SYNOPSIS
push_warning()
thd Thread handle
level Severity of warning (note, warning, error ...)
code Error number
msg Clear error message
*/
void push_warning(uint code, const char *msg)
void push_warning(THD *thd, MYSQL_ERROR::enum_warning_level level, uint code,
const char *msg)
{
THD *thd=current_thd;
mysql_st_error *warn = new mysql_st_error(code,msg,(const char *)thd->query);
if (thd->warn_list.elements >= thd->max_warning_count)
if (thd->warn_list.elements < thd->variables.max_error_count)
{
/* Remove the old elements and always maintian the max size
equal to sql_error_count
/*
The following code is here to change the allocation to not
use the thd->mem_root, which is freed after each query
*/
for (uint count=thd->warn_list.elements;
count <= thd->max_warning_count-1; count++)
{
thd->warn_list.remove_last();
}
MEM_ROOT *old_root=my_pthread_getspecific_ptr(MEM_ROOT*,THR_MALLOC);
my_pthread_setspecific_ptr(THR_MALLOC, &thd->warn_root);
MYSQL_ERROR *err= new MYSQL_ERROR(code, level, msg);
if (err)
thd->warn_list.push_back(err);
my_pthread_setspecific_ptr(THR_MALLOC, old_root);
}
thd->warn_list.push_front(warn);
thd->warn_count[(uint) level]++;
thd->total_warn_count++;
}
/*
List all errors
Send all notes, errors or warnings to the client in a result set
SYNOPSIS
mysqld_show_warnings()
thd Thread handler
levels_to_show Bitmap for which levels to show
DESCRIPTION
Takes into account the current LIMIT
RETURN VALUES
0 ok
1 Error sending data to client
*/
int mysqld_show_errors(THD *thd)
static const char *warning_level_names[]= {"Note", "Warning", "Error", "?"};
my_bool mysqld_show_warnings(THD *thd, ulong levels_to_show)
{
List<Item> field_list;
DBUG_ENTER("mysqld_show_errors");
field_list.push_back(new Item_int("CODE",0,4));
field_list.push_back(new Item_empty_string("MESSAGE",MYSQL_ERRMSG_SIZE));
field_list.push_back(new Item_empty_string("QUERY",NAME_LEN));
field_list.push_back(new Item_empty_string("Level", 7));
field_list.push_back(new Item_int("Code",0,4));
field_list.push_back(new Item_empty_string("Message",MYSQL_ERRMSG_SIZE));
if (send_fields(thd,field_list,1))
DBUG_RETURN(1);
mysql_st_error *err;
SELECT_LEX *sel=&thd->lex.select_lex;
ha_rows offset = sel->offset_limit,limit = sel->select_limit;
uint num_rows = 0;
MYSQL_ERROR *err;
SELECT_LEX *sel= &thd->lex.select_lex;
ha_rows offset= sel->offset_limit, limit= sel->select_limit;
Error_iterator<mysql_st_error> it(thd->err_list);
while(offset-- && (err = it++));/* Should be fixed with overloaded
operator '+' or with new funtion
goto() in list ?
*/
while((num_rows++ < limit) && (err = it++))
List_iterator_fast<MYSQL_ERROR> it(thd->warn_list);
while ((err= it++))
{
/* Skip levels that the user is not interested in */
if (!(levels_to_show & ((ulong) 1 << err->level)))
continue;
if (offset)
{
offset--;
continue;
}
thd->packet.length(0);
net_store_data(&thd->packet,(uint32)err->code);
net_store_data(&thd->packet,warning_level_names[err->level]);
net_store_data(&thd->packet,(uint32) err->code);
net_store_data(&thd->packet,err->msg);
net_store_data(&thd->packet,err->query);
if (my_net_write(&thd->net,(char*)thd->packet.ptr(),thd->packet.length()))
DBUG_RETURN(-1);
DBUG_RETURN(1);
if (!--limit)
break;
}
send_eof(&thd->net);
send_eof(thd);
DBUG_RETURN(0);
}
/*
Return errors count
*/
int mysqld_show_errors_count(THD *thd)
{
List<Item> field_list;
DBUG_ENTER("mysqld_show_errors_count");
field_list.push_back(new Item_int("COUNT(*)",0,4));
if (send_fields(thd,field_list,1))
DBUG_RETURN(1);
thd->packet.length(0);
net_store_data(&thd->packet,(uint32)thd->err_list.elements);
if (my_net_write(&thd->net,(char*) thd->packet.ptr(),thd->packet.length()))
DBUG_RETURN(-1);
send_eof(&thd->net);
DBUG_RETURN(0);
}
/*
List all warnings
*/
int mysqld_show_warnings(THD *thd)
{
List<Item> field_list;
DBUG_ENTER("mysqld_show_warnings");
field_list.push_back(new Item_int("CODE",0,21));
field_list.push_back(new Item_empty_string("MESSAGE",MYSQL_ERRMSG_SIZE));
field_list.push_back(new Item_empty_string("QUERY",NAME_LEN));
if (send_fields(thd,field_list,1))
DBUG_RETURN(1);
mysql_st_error *warn;
SELECT_LEX *sel=&thd->lex.select_lex;
ha_rows offset = sel->offset_limit,limit = sel->select_limit;
uint num_rows = 0;
Error_iterator<mysql_st_error> it(thd->warn_list);
while(offset-- && (warn = it++));
while((num_rows++ < limit) && (warn = it++))
{
thd->packet.length(0);
net_store_data(&thd->packet,(uint32)warn->code);
net_store_data(&thd->packet,warn->msg);
net_store_data(&thd->packet,warn->query);
if (my_net_write(&thd->net,(char*) thd->packet.ptr(),thd->packet.length()))
DBUG_RETURN(-1);
}
send_eof(&thd->net);
DBUG_RETURN(0);
}
/*
Return warnings count
*/
int mysqld_show_warnings_count(THD *thd)
{
List<Item> field_list;
DBUG_ENTER("mysqld_show_warnings_count");
field_list.push_back(new Item_int("COUNT(*)",0,21));
if (send_fields(thd,field_list,1))
DBUG_RETURN(1);
thd->packet.length(0);
net_store_data(&thd->packet,(uint32)thd->warn_list.elements);
if (my_net_write(&thd->net,(char*)thd->packet.ptr(),thd->packet.length()))
DBUG_RETURN(-1);
send_eof(&thd->net);
DBUG_RETURN(0);
}

View file

@ -62,7 +62,7 @@ int mysql_ha_open(THD *thd, TABLE_LIST *tables)
return -1;
}
send_ok(&thd->net);
send_ok(thd);
return 0;
}
@ -83,7 +83,7 @@ int mysql_ha_close(THD *thd, TABLE_LIST *tables, bool dont_send_ok)
return -1;
}
if (!dont_send_ok)
send_ok(&thd->net);
send_ok(thd);
return 0;
}
@ -185,7 +185,7 @@ int mysql_ha_read(THD *thd, TABLE_LIST *tables,
}
if (!(key= (byte*) sql_calloc(ALIGN_SIZE(key_len))))
{
send_error(&thd->net,ER_OUTOFMEMORY);
send_error(thd,ER_OUTOFMEMORY);
goto err;
}
key_copy(key, table, keyno, key_len);
@ -195,7 +195,7 @@ int mysql_ha_read(THD *thd, TABLE_LIST *tables,
break;
}
default:
send_error(&thd->net,ER_ILLEGAL_HA);
send_error(thd,ER_ILLEGAL_HA);
goto err;
}
@ -240,7 +240,7 @@ int mysql_ha_read(THD *thd, TABLE_LIST *tables,
}
ok:
mysql_unlock_tables(thd,lock);
send_eof(&thd->net);
send_eof(thd);
return 0;
err:
mysql_unlock_tables(thd,lock);

View file

@ -333,7 +333,7 @@ int mysql_insert(THD *thd,TABLE_LIST *table_list, List<Item> &fields,
if (values_list.elements == 1 && (!(thd->options & OPTION_WARNINGS) ||
!thd->cuted_fields))
send_ok(&thd->net,info.copied+info.deleted,id);
send_ok(thd,info.copied+info.deleted,id);
else
{
char buff[160];
@ -345,7 +345,7 @@ int mysql_insert(THD *thd,TABLE_LIST *table_list, List<Item> &fields,
else
sprintf(buff,ER(ER_INSERT_INFO),info.records,info.deleted,
thd->cuted_fields);
::send_ok(&thd->net,info.copied+info.deleted,(ulonglong)id,buff);
::send_ok(thd,info.copied+info.deleted,(ulonglong)id,buff);
}
DBUG_RETURN(0);
@ -667,7 +667,7 @@ static TABLE *delayed_get_table(THD *thd,TABLE_LIST *table_list)
delete tmp;
thd->fatal_error=1;
pthread_mutex_unlock(&LOCK_delayed_create);
net_printf(&thd->net,ER_CANT_CREATE_THREAD,error);
net_printf(thd,ER_CANT_CREATE_THREAD,error);
DBUG_RETURN(0);
}
@ -1334,7 +1334,7 @@ bool select_insert::send_data(List<Item> &values)
void select_insert::send_error(uint errcode,const char *err)
{
::send_error(&thd->net,errcode,err);
::send_error(thd,errcode,err);
table->file->extra(HA_EXTRA_NO_CACHE);
table->file->activate_all_index(thd);
ha_rollback_stmt(thd);
@ -1360,7 +1360,7 @@ bool select_insert::send_eof()
if (error)
{
table->file->print_error(error,MYF(0));
::send_error(&thd->net);
::send_error(thd);
return 1;
}
else
@ -1374,7 +1374,7 @@ bool select_insert::send_eof()
thd->cuted_fields);
if (last_insert_id)
thd->insert_id(last_insert_id); // For update log
::send_ok(&thd->net,info.copied,last_insert_id,buff);
::send_ok(thd,info.copied,last_insert_id,buff);
mysql_update_log.write(thd,thd->query,thd->query_length);
if (mysql_bin_log.is_open())
{

View file

@ -1064,7 +1064,7 @@ bool st_select_lex_unit::create_total_list_n_last_return(THD *thd, st_lex *lex,
// check usage of ORDER BY in union
if (sl->order_list.first && sl->next_select() && !sl->braces)
{
net_printf(&thd->net,ER_WRONG_USAGE,"UNION","ORDER BY");
net_printf(thd,ER_WRONG_USAGE,"UNION","ORDER BY");
return 1;
}
for (SELECT_LEX_UNIT *inner= sl->first_inner_unit();
@ -1092,7 +1092,7 @@ bool st_select_lex_unit::create_total_list_n_last_return(THD *thd, st_lex *lex,
if (!(cursor= (TABLE_LIST *) thd->memdup((char*) aux,
sizeof(*aux))))
{
send_error(&thd->net,0);
send_error(thd,0);
return 1;
}
*new_table_list= cursor;

View file

@ -238,7 +238,8 @@ typedef class st_select_lex_unit SELECT_LEX_UNIT;
SELECT_LEX - store information of parsed SELECT_LEX statment
*/
class JOIN;
class st_select_lex: public st_select_lex_node {
class st_select_lex: public st_select_lex_node
{
public:
char *db, *db1, *table1, *db2, *table2; /* For outer join using .. */
Item *where, *having; /* WHERE & HAVING clauses */
@ -342,6 +343,7 @@ typedef struct st_lex
enum enum_var_type option_type;
uint grant, grant_tot_col, which_columns, union_option;
uint fk_delete_opt, fk_update_opt, fk_match_option;
uint param_count;
bool drop_primary, drop_if_exists, local_file, olap;
bool in_comment, ignore_space, verbose, simple_alter;
bool derived_tables;

View file

@ -362,120 +362,3 @@ public:
I_List_iterator(I_List<T> &a) : base_ilist_iterator(a) {}
inline T* operator++(int) { return (T*) base_ilist_iterator::next(); }
};
/*
New error list without mem_root from THD, to have the life of the
allocation becomes connection level . by ovveriding new from Sql_alloc.
*/
class Error_alloc
{
public:
static void *operator new(size_t size)
{
return (void*)my_malloc((uint)size, MYF(MY_WME | MY_FAE));
}
#if 0
static void operator delete(void* ptr_arg, size_t size)
{
my_free((gptr)ptr_arg, MYF(MY_WME|MY_ALLOW_ZERO_PTR));
}
#endif
friend class error_node;
friend class error_list;
};
class error_node :public Error_alloc, public list_node
{
public:
static void *operator new(size_t size)
{
return (void*)my_malloc((uint)size, MYF(MY_WME | MY_FAE));
}
#if 0
static void operator delete(void* ptr_arg, size_t size)
{
my_free((gptr)ptr_arg, MYF(MY_WME|MY_ALLOW_ZERO_PTR));
}
#endif
error_node(void *info_par,list_node *next_par):list_node(info_par,next_par){};
error_node() : list_node() {};
friend class error_list;
friend class error_list_iterator;
};
class error_list: public Error_alloc, public base_list
{
public:
inline error_list() : base_list() { };
inline error_list(const error_list &tmp) : base_list(tmp)
{
elements=tmp.elements;
first=tmp.first;
last=tmp.last;
}
inline bool push_front(void *info)
{
error_node *node=new error_node(info,first);
if (node)
{
if (last == &first)
last= &node->next;
first=node;
elements++;
return 0;
}
return 1;
}
inline void remove_last(void)
{
remove(last);
}
protected:
void after(void *info,list_node *node)
{
error_node *new_node=new error_node(info,node->next);
node->next=new_node;
elements++;
if (last == &(node->next))
last= &new_node->next;
}
};
class error_list_iterator : public base_list_iterator
{
inline error_list_iterator(base_list &base_ptr): base_list_iterator(base_ptr) {};
};
template <class T> class Error :public error_list
{
public:
inline Error() :error_list() {}
inline Error(const Error<T> &tmp) :error_list(tmp) {}
inline bool push_back(T *a) { return error_list::push_back(a); }
inline bool push_front(T *a) { return error_list::push_front(a); }
inline T* head() {return (T*) error_list::head(); }
inline T** head_ref() {return (T**) error_list::head_ref(); }
inline T* pop() {return (T*) error_list::pop(); }
void delete_elements(void)
{
error_node *element,*next;
for (element=first; element != &error_end_of_list; element=next)
{
next=element->next;
delete (T*) element->info;
}
empty();
}
};
template <class T> class Error_iterator :public base_list_iterator
{
public:
Error_iterator(Error<T> &a) : base_list_iterator(a) {}
inline T* operator++(int) { return (T*) base_list_iterator::next(); }
inline T *replace(T *a) { return (T*) base_list_iterator::replace(a); }
inline T *replace(Error<T> &a) { return (T*) base_list_iterator::replace(a); }
inline void after(T *a) { base_list_iterator::after(a); }
inline T** ref(void) { return (T**) base_list_iterator::ref(); }
};

View file

@ -293,7 +293,7 @@ int mysql_load(THD *thd,sql_exchange *ex,TABLE_LIST *table_list,
}
sprintf(name,ER(ER_LOAD_INFO),info.records,info.deleted,
info.records-info.copied,thd->cuted_fields);
send_ok(&thd->net,info.copied+info.deleted,0L,name);
send_ok(thd,info.copied+info.deleted,0L,name);
// on the slave thd->query is never initialized
if (!thd->slave_thread)
mysql_update_log.write(thd,thd->query,thd->query_length);

File diff suppressed because it is too large Load diff

View file

@ -25,7 +25,7 @@ Prepare:
store its information list lex->param_list
- Without executing the query, return back to client the total
number of parameters along with result-set metadata information
(if any )
(if any)
Prepare-execute:
@ -38,46 +38,132 @@ Prepare-execute:
to client
Long data handling:
- Server gets the long data in pieces with command type 'COM_LONG_DATA'.
- The packet recieved will have the format as:
[type_spec_exists][type][length][data]
[COM_LONG_DATA:1][parameter_number:2][type:2][data]
- Checks if the type is specified by client, and if yes reads the type,
and stores the data in that format.
- If length == MYSQL_END_OF_DATA, then server sets up the data read ended.
- It's up to the client to check for read data ended. The server doesn't
care.
***********************************************************************/
#include "mysql_priv.h"
#include "sql_acl.h"
#include <assert.h> // for DEBUG_ASSERT()
#include <ctype.h> // for isspace()
#include <m_ctype.h> // for isspace()
/**************************************************************************/
extern int yyparse(void);
static ulong get_param_length(uchar **packet);
static uint get_buffer_type(uchar **packet);
static bool param_is_null(uchar **packet);
static bool setup_param_fields(THD *thd,List<Item> &params);
static uchar* setup_param_field(Item_param *item_param, uchar *pos, uint buffer_type);
static uchar* setup_param_field(Item_param *item_param, uchar *pos,
uint buffer_type);
static void setup_longdata_field(Item_param *item_param, uchar *pos);
static bool setup_longdata(THD *thd,List<Item> &params);
static void send_prepare_results(THD *thd);
static void mysql_parse_prepare_query(THD *thd,char *packet,uint length);
static bool mysql_send_insert_fields(THD *thd,TABLE_LIST *table_list,
static bool send_prepare_results(PREP_STMT *stmt);
static bool parse_prepare_query(PREP_STMT *stmt, char *packet, uint length);
static bool mysql_send_insert_fields(PREP_STMT *stmt, TABLE_LIST *table_list,
List<Item> &fields,
List<List_item> &values_list,thr_lock_type lock_type);
static bool mysql_test_insert_fields(THD *thd,TABLE_LIST *table_list,
List<List_item> &values_list,
thr_lock_type lock_type);
static bool mysql_test_insert_fields(PREP_STMT *stmt, TABLE_LIST *table_list,
List<Item> &fields,
List<List_item> &values_list,thr_lock_type lock_type);
static bool mysql_test_upd_fields(THD *thd,TABLE_LIST *table_list,
List<List_item> &values_list,
thr_lock_type lock_type);
static bool mysql_test_upd_fields(PREP_STMT *stmt, TABLE_LIST *table_list,
List<Item> &fields, List<Item> &values,
COND *conds,thr_lock_type lock_type);
static bool mysql_test_select_fields(THD *thd, TABLE_LIST *tables,
List<Item> &fields, List<Item> &values,
COND *conds, ORDER *order, ORDER *group,
Item *having,thr_lock_type lock_type);
extern const char *any_db;
/**************************************************************************/
static bool mysql_test_select_fields(PREP_STMT *stmt, TABLE_LIST *tables,
List<Item> &fields, List<Item> &values,
COND *conds, ORDER *order, ORDER *group,
Item *having,thr_lock_type lock_type);
/*
Find prepared statement in thd
SYNOPSIS
find_prepared_statement()
thd Thread handler
stmt_id Statement id server specified to the client on prepare
RETURN VALUES
0 error. In this case the error is sent with my_error()
ptr Pointer to statement
*/
static PREP_STMT *find_prepared_statement(THD *thd, ulong stmt_id,
const char *when)
{
PREP_STMT *stmt;
DBUG_ENTER("find_prepared_statement");
DBUG_PRINT("enter",("stmt_id: %d", stmt_id));
if (thd->last_prepared_stmt && thd->last_prepared_stmt->stmt_id == stmt_id)
DBUG_RETURN(thd->last_prepared_stmt);
if ((stmt= (PREP_STMT*) tree_search(&thd->prepared_statements, &stmt_id,
(void*) 0)))
DBUG_RETURN (thd->last_prepared_stmt= stmt);
my_error(ER_UNKNOWN_STMT_HANDLER, MYF(0), stmt_id, when);
DBUG_RETURN(0);
}
/*
Compare two prepared statements; Used to find a prepared statement
*/
int compare_prep_stmt(PREP_STMT *a, PREP_STMT *b, void *not_used)
{
return (a->stmt_id < b->stmt_id) ? -1 : (a->stmt_id == b->stmt_id) ? 0 : 1;
}
/*
Free prepared statement.
SYNOPSIS
standard tree_element_free function.
DESCRIPTION
We don't have to free the stmt itself as this was stored in the tree
and will be freed when the node is deleted
*/
void free_prep_stmt(PREP_STMT *stmt, TREE_FREE mode, void *not_used)
{
free_root(&stmt->mem_root, MYF(0));
free_items(stmt->free_list);
}
/*
Send prepared stmt info to client after prepare
*/
bool send_prep_stmt(PREP_STMT *stmt, uint columns)
{
char buff[8];
int4store(buff, stmt->stmt_id);
int2store(buff+4, columns);
int2store(buff+6, stmt->param_count);
return my_net_write(&stmt->thd->net, buff, sizeof(buff));
}
/*
Send information about all item parameters
TODO: Not yet ready
*/
bool send_item_params(PREP_STMT *stmt)
{
char buff[1];
buff[0]=0;
return my_net_write(&stmt->thd->net, buff, sizeof(buff));
}
/*
Read the buffer type, this happens only first time
@ -90,8 +176,13 @@ static uint get_buffer_type(uchar **packet)
return (uint) uint2korr(pos);
}
/*
Check for NULL param data
RETURN VALUES
0 Value was not NULL
1 Value was NULL
*/
static bool param_is_null(uchar **packet)
@ -144,8 +235,7 @@ static uchar* setup_param_field(Item_param *item_param,
item_param->set_null();
return(pos);
}
switch (buffer_type)
{
switch (buffer_type) {
case FIELD_TYPE_TINY:
item_param->set_int((longlong)(*pos));
pos += 1;
@ -169,7 +259,7 @@ static uchar* setup_param_field(Item_param *item_param,
case FIELD_TYPE_FLOAT:
float data;
float4get(data,pos);
item_param->set_double(data);
item_param->set_double((double) data);
pos += 4;
break;
case FIELD_TYPE_DOUBLE:
@ -193,20 +283,19 @@ static uchar* setup_param_field(Item_param *item_param,
from client ..
*/
static bool setup_param_fields(THD *thd, List<Item> &params)
static bool setup_param_fields(THD *thd, PREP_STMT *stmt)
{
reg2 Item_param *item_param;
List_iterator<Item> it(params);
NET *net = &thd->net;
DBUG_ENTER("setup_param_fields");
#ifdef READY_TO_BE_USED
Item_param *item_param;
ulong param_count=0;
uchar *pos=(uchar*)net->read_pos+1;// skip command type
uchar *pos=(uchar*) thd->net.read_pos+1;// skip command type
if(*pos++) // No types supplied, read only param data
if (*pos++) // No types supplied, read only param data
{
while ((item_param=(Item_param *)it++) &&
(param_count++ < thd->param_count))
(param_count++ < stmt->param_count))
{
if (item_param->long_data_supplied)
continue;
@ -224,68 +313,15 @@ static bool setup_param_fields(THD *thd, List<Item> &params)
continue;
if (!(pos=setup_param_field(item_param,pos,
item_param->buffer_type=(enum_field_types)get_buffer_type(&pos))))
item_param->buffer_type=
(enum_field_types) get_buffer_type(&pos))))
DBUG_RETURN(1);
}
}
#endif
DBUG_RETURN(0);
}
/*
Buffer the long data and update the flags
*/
static void setup_longdata_field(Item_param *item_param, uchar *pos)
{
ulong len;
if (!*pos++)
item_param->buffer_type=(enum_field_types)get_buffer_type(&pos);
if (*pos == MYSQL_LONG_DATA_END)
item_param->set_long_end();
else
{
len = get_param_length(&pos);
item_param->set_longdata((const char *)pos, len);
}
}
/*
Store the long data from client in pieces
*/
static bool setup_longdata(THD *thd, List<Item> &params)
{
NET *net=&thd->net;
List_iterator<Item> it(params);
DBUG_ENTER("setup_longdata");
uchar *pos=(uchar*)net->read_pos+1;// skip command type at first position
ulong param_number = get_param_length(&pos);
Item_param *item_param = thd->current_param;
if (thd->current_param_number != param_number)
{
thd->current_param_number = param_number;
while (param_number--) /* TODO:
Change this loop by either having operator '+'
overloaded to point to desired 'item' or
add another memeber in list as 'goto' with
location count as parameter number, but what
is the best way to traverse ?
*/
{
it++;
}
thd->current_param = item_param = (Item_param *)it++;
}
setup_longdata_field(item_param,pos);
DBUG_RETURN(0);
}
/*
Validates insert fields
@ -337,16 +373,15 @@ static int check_prepare_fields(THD *thd,TABLE *table, List<Item> &fields,
Validate the following information for INSERT statement:
- field existance
- fields count
If there is no column list spec exists, then update the field_list
with all columns from the table, and send fields info back to client
*/
static bool mysql_test_insert_fields(THD *thd, TABLE_LIST *table_list,
static bool mysql_test_insert_fields(PREP_STMT *stmt,
TABLE_LIST *table_list,
List<Item> &fields,
List<List_item> &values_list,
thr_lock_type lock_type)
{
THD *thd= stmt->thd;
TABLE *table;
List_iterator_fast<List_item> its(values_list);
List_item *values;
@ -358,7 +393,7 @@ static bool mysql_test_insert_fields(THD *thd, TABLE_LIST *table_list,
if ((values= its++))
{
uint value_count;
ulong counter=0;
ulong counter= 0;
if (check_insert_fields(thd,table,fields,*values,1))
DBUG_RETURN(1);
@ -366,35 +401,20 @@ static bool mysql_test_insert_fields(THD *thd, TABLE_LIST *table_list,
value_count= values->elements;
its.rewind();
while ((values = its++))
while ((values= its++))
{
counter++;
if (values->elements != value_count)
{
my_printf_error(ER_WRONG_VALUE_COUNT_ON_ROW,
ER(ER_WRONG_VALUE_COUNT_ON_ROW),
MYF(0),counter);
MYF(0), counter);
DBUG_RETURN(1);
}
}
if (fields.elements == 0)
{
/* No field listing, so setup all fields */
List<Item> all_fields;
Field **ptr,*field;
for (ptr=table->field; (field= *ptr) ; ptr++)
{
all_fields.push_back(new Item_field(table->table_cache_key,
table->real_name,
field->field_name));
}
if ((setup_fields(thd,table_list,all_fields,1,0,0) ||
send_fields(thd,all_fields,1)))
DBUG_RETURN(1);
}
else if (send_fields(thd,fields,1))
DBUG_RETURN(1);
}
if (send_prep_stmt(stmt, 0) || send_item_params(stmt))
DBUG_RETURN(1);
DBUG_RETURN(0);
}
@ -403,15 +423,16 @@ static bool mysql_test_insert_fields(THD *thd, TABLE_LIST *table_list,
Validate the following information
UPDATE - set and where clause DELETE - where clause
And send update-set cluase column list fields info
back to client. For DELETE, just validate where cluase
And send update-set clause column list fields info
back to client. For DELETE, just validate where clause
and return no fields information back to client.
*/
static bool mysql_test_upd_fields(THD *thd, TABLE_LIST *table_list,
static bool mysql_test_upd_fields(PREP_STMT *stmt, TABLE_LIST *table_list,
List<Item> &fields, List<Item> &values,
COND *conds, thr_lock_type lock_type)
{
THD *thd= stmt->thd;
TABLE *table;
DBUG_ENTER("mysql_test_upd_fields");
@ -426,9 +447,8 @@ static bool mysql_test_upd_fields(THD *thd, TABLE_LIST *table_list,
Currently return only column list info only, and we are not
sending any info on where clause.
*/
if (fields.elements && send_fields(thd,fields,1))
if (send_prep_stmt(stmt, 0) || send_item_params(stmt))
DBUG_RETURN(1);
DBUG_RETURN(0);
}
@ -437,7 +457,7 @@ static bool mysql_test_upd_fields(THD *thd, TABLE_LIST *table_list,
SELECT - column list
- where clause
- orderr clause
- order clause
- having clause
- group by clause
- if no column spec i.e. '*', then setup all fields
@ -445,13 +465,14 @@ static bool mysql_test_upd_fields(THD *thd, TABLE_LIST *table_list,
And send column list fields info back to client.
*/
static bool mysql_test_select_fields(THD *thd, TABLE_LIST *tables,
static bool mysql_test_select_fields(PREP_STMT *stmt, TABLE_LIST *tables,
List<Item> &fields, List<Item> &values,
COND *conds, ORDER *order, ORDER *group,
Item *having, thr_lock_type lock_type)
{
TABLE *table;
bool hidden_group_fields;
THD *thd= stmt->thd;
List<Item> all_fields(fields);
DBUG_ENTER("mysql_test_select_fields");
@ -482,11 +503,13 @@ static bool mysql_test_select_fields(THD *thd, TABLE_LIST *tables,
Currently return only column list info only, and we are not
sending any info on where clause.
*/
if (fields.elements && send_fields(thd,fields,1))
if (send_prep_stmt(stmt, fields.elements) ||
send_fields(thd,fields,0) || send_item_params(stmt))
DBUG_RETURN(1);
DBUG_RETURN(0);
}
/*
Check the access privileges
*/
@ -505,42 +528,47 @@ static bool check_prepare_access(THD *thd, TABLE_LIST *tables,
Send the prepare query results back to client
*/
static void send_prepare_results(THD *thd)
static bool send_prepare_results(PREP_STMT *stmt)
{
DBUG_ENTER("send_prepare_results");
THD *thd= stmt->thd;
LEX *lex= &thd->lex;
enum enum_sql_command sql_command = thd->lex.sql_command;
DBUG_ENTER("send_prepare_results");
DBUG_PRINT("enter",("command: %d, param_count: %ld",
sql_command, lex->param_count));
DBUG_PRINT("enter",("command :%d, param_count :%ld",
sql_command,thd->param_count));
/* Setup prepared stmt */
stmt->param_count= lex->param_count;
stmt->free_list= thd->free_list; // Save items used in stmt
thd->free_list= 0;
LEX *lex=&thd->lex;
SELECT_LEX *select_lex = lex->select;
TABLE_LIST *tables=(TABLE_LIST*) select_lex->table_list.first;
switch(sql_command) {
switch (sql_command) {
case SQLCOM_INSERT:
if (mysql_test_insert_fields(thd,tables, lex->field_list,
if (mysql_test_insert_fields(stmt, tables, lex->field_list,
lex->many_values, lex->lock_option))
goto abort;
break;
case SQLCOM_UPDATE:
if (mysql_test_upd_fields(thd,tables, select_lex->item_list,
if (mysql_test_upd_fields(stmt, tables, select_lex->item_list,
lex->value_list, select_lex->where,
lex->lock_option))
goto abort;
break;
case SQLCOM_DELETE:
if (mysql_test_upd_fields(thd,tables, select_lex->item_list,
if (mysql_test_upd_fields(stmt, tables, select_lex->item_list,
lex->value_list, select_lex->where,
lex->lock_option))
goto abort;
break;
case SQLCOM_SELECT:
if (mysql_test_select_fields(thd,tables, select_lex->item_list,
if (mysql_test_select_fields(stmt, tables, select_lex->item_list,
lex->value_list, select_lex->where,
(ORDER*) select_lex->order_list.first,
(ORDER*) select_lex->group_list.first,
@ -556,42 +584,37 @@ static void send_prepare_results(THD *thd)
*/
}
}
send_ok(&thd->net,thd->param_count,0);
DBUG_VOID_RETURN;
DBUG_RETURN(0);
abort:
send_error(&thd->net,thd->killed ? ER_SERVER_SHUTDOWN : 0);
DBUG_VOID_RETURN;
send_error(thd,thd->killed ? ER_SERVER_SHUTDOWN : 0);
DBUG_RETURN(1);
}
/*
Parse the prepare query
*/
static void mysql_parse_prepare_query(THD *thd, char *packet, uint length)
static bool parse_prepare_query(PREP_STMT *stmt,
char *packet, uint length)
{
DBUG_ENTER("mysql_parse_prepare_query");
bool error= 1;
THD *thd= stmt->thd;
DBUG_ENTER("parse_prepare_query");
mysql_log.write(thd,COM_PREPARE,"%s",packet);
mysql_init_query(thd);
thd->prepare_command=true;
thd->safe_to_cache_query= 0;
if (query_cache.send_result_to_client(thd, packet, length) <= 0)
{
LEX *lex=lex_start(thd, (uchar*)packet, length);
if (!yyparse() && !thd->fatal_error)
{
send_prepare_results(thd);
query_cache_end_of_result(&thd->net);
}
else
query_cache_abort(&thd->net);
lex_end(lex);
}
DBUG_VOID_RETURN;
LEX *lex=lex_start(thd, (uchar*) packet, length);
if (!yyparse() && !thd->fatal_error)
error= send_prepare_results(stmt);
lex_end(lex);
DBUG_RETURN(error);
}
/*
Parse the query and send the total number of parameters
and resultset metadata information back to client (if any),
@ -606,52 +629,36 @@ static void mysql_parse_prepare_query(THD *thd, char *packet, uint length)
items.
*/
void mysql_com_prepare(THD *thd, char *packet, uint packet_length)
bool mysql_stmt_prepare(THD *thd, char *packet, uint packet_length)
{
MEM_ROOT thd_root = thd->mem_root;
DBUG_ENTER("mysql_com_prepare");
PREP_STMT stmt;
bool error;
DBUG_ENTER("mysql_stmt_prepare");
packet_length--;
bzero((char*) &stmt, sizeof(stmt));
stmt.thd= thd;
stmt.stmt_id= ++thd->current_stmt_id;
init_sql_alloc(&stmt.mem_root, 8192, 8192);
while (isspace(packet[0]) && packet_length > 0)
{
packet++;
packet_length--;
}
char *pos=packet+packet_length;
while (packet_length > 0 && (pos[-1] == ';' || isspace(pos[-1])))
{
pos--;
packet_length--;
}
/*
Have the prepare items to have a connection level scope or
till next prepare statement by doing all allocations using
connection level memory allocator 'con_root' from THD.
*/
free_root(&thd->con_root,MYF(0));
init_sql_alloc(&thd->con_root,8192,8192);
thd->mem_root = thd->con_root;
if (!(thd->query= (char*) thd->memdup_w_gap((gptr) (packet),
packet_length,
thd->db_length+2)))
DBUG_VOID_RETURN;
thd->query[packet_length]=0;
thd->packet.shrink(net_buffer_length);
thd->query_length = packet_length;
if (!(specialflag & SPECIAL_NO_PRIOR))
my_pthread_setprio(pthread_self(),QUERY_PRIOR);
mysql_parse_prepare_query(thd,thd->query,packet_length);
thd->mem_root= stmt.mem_root;
if (alloc_query(thd, packet, packet_length))
goto err;
if (parse_prepare_query(&stmt, thd->query, thd->query_length))
goto err;
if (!(specialflag & SPECIAL_NO_PRIOR))
my_pthread_setprio(pthread_self(),WAIT_PRIOR);
thd->mem_root = thd_root; // restore main mem_root
DBUG_PRINT("exit",("prepare query ready"));
DBUG_VOID_RETURN;
stmt.mem_root= thd->mem_root;
thd->mem_root= thd_root; // restore main mem_root
DBUG_RETURN(0);
err:
stmt.mem_root= thd->mem_root;
free_prep_stmt(&stmt, free_free, (void*) 0);
thd->mem_root = thd_root; // restore main mem_root
DBUG_RETURN(1);
}
@ -663,47 +670,166 @@ void mysql_com_prepare(THD *thd, char *packet, uint packet_length)
execute the query
*/
void mysql_com_execute(THD *thd)
void mysql_stmt_execute(THD *thd, char *packet)
{
MEM_ROOT thd_root=thd->mem_root;
DBUG_ENTER("mysql_com_execute");
DBUG_PRINT("enter", ("parameters : %ld", thd->param_count));
ulong stmt_id= uint4korr(packet);
PREP_STMT *stmt;
DBUG_ENTER("mysql_stmt_execute");
thd->mem_root = thd->con_root;
if (thd->param_count && setup_param_fields(thd, thd->lex.param_list))
if (!(stmt=find_prepared_statement(thd, stmt_id, "execute")))
{
send_error(thd);
DBUG_VOID_RETURN;
}
/* Check if we got an error when sending long data */
if (stmt->error_in_prepare)
{
send_error(thd);
DBUG_VOID_RETURN;
}
if (stmt->param_count && setup_param_fields(thd, stmt))
DBUG_VOID_RETURN;
MEM_ROOT thd_root= thd->mem_root;
thd->mem_root = thd->con_root;
if (!(specialflag & SPECIAL_NO_PRIOR))
my_pthread_setprio(pthread_self(),QUERY_PRIOR);
/* TODO:
/*
TODO:
Also, have checks on basic executions such as mysql_insert(),
mysql_delete(), mysql_update() and mysql_select() to not to
have re-check on setup_* and other things ..
*/
mysql_execute_command();
mysql_execute_command(thd);
if (!(specialflag & SPECIAL_NO_PRIOR))
my_pthread_setprio(pthread_self(),WAIT_PRIOR);
my_pthread_setprio(pthread_self(), WAIT_PRIOR);
thd->mem_root = (MEM_ROOT )thd_root;
DBUG_PRINT("exit",("prepare-execute done!"));
thd->mem_root= thd_root;
DBUG_VOID_RETURN;
}
/*
Reset a prepared statement
SYNOPSIS
mysql_stmt_reset()
thd Thread handle
packet Packet with stmt handle
DESCRIPTION
This function is useful when one gets an error after calling
mysql_stmt_getlongdata() and one wants to reset the handle
so that one can call execute again.
*/
void mysql_stmt_reset(THD *thd, char *packet)
{
ulong stmt_id= uint4korr(packet);
PREP_STMT *stmt;
DBUG_ENTER("mysql_stmt_reset");
if (!(stmt=find_prepared_statement(thd, stmt_id, "close")))
{
send_error(thd);
DBUG_VOID_RETURN;
}
stmt->error_in_prepare=0;
Item_param *item= stmt->param, *end= item + stmt->param_count;
/* Free long data if used */
if (stmt->long_data_used)
{
stmt->long_data_used= 0;
for (; item < end ; item++)
item->reset();
}
DBUG_VOID_RETURN;
}
/*
Delete a prepared statement from memory
*/
void mysql_stmt_close(THD *thd, char *packet)
{
ulong stmt_id= uint4korr(packet);
PREP_STMT *stmt;
DBUG_ENTER("mysql_stmt_close");
if (!(stmt=find_prepared_statement(thd, stmt_id, "close")))
{
send_error(thd);
DBUG_VOID_RETURN;
}
/* Will call free_prep_stmt() */
tree_delete(&thd->prepared_statements, (void*) stmt, NULL);
thd->last_prepared_stmt=0;
DBUG_VOID_RETURN;
}
/*
Long data in pieces from client
SYNOPSIS
mysql_stmt_get_longdata()
thd Thread handle
pos String to append
packet_length Length of string
DESCRIPTION
Get a part of a long data.
To make the protocol efficient, we are not sending any return packages
here.
If something goes wrong, then we will send the error on 'execute'
We assume that the client takes care of checking that all parts are sent
to the server. (No checking that we get a 'end of column' in the server)
*/
void mysql_com_longdata(THD *thd)
void mysql_stmt_get_longdata(THD *thd, char *pos, ulong packet_length)
{
DBUG_ENTER("mysql_com_execute");
PREP_STMT *stmt;
DBUG_ENTER("mysql_stmt_get_longdata");
if(thd->param_count && setup_longdata(thd,thd->lex.param_list))
/* The following should never happen */
if (packet_length < 9)
{
my_error(ER_WRONG_ARGUMENTS, MYF(0), "get_longdata");
DBUG_VOID_RETURN;
}
send_ok(&thd->net,0,0);// ok status to client
DBUG_PRINT("exit",("longdata-buffering done!"));
pos++; // skip command type at first position
ulong stmt_id= uint4korr(pos);
uint param_number= uint2korr(pos+4);
uint param_type= uint2korr(pos+6);
pos+=8; // Point to data
if (!(stmt=find_prepared_statement(thd, stmt_id, "get_longdata")))
{
/*
There is a chance that the client will never see this as
it doesn't expect an answer from this call...
*/
send_error(thd);
DBUG_VOID_RETURN;
}
if (param_number >= stmt->param_count)
{
stmt->error_in_prepare=1;
stmt->last_errno=ER_WRONG_ARGUMENTS;
sprintf(stmt->last_error, ER(ER_WRONG_ARGUMENTS), "get_longdata");
DBUG_VOID_RETURN;
}
stmt->param[param_number].set_longdata(pos, packet_length-9);
stmt->long_data_used= 1;
DBUG_VOID_RETURN;
}

View file

@ -97,7 +97,7 @@ end:
Query_log_event qinfo(thd, thd->query, thd->query_length);
mysql_bin_log.write(&qinfo);
}
send_ok(&thd->net);
send_ok(thd);
}
for (TABLE_LIST *table=table_list ; table != lock_table ; table=table->next)

View file

@ -283,11 +283,11 @@ binlog purge"; break;
if (errmsg)
{
send_error(&thd->net, 0, errmsg);
send_error(thd, 0, errmsg);
return 1;
}
else
send_ok(&thd->net);
send_ok(thd);
return 0;
}
@ -372,7 +372,7 @@ impossible position";
We need to start a packet with something other than 255
to distiquish it from error
*/
packet->set("\0", 1);
packet->set("\0", 1, system_charset_info);
// if we are at the start of the log
if (pos == BIN_LOG_HEADER_SIZE)
@ -383,7 +383,7 @@ impossible position";
my_errno= ER_MASTER_FATAL_ERROR_READING_BINLOG;
goto err;
}
packet->set("\0", 1);
packet->set("\0", 1, system_charset_info);
}
while (!net->error && net->vio != 0 && !thd->killed)
@ -418,7 +418,7 @@ impossible position";
goto err;
}
}
packet->set("\0", 1);
packet->set("\0", 1, system_charset_info);
}
/*
TODO: now that we are logging the offset, check to make sure
@ -538,7 +538,7 @@ Increase max_allowed_packet on master";
goto err;
}
}
packet->set("\0", 1);
packet->set("\0", 1, system_charset_info);
/*
No need to net_flush because we will get to flush later when
we hit EOF pretty quick
@ -593,7 +593,7 @@ Increase max_allowed_packet on master";
end_io_cache(&log);
(void)my_close(file, MYF(MY_WME));
send_eof(&thd->net);
send_eof(thd);
thd->proc_info = "waiting to finalize termination";
pthread_mutex_lock(&LOCK_thread_count);
thd->current_linfo = 0;
@ -615,15 +615,15 @@ Increase max_allowed_packet on master";
pthread_mutex_unlock(&LOCK_thread_count);
if (file >= 0)
(void) my_close(file, MYF(MY_WME));
send_error(&thd->net, my_errno, errmsg);
send_error(thd, my_errno, errmsg);
DBUG_VOID_RETURN;
}
int start_slave(THD* thd , MASTER_INFO* mi, bool net_report)
{
int slave_errno = 0;
if (!thd) thd = current_thd;
NET* net = &thd->net;
if (!thd)
thd = current_thd;
int thread_mask;
DBUG_ENTER("start_slave");
@ -654,20 +654,21 @@ int start_slave(THD* thd , MASTER_INFO* mi, bool net_report)
if (slave_errno)
{
if (net_report)
send_error(net, slave_errno);
send_error(thd, slave_errno);
DBUG_RETURN(1);
}
else if (net_report)
send_ok(net);
send_ok(thd);
DBUG_RETURN(0);
}
int stop_slave(THD* thd, MASTER_INFO* mi, bool net_report )
{
int slave_errno = 0;
if (!thd) thd = current_thd;
NET* net = &thd->net;
if (!thd)
thd = current_thd;
if (check_access(thd, SUPER_ACL, any_db))
return 1;
@ -686,11 +687,11 @@ int stop_slave(THD* thd, MASTER_INFO* mi, bool net_report )
if (slave_errno)
{
if (net_report)
send_error(net, slave_errno);
send_error(thd, slave_errno);
return 1;
}
else if (net_report)
send_ok(net);
send_ok(thd);
return 0;
}
@ -779,7 +780,7 @@ int change_master(THD* thd, MASTER_INFO* mi)
restart_thread_mask,
1 /*skip lock*/)))
{
send_error(&thd->net,error);
send_error(thd,error);
unlock_slave_threads(mi);
DBUG_RETURN(1);
}
@ -788,7 +789,7 @@ int change_master(THD* thd, MASTER_INFO* mi)
// TODO: see if needs re-write
if (init_master_info(mi, master_info_file, relay_log_info_file, 0))
{
send_error(&thd->net, 0, "Could not initialize master info");
send_error(thd, 0, "Could not initialize master info");
unlock_slave_threads(mi);
DBUG_RETURN(1);
}
@ -850,7 +851,7 @@ int change_master(THD* thd, MASTER_INFO* mi)
0 /* not only reset, but also reinit */,
&errmsg))
{
net_printf(&thd->net, 0, "Failed purging old relay logs: %s",errmsg);
net_printf(thd, 0, "Failed purging old relay logs: %s",errmsg);
DBUG_RETURN(1);
}
}
@ -864,7 +865,7 @@ int change_master(THD* thd, MASTER_INFO* mi)
0 /*no data lock*/,
&msg))
{
net_printf(&thd->net,0,"Failed initializing relay log position: %s",msg);
net_printf(thd,0,"Failed initializing relay log position: %s",msg);
unlock_slave_threads(mi);
DBUG_RETURN(1);
}
@ -890,9 +891,9 @@ int change_master(THD* thd, MASTER_INFO* mi)
unlock_slave_threads(mi);
thd->proc_info = 0;
if (error)
send_error(&thd->net,error);
send_error(thd,error);
else
send_ok(&thd->net);
send_ok(thd);
DBUG_RETURN(0);
}
@ -1010,12 +1011,12 @@ err:
if (errmsg)
{
net_printf(&thd->net, ER_ERROR_WHEN_EXECUTING_COMMAND,
net_printf(thd, ER_ERROR_WHEN_EXECUTING_COMMAND,
"SHOW BINLOG EVENTS", errmsg);
DBUG_RETURN(1);
}
send_eof(&thd->net);
send_eof(thd);
DBUG_RETURN(0);
}
@ -1045,7 +1046,7 @@ int show_binlog_info(THD* thd)
if (my_net_write(&thd->net, (char*)thd->packet.ptr(), packet->length()))
DBUG_RETURN(-1);
}
send_eof(&thd->net);
send_eof(thd);
DBUG_RETURN(0);
}
@ -1098,11 +1099,11 @@ int show_binlogs(THD* thd)
goto err;
}
mysql_bin_log.unlock_index();
send_eof(net);
send_eof(thd);
return 0;
err_with_msg:
send_error(net, 0, errmsg);
send_error(thd, ER_UNKNOWN_ERROR, errmsg);
err:
mysql_bin_log.unlock_index();
return 1;

View file

@ -164,13 +164,7 @@ int handle_select(THD *thd, LEX *lex, select_result *result)
for (TABLE_LIST *cursor= (TABLE_LIST *)sl->table_list.first;
cursor;
cursor=cursor->next)
{
if (cursor->do_redirect) // False if CUBE/ROLLUP
{
cursor->do_redirect=false;
cursor->table= ((TABLE_LIST*) cursor->table)->table;
}
}
cursor->table= ((TABLE_LIST*) cursor->table)->table;
}
}
@ -226,7 +220,7 @@ int
JOIN::prepare(TABLE_LIST *tables_init,
COND *conds_init, ORDER *order_init, ORDER *group_init,
Item *having_init,
ORDER *proc_param_init, SELECT_LEX *select_lex,
ORDER *proc_param_init, SELECT_LEX *select,
SELECT_LEX_UNIT *unit)
{
DBUG_ENTER("JOIN::prepare");
@ -237,7 +231,8 @@ JOIN::prepare(TABLE_LIST *tables_init,
having= having_init;
proc_param= proc_param_init;
tables_list= tables_init;
select->join= this;
select_lex= select;
select_lex->join= this;
union_part= (unit->first_select()->next_select() != 0);
/* Check that all tables, fields, conds and order are ok */
@ -679,16 +674,16 @@ JOIN::exec()
result->send_fields(fields_list,1);
if (!having || having->val_int())
{
if (do_send_rows && result->send_data(fields_list))
{
result->send_error(0,NullS); /* purecov: inspected */
error=1;
if (do_send_rows && result->send_data(fields_list))
{
result->send_error(0,NullS); /* purecov: inspected */
error=1;
}
else
error=(int) result->send_eof();
}
else
error=(int) result->send_eof();
}
else
error=(int) result->send_eof();
error=(int) result->send_eof();
}
delete procedure;
DBUG_VOID_RETURN;
@ -696,6 +691,7 @@ JOIN::exec()
if (zero_result_cause)
{
error=0;
(void) return_zero_rows(this, result, tables_list, fields_list,
tmp_table_param.sum_func_count != 0 &&
!group_list,
@ -739,7 +735,7 @@ JOIN::exec()
thd->proc_info="Creating tmp table";
tmp_table_param.hidden_field_count= (all_fields.elements-
fields.elements);
fields_list.elements);
if (!(exec_tmp_table =
create_tmp_table(thd, &tmp_table_param, all_fields,
((!simple_group && !procedure &&
@ -996,6 +992,8 @@ JOIN::exec()
int
JOIN::cleanup(THD *thd)
{
DBUG_ENTER("JOIN::cleanup");
lock=0; // It's faster to unlock later
join_free(this);
if (exec_tmp_table)
@ -1006,6 +1004,7 @@ JOIN::cleanup(THD *thd)
for (SELECT_LEX_UNIT *unit= select_lex->first_inner_unit();
unit != 0;
unit= unit->next_unit())
{
for (SELECT_LEX *sl= unit->first_select();
sl != 0;
sl= sl->next_select())
@ -1018,7 +1017,8 @@ JOIN::cleanup(THD *thd)
sl->join= 0;
}
}
return error;
}
DBUG_RETURN(error);
}
int
@ -1044,7 +1044,7 @@ mysql_select(THD *thd, TABLE_LIST *tables, List<Item> &fields, COND *conds,
goto err;
}
if(join->global_optimize())
if (join->global_optimize())
goto err;
join->exec();
@ -7276,7 +7276,8 @@ static void select_describe(JOIN *join, bool need_tmp_table, bool need_order,
{
KEY *key_info=table->key_info+ tab->ref.key;
item_list.push_back(new Item_string(key_info->name,
strlen(key_info->name)));
strlen(key_info->name),
system_charset_info));
item_list.push_back(new Item_int((int32) tab->ref.key_length));
for (store_key **ref=tab->ref.key_copy ; *ref ; ref++)
{
@ -7416,5 +7417,5 @@ static void describe_info(JOIN *join, const char *info)
packet->length(0);
net_store_data(packet,info);
if (!my_net_write(&thd->net,(char*) packet->ptr(),packet->length()))
send_eof(&thd->net);
send_eof(thd);
}

View file

@ -149,7 +149,8 @@ class TMP_TABLE_PARAM {
}
};
class JOIN :public Sql_alloc{
class JOIN :public Sql_alloc
{
public:
JOIN_TAB *join_tab,**best_ref,**map2table;
TABLE **table,**all_tables,*sort_by_table;
@ -222,6 +223,7 @@ class JOIN :public Sql_alloc{
!test(select_options & OPTION_FOUND_ROWS)),
all_fields(fields),
fields_list(fields),
error(0),
select(0),
exec_tmp_table(0),
test_function_query(0),

View file

@ -1,4 +1,4 @@
/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
/* Copyright (C) 2000 MySQL AB
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@ -76,6 +76,8 @@ mysqld_show_dbs(THD *thd,const char *wild)
if (mysql_find_files(thd,&files,NullS,mysql_data_home,wild,1))
DBUG_RETURN(1);
List_iterator_fast<char> it(files);
String *packet= &thd->packet;
while ((file_name=it++))
{
if (thd->master_access & (DB_ACLS | SHOW_DB_ACL) ||
@ -83,19 +85,20 @@ mysqld_show_dbs(THD *thd,const char *wild)
thd->priv_user, file_name) ||
(grant_option && !check_grant_db(thd, file_name)))
{
thd->packet.length(0);
net_store_data(&thd->packet, thd->variables.convert_set, file_name);
if (my_net_write(&thd->net, (char*) thd->packet.ptr(),
thd->packet.length()))
packet->length(0);
net_store_data(packet, thd->variables.convert_set, file_name);
if (my_net_write(&thd->net, (char*) packet->ptr(),
packet->length()))
DBUG_RETURN(-1);
}
}
send_eof(&thd->net);
send_eof(thd);
DBUG_RETURN(0);
}
/***************************************************************************
** List all open tables in a database
List all open tables in a database
***************************************************************************/
int mysqld_show_open_tables(THD *thd,const char *wild)
@ -116,19 +119,20 @@ int mysqld_show_open_tables(THD *thd,const char *wild)
if (!(open_list=list_open_tables(thd,wild)) && thd->fatal_error)
DBUG_RETURN(-1);
String *packet= &thd->packet;
for (; open_list ; open_list=open_list->next)
{
thd->packet.length(0);
net_store_data(&thd->packet,convert, open_list->db);
net_store_data(&thd->packet,convert, open_list->table);
net_store_data(&thd->packet,open_list->in_use);
net_store_data(&thd->packet,open_list->locked);
if (my_net_write(&thd->net,(char*) thd->packet.ptr(),thd->packet.length()))
packet->length(0);
net_store_data(packet,convert, open_list->db);
net_store_data(packet,convert, open_list->table);
net_store_data(packet,open_list->in_use);
net_store_data(packet,open_list->locked);
if (my_net_write(&thd->net,(char*) packet->ptr(),packet->length()))
{
DBUG_RETURN(-1);
}
}
send_eof(&thd->net);
send_eof(thd);
DBUG_RETURN(0);
}
@ -160,14 +164,15 @@ int mysqld_show_tables(THD *thd,const char *db,const char *wild)
if (mysql_find_files(thd,&files,db,path,wild,0))
DBUG_RETURN(-1);
List_iterator_fast<char> it(files);
String *packet= &thd->packet;
while ((file_name=it++))
{
thd->packet.length(0);
net_store_data(&thd->packet, thd->variables.convert_set, file_name);
if (my_net_write(&thd->net,(char*) thd->packet.ptr(),thd->packet.length()))
packet->length(0);
net_store_data(packet, thd->variables.convert_set, file_name);
if (my_net_write(&thd->net,(char*) packet->ptr(),packet->length()))
DBUG_RETURN(-1);
}
send_eof(&thd->net);
send_eof(thd);
DBUG_RETURN(0);
}
@ -175,15 +180,33 @@ int mysqld_show_tables(THD *thd,const char *db,const char *wild)
** List all table types supported
***************************************************************************/
static struct show_table_type_st sys_table_types[]= {
{"MyISAM", (char *)"YES", "Default type from 3.23 with great performance"},
{"HEAP" , (char *)"YES", "Hash based, stored in memory, useful for temporary tables"},
{"MERGE", (char *)"YES", "Collection of identical MyISAM tables"},
{"ISAM", (char*) &have_isam,"Obsolete table type"},
{"InnoDB", (char*) &have_innodb,"Supports transactions, row-level locking and foreign keys"},
{"BDB", (char*) &have_berkeley_db, "Supports transactions and page-level locking"},
struct show_table_type_st {
const char *type;
SHOW_COMP_OPTION *value;
const char *comment;
};
SHOW_COMP_OPTION have_yes= SHOW_OPTION_YES;
static struct show_table_type_st sys_table_types[]=
{
{"MyISAM", &have_yes,
"Default type from 3.23 with great performance"},
{"HEAP" , &have_yes,
"Hash based, stored in memory, useful for temporary tables"},
{"MERGE", &have_yes,
"Collection of identical MyISAM tables"},
{"ISAM", &have_isam,
"Obsolete table type; Is replaced by MyISAM"},
{"InnoDB", &have_innodb,
"Supports transactions, row-level locking and foreign keys"},
{"BDB", &have_berkeley_db,
"Supports transactions and page-level locking"},
{NullS, NULL, NullS}
};
int mysqld_show_table_types(THD *thd)
{
List<Item> field_list;
@ -191,76 +214,68 @@ int mysqld_show_table_types(THD *thd)
field_list.push_back(new Item_empty_string("Type",10));
field_list.push_back(new Item_empty_string("Support",10));
field_list.push_back(new Item_empty_string("Comment",NAME_LEN));
field_list.push_back(new Item_empty_string("Comment",80));
if (send_fields(thd,field_list,1))
DBUG_RETURN(1);
const char *default_type_name=ha_table_typelib.type_names[default_table_type-1];
show_table_type_st *types = sys_table_types;
const char *default_type_name= ha_table_typelib.type_names[thd->variables.table_type];
uint i;
for (i = 0; i < 3; i++)
show_table_type_st *types;
String *packet= &thd->packet;
for (types= sys_table_types; types->type; types++)
{
thd->packet.length(0);
net_store_data(&thd->packet,types[i].type);
if (!strcasecmp(default_type_name,types[i].type))
net_store_data(&thd->packet,"DEFAULT");
else
net_store_data(&thd->packet,types[i].value);
net_store_data(&thd->packet,types[i].comment);
if (my_net_write(&thd->net,(char*) thd->packet.ptr(),thd->packet.length()))
packet->length(0);
net_store_data(packet, types->type);
const char *option_name= show_comp_option_name[(int) *types->value];
if (*types->value == SHOW_OPTION_YES &&
!strcasecmp(default_type_name, types->type))
option_name= "DEFAULT";
net_store_data(packet, option_name);
net_store_data(packet, types->comment);
if (my_net_write(&thd->net, (char*) packet->ptr(), packet->length()))
DBUG_RETURN(-1);
}
for (; i < sizeof(sys_table_types)/sizeof(sys_table_types[0]); i++)
{
thd->packet.length(0);
net_store_data(&thd->packet,types[i].type);
SHOW_COMP_OPTION tmp= *(SHOW_COMP_OPTION*) types[i].value;
if (tmp == SHOW_OPTION_NO)
net_store_data(&thd->packet,"NO");
else
{
if (tmp == SHOW_OPTION_YES)
{
if (!strcasecmp(default_type_name,types[i].type))
net_store_data(&thd->packet,"DEFAULT");
else
net_store_data(&thd->packet,"YES");
}
else net_store_data(&thd->packet,"DISABLED");
}
net_store_data(&thd->packet,types[i].comment);
if (my_net_write(&thd->net,(char*) thd->packet.ptr(),thd->packet.length()))
DBUG_RETURN(-1);
}
send_eof(&thd->net);
send_eof(thd);
DBUG_RETURN(0);
}
/***************************************************************************
** List all privileges supported
List all privileges supported
***************************************************************************/
static struct show_table_type_st sys_privileges[]= {
{"Select", (char *)"Tables", "To retrieve rows from table"},
{"Insert", (char *)"Tables", "To insert data into tables"},
{"Update", (char *)"Tables", "To update existing rows "},
{"Delete", (char *)"Tables", "To delete existing rows"},
{"Index", (char *)"Tables", "To create or drop indexes"},
{"Alter", (char *)"Tables", "To alter the table"},
{"Create", (char *)"Databases,Tables,Indexes", "To create new databases and tables"},
{"Drop", (char *)"Databases,Tables", "To drop databases and tables"},
{"Grant", (char *)"Databases,Tables", "To give to other users those privileges you possesed"},
{"References", (char *)"Databases,Tables", "To have references on tables"},
{"Reload", (char *)"Server Admin", "To reload or refresh tables, logs and privileges"},
{"Shutdown",(char *)"Server Admin", "To shutdown the server"},
{"Process", (char *)"Server Admin", "To view the plain text of currently executing queries"},
{"File", (char *)"File access on server", "To read and write files on the server"},
struct show_privileges_st {
const char *privilege;
const char *context;
const char *comment;
};
/*
TODO: Update with new privileges
*/
static struct show_privileges_st sys_privileges[]=
{
{"Select", "Tables", "To retrieve rows from table"},
{"Insert", "Tables", "To insert data into tables"},
{"Update", "Tables", "To update existing rows "},
{"Delete", "Tables", "To delete existing rows"},
{"Index", "Tables", "To create or drop indexes"},
{"Alter", "Tables", "To alter the table"},
{"Create", "Databases,Tables,Indexes", "To create new databases and tables"},
{"Drop", "Databases,Tables", "To drop databases and tables"},
{"Grant", "Databases,Tables", "To give to other users those privileges you possess"},
{"References", "Databases,Tables", "To have references on tables"},
{"Reload", "Server Admin", "To reload or refresh tables, logs and privileges"},
{"Shutdown","Server Admin", "To shutdown the server"},
{"Process", "Server Admin", "To view the plain text of currently executing queries"},
{"File", "File access on server", "To read and write files on the server"},
{NullS, NullS, NullS}
};
int mysqld_show_privileges(THD *thd)
{
List<Item> field_list;
@ -273,43 +288,48 @@ int mysqld_show_privileges(THD *thd)
if (send_fields(thd,field_list,1))
DBUG_RETURN(1);
for (uint i=0; i < sizeof(sys_privileges)/sizeof(sys_privileges[0]); i++)
show_privileges_st *privilege= sys_privileges;
String *packet= &thd->packet;
for (privilege= sys_privileges; privilege->privilege ; privilege++)
{
thd->packet.length(0);
net_store_data(&thd->packet,sys_privileges[i].type);
net_store_data(&thd->packet,sys_privileges[i].value);
net_store_data(&thd->packet,sys_privileges[i].comment);
if (my_net_write(&thd->net,(char*) thd->packet.ptr(),thd->packet.length()))
packet->length(0);
net_store_data(packet,privilege->privilege);
net_store_data(packet,privilege->context);
net_store_data(packet,privilege->comment);
if (my_net_write(&thd->net,(char*) packet->ptr(),packet->length()))
DBUG_RETURN(-1);
}
send_eof(&thd->net);
send_eof(thd);
DBUG_RETURN(0);
}
/***************************************************************************
** List all column types
List all column types
***************************************************************************/
#if 0
struct show_column_type_st {
struct show_column_type_st
{
const char *type;
uint size;
char *min_value;
char *max_value;
uint precision,
uint scale,
char *nullable;
char *auto_increment;
char *unsigned_attr;
char *zerofill;
char *searchable;
char *case_sensitivity;
char *default_value;
char *comment;
const char *min_value;
const char *max_value;
uint precision;
uint scale;
const char *nullable;
const char *auto_increment;
const char *unsigned_attr;
const char *zerofill;
const char *searchable;
const char *case_sensitivity;
const char *default_value;
const char *comment;
};
#endif
static struct show_column_type_st sys_column_types[]= {
/* TODO: Add remaning types */
static struct show_column_type_st sys_column_types[]=
{
{"tinyint",
1, "-128", "127", 0, 0, "YES", "YES",
"NO", "YES", "YES", "NO", "NULL,0",
@ -343,30 +363,33 @@ int mysqld_show_column_types(THD *thd)
if (send_fields(thd,field_list,1))
DBUG_RETURN(1);
/* TODO: Change the loop to not use 'i' */
String *packet= &thd->packet;
for (uint i=0; i < sizeof(sys_column_types)/sizeof(sys_column_types[0]); i++)
{
thd->packet.length(0);
net_store_data(&thd->packet,sys_column_types[i].type);
net_store_data(&thd->packet,(longlong)sys_column_types[i].size);
net_store_data(&thd->packet,sys_column_types[i].min_value);
net_store_data(&thd->packet,sys_column_types[i].max_value);
net_store_data(&thd->packet,(uint32)sys_column_types[i].precision);
net_store_data(&thd->packet,(uint32)sys_column_types[i].scale);
net_store_data(&thd->packet,sys_column_types[i].nullable);
net_store_data(&thd->packet,sys_column_types[i].auto_increment);
net_store_data(&thd->packet,sys_column_types[i].unsigned_attr);
net_store_data(&thd->packet,sys_column_types[i].zerofill);
net_store_data(&thd->packet,sys_column_types[i].searchable);
net_store_data(&thd->packet,sys_column_types[i].case_sensitivity);
net_store_data(&thd->packet,sys_column_types[i].default_value);
net_store_data(&thd->packet,sys_column_types[i].comment);
if (my_net_write(&thd->net,(char*) thd->packet.ptr(),thd->packet.length()))
packet->length(0);
net_store_data(packet,sys_column_types[i].type);
net_store_data(packet,(longlong)sys_column_types[i].size);
net_store_data(packet,sys_column_types[i].min_value);
net_store_data(packet,sys_column_types[i].max_value);
net_store_data(packet,(uint32)sys_column_types[i].precision);
net_store_data(packet,(uint32)sys_column_types[i].scale);
net_store_data(packet,sys_column_types[i].nullable);
net_store_data(packet,sys_column_types[i].auto_increment);
net_store_data(packet,sys_column_types[i].unsigned_attr);
net_store_data(packet,sys_column_types[i].zerofill);
net_store_data(packet,sys_column_types[i].searchable);
net_store_data(packet,sys_column_types[i].case_sensitivity);
net_store_data(packet,sys_column_types[i].default_value);
net_store_data(packet,sys_column_types[i].comment);
if (my_net_write(&thd->net,(char*) packet->ptr(),packet->length()))
DBUG_RETURN(-1);
}
send_eof(&thd->net);
send_eof(thd);
DBUG_RETURN(0);
}
static int
mysql_find_files(THD *thd,List<char> *files, const char *db,const char *path,
const char *wild, bool dir)
@ -441,8 +464,9 @@ mysql_find_files(THD *thd,List<char> *files, const char *db,const char *path,
DBUG_RETURN(0);
}
/***************************************************************************
** Extended version of mysqld_show_tables
Extended version of mysqld_show_tables
***************************************************************************/
int mysqld_extend_show_tables(THD *thd,const char *db,const char *wild)
@ -459,7 +483,6 @@ int mysqld_extend_show_tables(THD *thd,const char *db,const char *wild)
(void) sprintf(path,"%s/%s",mysql_data_home,db);
(void) unpack_dirname(path,path);
//,default_charset_info
field_list.push_back(item=new Item_empty_string("Name",NAME_LEN));
item->maybe_null=1;
field_list.push_back(item=new Item_empty_string("Type",10));
@ -612,14 +635,13 @@ int mysqld_extend_show_tables(THD *thd,const char *db,const char *wild)
packet->length()))
DBUG_RETURN(-1);
}
send_eof(&thd->net);
send_eof(thd);
DBUG_RETURN(0);
}
/***************************************************************************
** List all columns in a table
List all columns in a table
***************************************************************************/
int
@ -637,7 +659,7 @@ mysqld_show_fields(THD *thd, TABLE_LIST *table_list,const char *wild,
if (!(table = open_ltable(thd, table_list, TL_UNLOCK)))
{
send_error(&thd->net);
send_error(thd);
DBUG_RETURN(1);
}
file=table->file;
@ -742,10 +764,11 @@ mysqld_show_fields(THD *thd, TABLE_LIST *table_list,const char *wild,
}
}
}
send_eof(&thd->net);
send_eof(thd);
DBUG_RETURN(0);
}
int
mysqld_show_create(THD *thd, TABLE_LIST *table_list)
{
@ -758,7 +781,7 @@ mysqld_show_create(THD *thd, TABLE_LIST *table_list)
/* Only one table for now */
if (!(table = open_ltable(thd, table_list, TL_UNLOCK)))
{
send_error(&thd->net);
send_error(thd);
DBUG_RETURN(1);
}
@ -809,7 +832,7 @@ mysqld_show_create(THD *thd, TABLE_LIST *table_list)
if (my_net_write(&thd->net, (char*)packet->ptr(), packet->length()))
DBUG_RETURN(1);
}
send_eof(&thd->net);
send_eof(thd);
DBUG_RETURN(0);
}
@ -832,7 +855,7 @@ mysqld_show_logs(THD *thd)
DBUG_RETURN(-1);
#endif
send_eof(&thd->net);
send_eof(thd);
DBUG_RETURN(0);
}
@ -849,7 +872,7 @@ mysqld_show_keys(THD *thd, TABLE_LIST *table_list)
if (!(table = open_ltable(thd, table_list, TL_UNLOCK)))
{
send_error(&thd->net);
send_error(thd);
DBUG_RETURN(1);
}
@ -933,14 +956,14 @@ mysqld_show_keys(THD *thd, TABLE_LIST *table_list)
DBUG_RETURN(1); /* purecov: inspected */
}
}
send_eof(&thd->net);
send_eof(thd);
DBUG_RETURN(0);
}
/****************************************************************************
** Return only fields for API mysql_list_fields
** Use "show table wildcard" in mysql instead of this
Return only fields for API mysql_list_fields
Use "show table wildcard" in mysql instead of this
****************************************************************************/
void
@ -952,7 +975,7 @@ mysqld_list_fields(THD *thd, TABLE_LIST *table_list, const char *wild)
if (!(table = open_ltable(thd, table_list, TL_UNLOCK)))
{
send_error(&thd->net);
send_error(thd);
DBUG_VOID_RETURN;
}
List<Item> field_list;
@ -971,6 +994,7 @@ mysqld_list_fields(THD *thd, TABLE_LIST *table_list, const char *wild)
DBUG_VOID_RETURN;
}
int
mysqld_dump_create_info(THD *thd, TABLE *table, int fd)
{
@ -978,7 +1002,7 @@ mysqld_dump_create_info(THD *thd, TABLE *table, int fd)
DBUG_ENTER("mysqld_dump_create_info");
DBUG_PRINT("enter",("table: %s",table->real_name));
String* packet = &thd->packet;
String *packet = &thd->packet;
packet->length(0);
if (store_create_info(thd,table,packet))
DBUG_RETURN(-1);
@ -1000,6 +1024,7 @@ mysqld_dump_create_info(THD *thd, TABLE *table, int fd)
DBUG_RETURN(0);
}
static void
append_identifier(THD *thd, String *packet, const char *name)
{
@ -1015,6 +1040,7 @@ append_identifier(THD *thd, String *packet, const char *name)
}
}
static int
store_create_info(THD *thd, TABLE *table, String *packet)
{
@ -1215,8 +1241,8 @@ store_create_info(THD *thd, TABLE *table, String *packet)
/****************************************************************************
** Return info about all processes
** returns for each thread: thread id, user, host, db, command, info
Return info about all processes
returns for each thread: thread id, user, host, db, command, info
****************************************************************************/
class thread_info :public ilink {
@ -1357,7 +1383,7 @@ void mysqld_list_processes(THD *thd,const char *user, bool verbose)
if (my_net_write(&thd->net,(char*) packet->ptr(),packet->length()))
break; /* purecov: inspected */
}
send_eof(&thd->net);
send_eof(thd);
DBUG_VOID_RETURN;
}
@ -1372,7 +1398,7 @@ int mysqld_show_charsets(THD *thd, const char *wild)
char buff[8192];
String packet2(buff,sizeof(buff),default_charset_info);
List<Item> field_list;
CONVERT *convert=thd->convert_set;
CONVERT *convert=thd->variables.convert_set;
CHARSET_INFO *cs;
DBUG_ENTER("mysqld_show_charsets");
@ -1401,7 +1427,7 @@ int mysqld_show_charsets(THD *thd, const char *wild)
goto err;
}
}
send_eof(&thd->net);
send_eof(thd);
DBUG_RETURN(0);
err:
DBUG_RETURN(1);
@ -1428,7 +1454,7 @@ int mysqld_show(THD *thd, const char *wild, show_var_st *variables,
for (; variables->name; variables++)
{
if (!(wild && wild[0] && wild_case_compare(system_charset_info,
variables[i].name,wild)))
variables->name,wild)))
{
packet2.length(0);
net_store_data(&packet2,convert,variables->name);
@ -1461,9 +1487,7 @@ int mysqld_show(THD *thd, const char *wild, show_var_st *variables,
case SHOW_HAVE:
{
SHOW_COMP_OPTION tmp= *(SHOW_COMP_OPTION*) value;
net_store_data(&packet2, (tmp == SHOW_OPTION_NO ? "NO" :
tmp == SHOW_OPTION_YES ? "YES" :
"DISABLED"));
net_store_data(&packet2, show_comp_option_name[(int) tmp]);
break;
}
case SHOW_CHAR:
@ -1663,7 +1687,7 @@ int mysqld_show(THD *thd, const char *wild, show_var_st *variables,
}
pthread_mutex_unlock(&LOCK_status);
/* pthread_mutex_unlock(&THR_LOCK_keycache); */
send_eof(&thd->net);
send_eof(thd);
DBUG_RETURN(0);
err:

View file

@ -82,7 +82,7 @@ int mysql_rm_table(THD *thd,TABLE_LIST *tables, my_bool if_exists)
if (error)
DBUG_RETURN(-1);
send_ok(&thd->net);
send_ok(thd);
DBUG_RETURN(0);
}
@ -305,8 +305,7 @@ int mysql_create_table(THD *thd,const char *db, const char *table_name,
DBUG_RETURN(-1);
}
for(field_no=0; (sql_field=it++) ; field_no++)
for (field_no=0; (sql_field=it++) ; field_no++)
{
/* Don't pack keys in old tables if the user has requested this */
if ((sql_field->flags & BLOB_FLAG) ||
@ -317,28 +316,35 @@ int mysql_create_table(THD *thd,const char *db, const char *table_name,
}
if (!(sql_field->flags & NOT_NULL_FLAG))
null_fields++;
for(dup_no=0; (dup_field=it2++) != sql_field; dup_no++)
/* Check if we have used the same field name before */
for (dup_no=0; (dup_field=it2++) != sql_field; dup_no++)
{
if (my_strcasecmp(system_charset_info,
sql_field->field_name,
dup_field->field_name) == 0)
{
if (field_no<select_field_pos || dup_no>=select_field_pos)
/*
If this was a CREATE ... SELECT statement, accept a field
redefinition if we are changing a field in the SELECT part
*/
if (field_no < select_field_pos || dup_no >= select_field_pos)
{
my_error(ER_DUP_FIELDNAME,MYF(0),sql_field->field_name);
DBUG_RETURN(-1);
}
else
{
sql_field->length=dup_field->length;
sql_field->decimals=dup_field->decimals;
sql_field->flags=dup_field->flags;
sql_field->pack_length=dup_field->pack_length;
sql_field->unireg_check=dup_field->unireg_check;
sql_field->sql_type=dup_field->sql_type;
it2.remove();
select_field_pos--;
break;
/* Field redefined */
sql_field->length= dup_field->length;
sql_field->decimals= dup_field->decimals;
sql_field->flags= dup_field->flags;
sql_field->pack_length= dup_field->pack_length;
sql_field->unireg_check= dup_field->unireg_check;
sql_field->sql_type= dup_field->sql_type;
it2.remove(); // Remove first (create) definition
select_field_pos--;
break;
}
}
}
@ -749,7 +755,7 @@ int mysql_create_table(THD *thd,const char *db, const char *table_name,
create_info->create_statement = thd->query;
create_info->table_options=db_options;
if (rea_create_table(path, create_info, fields, key_count,
if (rea_create_table(thd, path, create_info, fields, key_count,
key_info_buffer))
{
/* my_error(ER_CANT_CREATE_TABLE,MYF(0),table_name,my_errno); */
@ -825,7 +831,7 @@ TABLE *create_table_from_items(THD *thd, HA_CREATE_INFO *create_info,
TABLE tmp_table; // Used during 'create_field()'
TABLE *table;
tmp_table.table_name=0;
uint select_field_count=0;
uint select_field_count= items->elements;
DBUG_ENTER("create_table_from_items");
/* Add selected items to field list */
@ -859,7 +865,6 @@ TABLE *create_table_from_items(THD *thd, HA_CREATE_INFO *create_info,
(Field*) 0))))
DBUG_RETURN(0);
extra_fields->push_back(cr_field);
select_field_count++;
}
/* create and lock table */
/* QQ: This should be done atomic ! */
@ -1271,7 +1276,7 @@ static int mysql_admin_table(THD* thd, TABLE_LIST* tables,
goto err;
}
send_eof(&thd->net);
send_eof(thd);
DBUG_RETURN(0);
err:
close_thread_tables(thd); // Shouldn't be needed
@ -1476,7 +1481,7 @@ int mysql_alter_table(THD *thd,char *new_db, char *new_name,
Query_log_event qinfo(thd, thd->query, thd->query_length);
mysql_bin_log.write(&qinfo);
}
send_ok(&thd->net);
send_ok(thd);
}
DBUG_RETURN(error);
}
@ -1994,7 +1999,7 @@ int mysql_alter_table(THD *thd,char *new_db, char *new_name,
end_temporary:
sprintf(tmp_name,ER(ER_INSERT_INFO),(ulong) (copied+deleted),
(ulong) deleted, thd->cuted_fields);
send_ok(&thd->net,copied+deleted,0L,tmp_name);
send_ok(thd,copied+deleted,0L,tmp_name);
thd->some_tables_deleted=0;
DBUG_RETURN(0);

View file

@ -342,7 +342,7 @@ int mysql_create_function(THD *thd,udf_func *udf)
if (!initialized)
{
send_error(&thd->net, ER_OUT_OF_RESOURCES, ER(ER_OUT_OF_RESOURCES));
send_error(thd, ER_OUT_OF_RESOURCES, ER(ER_OUT_OF_RESOURCES));
DBUG_RETURN(1);
}
@ -353,19 +353,19 @@ int mysql_create_function(THD *thd,udf_func *udf)
*/
if (strchr(udf->dl, '/'))
{
send_error(&thd->net, ER_UDF_NO_PATHS,ER(ER_UDF_NO_PATHS));
send_error(thd, ER_UDF_NO_PATHS,ER(ER_UDF_NO_PATHS));
DBUG_RETURN(1);
}
if (udf->name_length > NAME_LEN)
{
net_printf(&thd->net, ER_TOO_LONG_IDENT,udf->name);
net_printf(thd, ER_TOO_LONG_IDENT,udf->name);
DBUG_RETURN(1);
}
pthread_mutex_lock(&THR_LOCK_udf);
if (hash_search(&udf_hash,(byte*) udf->name, udf->name_length))
{
net_printf(&thd->net, ER_UDF_EXISTS, udf->name);
net_printf(thd, ER_UDF_EXISTS, udf->name);
goto err;
}
if (!(dl = find_udf_dl(udf->dl)))
@ -374,7 +374,7 @@ int mysql_create_function(THD *thd,udf_func *udf)
{
DBUG_PRINT("error",("dlopen of %s failed, error: %d (%s)",
udf->dl,errno,dlerror()));
net_printf(&thd->net, ER_CANT_OPEN_LIBRARY, udf->dl, errno, dlerror());
net_printf(thd, ER_CANT_OPEN_LIBRARY, udf->dl, errno, dlerror());
goto err;
}
new_dl=1;
@ -384,7 +384,7 @@ int mysql_create_function(THD *thd,udf_func *udf)
if (udf->func == NULL)
{
net_printf(&thd->net, ER_CANT_FIND_DL_ENTRY, udf->name);
net_printf(thd, ER_CANT_FIND_DL_ENTRY, udf->name);
goto err;
}
udf->name=strdup_root(&mem,udf->name);
@ -392,7 +392,7 @@ int mysql_create_function(THD *thd,udf_func *udf)
if (!udf->name || !udf->dl ||
!(u_d=add_udf(udf->name,udf->returns,udf->dl,udf->type)))
{
send_error(&thd->net,0); // End of memory
send_error(thd,0); // End of memory
goto err;
}
u_d->dlhandle = dl;
@ -422,7 +422,7 @@ int mysql_create_function(THD *thd,udf_func *udf)
close_thread_tables(thd);
if (error)
{
net_printf(&thd->net, ER_ERROR_ON_WRITE, "func@mysql",error);
net_printf(thd, ER_ERROR_ON_WRITE, "func@mysql",error);
del_udf(u_d);
goto err;
}
@ -445,13 +445,13 @@ int mysql_drop_function(THD *thd,const char *udf_name)
DBUG_ENTER("mysql_drop_function");
if (!initialized)
{
send_error(&thd->net, ER_OUT_OF_RESOURCES, ER(ER_OUT_OF_RESOURCES));
send_error(thd, ER_OUT_OF_RESOURCES, ER(ER_OUT_OF_RESOURCES));
DBUG_RETURN(1);
}
pthread_mutex_lock(&THR_LOCK_udf);
if (!(udf=(udf_func*) hash_search(&udf_hash,(byte*) udf_name, (uint) strlen(udf_name))))
{
net_printf(&thd->net, ER_FUNCTION_NOT_DEFINED, udf_name);
net_printf(thd, ER_FUNCTION_NOT_DEFINED, udf_name);
goto err;
}
del_udf(udf);

View file

@ -242,7 +242,7 @@ bool select_union::flush()
if ((error=table->file->extra(HA_EXTRA_NO_CACHE)))
{
table->file->print_error(error,MYF(0));
::send_error(&thd->net);
::send_error(thd);
return 1;
}
return 0;

View file

@ -127,7 +127,7 @@ int mysql_update(THD *thd,
{
DBUG_RETURN(-1); // Error in where
}
send_ok(&thd->net); // No matching records
send_ok(thd); // No matching records
DBUG_RETURN(0);
}
/* If running in safe sql mode, don't allow updates without keys */
@ -138,7 +138,7 @@ int mysql_update(THD *thd,
{
delete select;
table->time_stamp=save_time_stamp;
send_error(&thd->net,ER_UPDATE_WITHOUT_KEY_IN_SAFE_MODE);
send_error(thd,ER_UPDATE_WITHOUT_KEY_IN_SAFE_MODE);
DBUG_RETURN(1);
}
}
@ -329,13 +329,13 @@ int mysql_update(THD *thd,
delete select;
if (error >= 0)
send_error(&thd->net,thd->killed ? ER_SERVER_SHUTDOWN : 0); /* purecov: inspected */
send_error(thd,thd->killed ? ER_SERVER_SHUTDOWN : 0); /* purecov: inspected */
else
{
char buff[80];
sprintf(buff,ER(ER_UPDATE_INFO), (long) found, (long) updated,
(long) thd->cuted_fields);
send_ok(&thd->net,
send_ok(thd,
(thd->client_capabilities & CLIENT_FOUND_ROWS) ? found : updated,
thd->insert_id_used ? thd->insert_id() : 0L,buff);
DBUG_PRINT("info",("%d records updated",updated));
@ -439,7 +439,7 @@ multi_update::prepare(List<Item> &values, SELECT_LEX_UNIT *u)
}
if (!table_ref)
{
net_printf(&thd->net, ER_NOT_SUPPORTED_YET, "JOIN SYNTAX WITH MULTI-TABLE UPDATES");
net_printf(thd, ER_NOT_SUPPORTED_YET, "JOIN SYNTAX WITH MULTI-TABLE UPDATES");
DBUG_RETURN(1);
}
else
@ -447,7 +447,7 @@ multi_update::prepare(List<Item> &values, SELECT_LEX_UNIT *u)
}
if (!num_updated)
{
net_printf(&thd->net, ER_NOT_SUPPORTED_YET, "SET CLAUSE MUST CONTAIN TABLE.FIELD REFERENCE");
net_printf(thd, ER_NOT_SUPPORTED_YET, "SET CLAUSE MUST CONTAIN TABLE.FIELD REFERENCE");
DBUG_RETURN(1);
}
@ -662,7 +662,7 @@ bool multi_update::send_data(List<Item> &values)
void multi_update::send_error(uint errcode,const char *err)
{
/* First send error what ever it is ... */
::send_error(&thd->net,errcode,err);
::send_error(thd,errcode,err);
/* reset used flags */
// update_tables->table->no_keyread=0;
@ -821,7 +821,7 @@ bool multi_update::send_eof()
{
query_cache_invalidate3(thd, update_tables, 1);
}
::send_ok(&thd->net,
::send_ok(thd,
(thd->client_capabilities & CLIENT_FOUND_ROWS) ? found : updated,
thd->insert_id_used ? thd->insert_id() : 0L,buff);
}

Some files were not shown because too many files have changed in this diff Show more