mirror of
https://github.com/MariaDB/server.git
synced 2026-05-16 20:07:13 +02:00
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:
parent
7134ffec21
commit
d69250a969
108 changed files with 3026 additions and 2916 deletions
|
|
@ -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
|
||||
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
131
include/mysql.h
131
include/mysql.h
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
|
|
|
|||
|
|
@ -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; \
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
||||
|
|
|
|||
1445
libmysql/libmysql.c
1445
libmysql/libmysql.c
File diff suppressed because it is too large
Load diff
|
|
@ -104,8 +104,8 @@ EXPORTS
|
|||
mysql_rpl_probe
|
||||
mysql_set_master
|
||||
mysql_add_slave
|
||||
|
||||
|
||||
mysql_warning_count
|
||||
mysql_warnings
|
||||
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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");
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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",
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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.
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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));
|
||||
|
|
|
|||
|
|
@ -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];
|
||||
|
|
|
|||
25
mysys/tree.c
25
mysys/tree.c
|
|
@ -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"
|
||||
|
|
|
|||
64
sql/field.cc
64
sql/field.cc
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -3557,7 +3557,7 @@ innodb_show_status(
|
|||
|
||||
ut_free(buf);
|
||||
|
||||
send_eof(&thd->net);
|
||||
send_eof(thd);
|
||||
|
||||
DBUG_RETURN(0);
|
||||
}
|
||||
|
|
|
|||
73
sql/item.cc
73
sql/item.cc
|
|
@ -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();
|
||||
|
|
|
|||
35
sql/item.h
35
sql/item.h
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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.
|
||||
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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);}
|
||||
};
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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:
|
||||
|
|
|
|||
|
|
@ -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},
|
||||
|
|
|
|||
37
sql/log.cc
37
sql/log.cc
|
|
@ -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,
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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 */
|
||||
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
|
|
|
|||
172
sql/net_pkg.cc
172
sql/net_pkg.cc
|
|
@ -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;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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));
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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(¤t_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;
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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",
|
||||
|
|
|
|||
|
|
@ -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",
|
||||
|
|
|
|||
|
|
@ -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",
|
||||
|
|
|
|||
|
|
@ -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",
|
||||
|
|
|
|||
|
|
@ -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",
|
||||
|
|
|
|||
|
|
@ -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",
|
||||
|
|
|
|||
|
|
@ -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",
|
||||
|
|
|
|||
|
|
@ -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",
|
||||
|
|
|
|||
|
|
@ -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",
|
||||
|
|
|
|||
|
|
@ -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",
|
||||
|
|
|
|||
|
|
@ -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",
|
||||
|
|
|
|||
|
|
@ -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",
|
||||
|
|
|
|||
47
sql/slave.cc
47
sql/slave.cc
|
|
@ -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)))
|
||||
|
|
|
|||
141
sql/spatial.h
141
sql/spatial.h
|
|
@ -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;
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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 */
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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() {}
|
||||
|
|
|
|||
367
sql/sql_db.cc
367
sql/sql_db.cc
|
|
@ -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);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
|
|
|
|||
244
sql/sql_error.cc
244
sql/sql_error.cc
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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())
|
||||
{
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
117
sql/sql_list.h
117
sql/sql_list.h
|
|
@ -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(); }
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
364
sql/sql_parse.cc
364
sql/sql_parse.cc
File diff suppressed because it is too large
Load diff
|
|
@ -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> ¶ms);
|
||||
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> ¶ms);
|
||||
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> ¶ms)
|
||||
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> ¶ms)
|
|||
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> ¶ms)
|
||||
{
|
||||
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;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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),
|
||||
|
|
|
|||
316
sql/sql_show.cc
316
sql/sql_show.cc
|
|
@ -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:
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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
Loading…
Add table
Add a link
Reference in a new issue