Merge bk-internal.mysql.com:/home/bk/mysql-4.1
into mysql.com:/home/my/mysql-4.1
This commit is contained in:
commit
a6f89625fc
@ -619,10 +619,10 @@ static struct my_option my_long_options[] =
|
|||||||
(gptr*) ¤t_user, 0, GET_STR_ALLOC, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
|
(gptr*) ¤t_user, 0, GET_STR_ALLOC, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
|
||||||
#endif
|
#endif
|
||||||
{"safe-updates", 'U', "Only allow UPDATE and DELETE that uses keys.",
|
{"safe-updates", 'U', "Only allow UPDATE and DELETE that uses keys.",
|
||||||
(gptr*) &safe_updates, (gptr*) &safe_updates, 0, GET_BOOL, OPT_ARG, 0, 0,
|
(gptr*) &safe_updates, (gptr*) &safe_updates, 0, GET_BOOL, NO_ARG, 0, 0,
|
||||||
0, 0, 0, 0},
|
0, 0, 0, 0},
|
||||||
{"i-am-a-dummy", 'U', "Synonym for option --safe-updates, -U.",
|
{"i-am-a-dummy", 'U', "Synonym for option --safe-updates, -U.",
|
||||||
(gptr*) &safe_updates, (gptr*) &safe_updates, 0, GET_BOOL, OPT_ARG, 0, 0,
|
(gptr*) &safe_updates, (gptr*) &safe_updates, 0, GET_BOOL, NO_ARG, 0, 0,
|
||||||
0, 0, 0, 0},
|
0, 0, 0, 0},
|
||||||
{"verbose", 'v', "Write more. (-v -v -v gives the table output format).", 0,
|
{"verbose", 'v', "Write more. (-v -v -v gives the table output format).", 0,
|
||||||
0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
|
0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
|
||||||
|
@ -95,6 +95,7 @@ functions */
|
|||||||
#define LONGLONG_MAX ((__int64) 0x7FFFFFFFFFFFFFFF)
|
#define LONGLONG_MAX ((__int64) 0x7FFFFFFFFFFFFFFF)
|
||||||
#define ULONGLONG_MAX ((unsigned __int64) 0xFFFFFFFFFFFFFFFF)
|
#define ULONGLONG_MAX ((unsigned __int64) 0xFFFFFFFFFFFFFFFF)
|
||||||
#define LL(A) ((__int64) A)
|
#define LL(A) ((__int64) A)
|
||||||
|
#define ULL(A) ((unsigned __int64) A)
|
||||||
|
|
||||||
/* Type information */
|
/* Type information */
|
||||||
|
|
||||||
|
@ -67,7 +67,7 @@ extern const char *client_errors[]; /* Error messages */
|
|||||||
/* new 4.1 error codes */
|
/* new 4.1 error codes */
|
||||||
#define CR_NULL_POINTER 2028
|
#define CR_NULL_POINTER 2028
|
||||||
#define CR_NO_PREPARE_STMT 2029
|
#define CR_NO_PREPARE_STMT 2029
|
||||||
#define CR_NOT_ALL_PARAMS_BOUND 2030
|
#define CR_PARAMS_NOT_BOUND 2030
|
||||||
#define CR_DATA_TRUNCATED 2031
|
#define CR_DATA_TRUNCATED 2031
|
||||||
#define CR_NO_PARAMETERS_EXISTS 2032
|
#define CR_NO_PARAMETERS_EXISTS 2032
|
||||||
#define CR_INVALID_PARAMETER_NO 2033
|
#define CR_INVALID_PARAMETER_NO 2033
|
||||||
@ -87,3 +87,5 @@ extern const char *client_errors[]; /* Error messages */
|
|||||||
#define CR_CONN_UNKNOW_PROTOCOL 2046
|
#define CR_CONN_UNKNOW_PROTOCOL 2046
|
||||||
#define CR_INVALID_CONN_HANDLE 2047
|
#define CR_INVALID_CONN_HANDLE 2047
|
||||||
#define CR_SECURE_AUTH 2048
|
#define CR_SECURE_AUTH 2048
|
||||||
|
#define CR_FETCH_CANCELLED 2049
|
||||||
|
#define CR_NO_DATA 2050
|
||||||
|
@ -842,6 +842,14 @@ typedef char bool; /* Ordinary boolean values 0 1 */
|
|||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifndef ULL
|
||||||
|
#ifdef HAVE_LONG_LONG
|
||||||
|
#define ULL(A) A ## ULL
|
||||||
|
#else
|
||||||
|
#define ULL(A) A ## UL
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Defines to make it possible to prioritize register assignments. No
|
Defines to make it possible to prioritize register assignments. No
|
||||||
longer that important with modern compilers.
|
longer that important with modern compilers.
|
||||||
|
@ -256,6 +256,11 @@ typedef struct st_mysql
|
|||||||
LIST *stmts; /* list of all statements */
|
LIST *stmts; /* list of all statements */
|
||||||
const struct st_mysql_methods *methods;
|
const struct st_mysql_methods *methods;
|
||||||
void *thd;
|
void *thd;
|
||||||
|
/*
|
||||||
|
Points to boolean flag in MYSQL_RES or MYSQL_STMT. We set this flag
|
||||||
|
from mysql_stmt_close if close had to cancel result set of this object.
|
||||||
|
*/
|
||||||
|
my_bool *unbuffered_fetch_owner;
|
||||||
} MYSQL;
|
} MYSQL;
|
||||||
|
|
||||||
typedef struct st_mysql_res {
|
typedef struct st_mysql_res {
|
||||||
@ -270,6 +275,8 @@ typedef struct st_mysql_res {
|
|||||||
MYSQL_ROW row; /* If unbuffered read */
|
MYSQL_ROW row; /* If unbuffered read */
|
||||||
MYSQL_ROW current_row; /* buffer to current row */
|
MYSQL_ROW current_row; /* buffer to current row */
|
||||||
my_bool eof; /* Used by mysql_fetch_row */
|
my_bool eof; /* Used by mysql_fetch_row */
|
||||||
|
/* mysql_stmt_close() had to cancel this result */
|
||||||
|
my_bool unbuffered_fetch_cancelled;
|
||||||
const struct st_mysql_methods *methods;
|
const struct st_mysql_methods *methods;
|
||||||
} MYSQL_RES;
|
} MYSQL_RES;
|
||||||
|
|
||||||
@ -479,7 +486,11 @@ my_bool STDCALL mysql_read_query_result(MYSQL *mysql);
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
/* statement state */
|
/* statement state */
|
||||||
enum PREP_STMT_STATE { MY_ST_UNKNOWN, MY_ST_PREPARE, MY_ST_EXECUTE };
|
enum enum_mysql_stmt_state
|
||||||
|
{
|
||||||
|
MYSQL_STMT_INIT_DONE= 1, MYSQL_STMT_PREPARE_DONE, MYSQL_STMT_EXECUTE_DONE,
|
||||||
|
MYSQL_STMT_FETCH_DONE
|
||||||
|
};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
client TIME structure to handle TIME, DATE and TIMESTAMP directly in
|
client TIME structure to handle TIME, DATE and TIMESTAMP directly in
|
||||||
@ -525,31 +536,34 @@ typedef struct st_mysql_bind
|
|||||||
/* statement handler */
|
/* statement handler */
|
||||||
typedef struct st_mysql_stmt
|
typedef struct st_mysql_stmt
|
||||||
{
|
{
|
||||||
|
MEM_ROOT mem_root; /* root allocations */
|
||||||
|
LIST list; /* list to keep track of all stmts */
|
||||||
MYSQL *mysql; /* connection handle */
|
MYSQL *mysql; /* connection handle */
|
||||||
MYSQL_BIND *params; /* input parameters */
|
MYSQL_BIND *params; /* input parameters */
|
||||||
MYSQL_RES *result; /* resultset */
|
MYSQL_BIND *bind; /* output parameters */
|
||||||
MYSQL_BIND *bind; /* row binding */
|
MYSQL_FIELD *fields; /* result set metadata */
|
||||||
MYSQL_FIELD *fields; /* prepare meta info */
|
MYSQL_RES *result; /* cached result set */
|
||||||
LIST list; /* list to keep track of all stmts */
|
|
||||||
unsigned char *current_row; /* unbuffered row */
|
|
||||||
unsigned char *last_fetched_buffer; /* last fetched column buffer */
|
|
||||||
char *query; /* query buffer */
|
|
||||||
MEM_ROOT mem_root; /* root allocations */
|
|
||||||
my_ulonglong last_fetched_column; /* last fetched column */
|
|
||||||
/* copy of mysql->affected_rows after statement execution */
|
/* copy of mysql->affected_rows after statement execution */
|
||||||
my_ulonglong affected_rows;
|
my_ulonglong affected_rows;
|
||||||
|
/*
|
||||||
|
mysql_stmt_fetch() calls this function to fetch one row (it's different
|
||||||
|
for buffered, unbuffered and cursor fetch).
|
||||||
|
*/
|
||||||
|
int (*read_row_func)(struct st_mysql_stmt *stmt,
|
||||||
|
unsigned char **row);
|
||||||
unsigned long stmt_id; /* Id for prepared statement */
|
unsigned long stmt_id; /* Id for prepared statement */
|
||||||
unsigned int last_errno; /* error code */
|
unsigned int last_errno; /* error code */
|
||||||
unsigned int param_count; /* parameters count */
|
unsigned int param_count; /* inpute parameters count */
|
||||||
unsigned int field_count; /* fields count */
|
unsigned int field_count; /* number of columns in result set */
|
||||||
enum PREP_STMT_STATE state; /* statement state */
|
enum enum_mysql_stmt_state state; /* statement state */
|
||||||
char last_error[MYSQL_ERRMSG_SIZE]; /* error message */
|
char last_error[MYSQL_ERRMSG_SIZE]; /* error message */
|
||||||
char sqlstate[SQLSTATE_LENGTH+1];
|
char sqlstate[SQLSTATE_LENGTH+1];
|
||||||
my_bool long_alloced; /* flag to indicate long alloced */
|
/* Types of input parameters should be sent to server */
|
||||||
my_bool send_types_to_server; /* Types sent to server */
|
my_bool send_types_to_server;
|
||||||
my_bool param_buffers; /* param bound buffers */
|
my_bool bind_param_done; /* input buffers were supplied */
|
||||||
my_bool res_buffers; /* output bound buffers */
|
my_bool bind_result_done; /* output buffers were supplied */
|
||||||
my_bool result_buffered; /* Results buffered */
|
/* mysql_stmt_close() had to cancel this result */
|
||||||
|
my_bool unbuffered_fetch_cancelled;
|
||||||
} MYSQL_STMT;
|
} MYSQL_STMT;
|
||||||
|
|
||||||
|
|
||||||
|
@ -308,4 +308,5 @@
|
|||||||
#define ER_FEATURE_DISABLED 1289
|
#define ER_FEATURE_DISABLED 1289
|
||||||
#define ER_OPTION_PREVENTS_STATEMENT 1290
|
#define ER_OPTION_PREVENTS_STATEMENT 1290
|
||||||
#define ER_DUPLICATED_VALUE_IN_TYPE 1291
|
#define ER_DUPLICATED_VALUE_IN_TYPE 1291
|
||||||
#define ER_ERROR_MESSAGES 292
|
#define ER_TRUNCATED_WRONG_VALUE 1292
|
||||||
|
#define ER_ERROR_MESSAGES 293
|
||||||
|
@ -25,6 +25,7 @@ extern "C" {
|
|||||||
MYSQL_FIELD *unpack_fields(MYSQL_DATA *data,MEM_ROOT *alloc,uint fields,
|
MYSQL_FIELD *unpack_fields(MYSQL_DATA *data,MEM_ROOT *alloc,uint fields,
|
||||||
my_bool default_value, uint server_capabilities);
|
my_bool default_value, uint server_capabilities);
|
||||||
void free_rows(MYSQL_DATA *cur);
|
void free_rows(MYSQL_DATA *cur);
|
||||||
|
void flush_use_result(MYSQL *mysql);
|
||||||
my_bool mysql_autenticate(MYSQL *mysql, const char *passwd);
|
my_bool mysql_autenticate(MYSQL *mysql, const char *passwd);
|
||||||
void free_old_query(MYSQL *mysql);
|
void free_old_query(MYSQL *mysql);
|
||||||
void end_server(MYSQL *mysql);
|
void end_server(MYSQL *mysql);
|
||||||
|
@ -22,7 +22,6 @@ extern my_string mysql_unix_port;
|
|||||||
CLIENT_PROTOCOL_41 | CLIENT_SECURE_CONNECTION)
|
CLIENT_PROTOCOL_41 | CLIENT_SECURE_CONNECTION)
|
||||||
|
|
||||||
sig_handler pipe_sig_handler(int sig __attribute__((unused)));
|
sig_handler pipe_sig_handler(int sig __attribute__((unused)));
|
||||||
my_bool stmt_close(MYSQL_STMT *stmt, my_bool skip_free);
|
|
||||||
void read_user_name(char *name);
|
void read_user_name(char *name);
|
||||||
my_bool send_file_to_server(MYSQL *mysql, const char *filename);
|
my_bool send_file_to_server(MYSQL *mysql, const char *filename);
|
||||||
|
|
||||||
|
@ -54,7 +54,7 @@ const char *client_errors[]=
|
|||||||
"Malformed packet",
|
"Malformed packet",
|
||||||
"Invalid use of null pointer",
|
"Invalid use of null pointer",
|
||||||
"Statement not prepared",
|
"Statement not prepared",
|
||||||
"Not all parameters data supplied",
|
"Parameters data was not supplied",
|
||||||
"Data truncated",
|
"Data truncated",
|
||||||
"No parameters exists in the statement",
|
"No parameters exists in the statement",
|
||||||
"Invalid parameter number",
|
"Invalid parameter number",
|
||||||
@ -72,7 +72,9 @@ const char *client_errors[]=
|
|||||||
"Can't open shared memory. Can't send the request event to server (%lu)",
|
"Can't open shared memory. Can't send the request event to server (%lu)",
|
||||||
"Wrong or unknown protocol",
|
"Wrong or unknown protocol",
|
||||||
"Invalid connection handle",
|
"Invalid connection handle",
|
||||||
"Connection using old (pre 4.1.1) authentication protocol refused (client option 'secure_auth' enabled)"
|
"Connection using old (pre 4.1.1) authentication protocol refused (client option 'secure_auth' enabled)",
|
||||||
|
"Row retrieval was cancelled by mysql_stmt_close() call",
|
||||||
|
"Attempt to read column without prior row fetch"
|
||||||
};
|
};
|
||||||
|
|
||||||
/* Start of code added by Roberto M. Serqueira - martinsc@uol.com.br - 05.24.2001 */
|
/* Start of code added by Roberto M. Serqueira - martinsc@uol.com.br - 05.24.2001 */
|
||||||
@ -110,7 +112,7 @@ const char *client_errors[]=
|
|||||||
"Malformed packet",
|
"Malformed packet",
|
||||||
"Invalid use of null pointer",
|
"Invalid use of null pointer",
|
||||||
"Statement not prepared",
|
"Statement not prepared",
|
||||||
"Not all parameters data supplied",
|
"Parameters data was not supplied",
|
||||||
"Data truncated",
|
"Data truncated",
|
||||||
"No parameters exists in the statement",
|
"No parameters exists in the statement",
|
||||||
"Invalid parameter number",
|
"Invalid parameter number",
|
||||||
@ -128,7 +130,9 @@ const char *client_errors[]=
|
|||||||
"Can't open shared memory. Can't send the request event to server (%lu)",
|
"Can't open shared memory. Can't send the request event to server (%lu)",
|
||||||
"Wrong or unknown protocol",
|
"Wrong or unknown protocol",
|
||||||
"Invalid connection handle",
|
"Invalid connection handle",
|
||||||
"Connection using old (pre 4.1.1) authentication protocol refused (client option 'secure_auth' enabled)"
|
"Connection using old (pre 4.1.1) authentication protocol refused (client option 'secure_auth' enabled)",
|
||||||
|
"Row retrieval was cancelled by mysql_stmt_close() call",
|
||||||
|
"Attempt to read column without prior row fetch"
|
||||||
};
|
};
|
||||||
|
|
||||||
#else /* ENGLISH */
|
#else /* ENGLISH */
|
||||||
@ -182,7 +186,9 @@ const char *client_errors[]=
|
|||||||
"Can't open shared memory. Can't send the request event to server (%lu)",
|
"Can't open shared memory. Can't send the request event to server (%lu)",
|
||||||
"Wrong or unknown protocol",
|
"Wrong or unknown protocol",
|
||||||
"Invalid connection handle",
|
"Invalid connection handle",
|
||||||
"Connection using old (pre 4.1.1) authentication protocol refused (client option 'secure_auth' enabled)"
|
"Connection using old (pre 4.1.1) authentication protocol refused (client option 'secure_auth' enabled)",
|
||||||
|
"Row retrieval was cancelled by mysql_stmt_close() call",
|
||||||
|
"Attempt to read column without prior row fetch"
|
||||||
};
|
};
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -638,6 +638,7 @@ int cli_read_change_user_result(MYSQL *mysql, char *buff, const char *passwd)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
my_bool STDCALL mysql_change_user(MYSQL *mysql, const char *user,
|
my_bool STDCALL mysql_change_user(MYSQL *mysql, const char *user,
|
||||||
const char *passwd, const char *db)
|
const char *passwd, const char *db)
|
||||||
{
|
{
|
||||||
@ -866,6 +867,7 @@ STDCALL mysql_set_master(MYSQL* mysql, const char* host,
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
int
|
int
|
||||||
STDCALL mysql_add_slave(MYSQL* mysql, const char* host,
|
STDCALL mysql_add_slave(MYSQL* mysql, const char* host,
|
||||||
unsigned int port,
|
unsigned int port,
|
||||||
@ -987,6 +989,7 @@ mysql_list_tables(MYSQL *mysql, const char *wild)
|
|||||||
DBUG_RETURN (mysql_store_result(mysql));
|
DBUG_RETURN (mysql_store_result(mysql));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
MYSQL_FIELD *cli_list_fields(MYSQL *mysql)
|
MYSQL_FIELD *cli_list_fields(MYSQL *mysql)
|
||||||
{
|
{
|
||||||
MYSQL_DATA *query;
|
MYSQL_DATA *query;
|
||||||
@ -1062,6 +1065,7 @@ mysql_list_processes(MYSQL *mysql)
|
|||||||
DBUG_RETURN(mysql_store_result(mysql));
|
DBUG_RETURN(mysql_store_result(mysql));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
#ifdef USE_OLD_FUNCTIONS
|
#ifdef USE_OLD_FUNCTIONS
|
||||||
int STDCALL
|
int STDCALL
|
||||||
mysql_create_db(MYSQL *mysql, const char *db)
|
mysql_create_db(MYSQL *mysql, const char *db)
|
||||||
@ -1099,6 +1103,7 @@ mysql_refresh(MYSQL *mysql,uint options)
|
|||||||
DBUG_RETURN(simple_command(mysql,COM_REFRESH,(char*) bits,1,0));
|
DBUG_RETURN(simple_command(mysql,COM_REFRESH,(char*) bits,1,0));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
int STDCALL
|
int STDCALL
|
||||||
mysql_kill(MYSQL *mysql,ulong pid)
|
mysql_kill(MYSQL *mysql,ulong pid)
|
||||||
{
|
{
|
||||||
@ -1126,6 +1131,7 @@ mysql_dump_debug_info(MYSQL *mysql)
|
|||||||
DBUG_RETURN(simple_command(mysql,COM_DEBUG,0,0,0));
|
DBUG_RETURN(simple_command(mysql,COM_DEBUG,0,0,0));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
const char *cli_read_statistics(MYSQL *mysql)
|
const char *cli_read_statistics(MYSQL *mysql)
|
||||||
{
|
{
|
||||||
mysql->net.read_pos[mysql->packet_length]=0; /* End of stat string */
|
mysql->net.read_pos[mysql->packet_length]=0; /* End of stat string */
|
||||||
@ -1139,6 +1145,7 @@ const char *cli_read_statistics(MYSQL *mysql)
|
|||||||
return (char*) mysql->net.read_pos;
|
return (char*) mysql->net.read_pos;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
const char * STDCALL
|
const char * STDCALL
|
||||||
mysql_stat(MYSQL *mysql)
|
mysql_stat(MYSQL *mysql)
|
||||||
{
|
{
|
||||||
@ -1576,6 +1583,10 @@ static my_bool my_realloc_str(NET *net, ulong length)
|
|||||||
Prepare related implementations
|
Prepare related implementations
|
||||||
********************************************************************/
|
********************************************************************/
|
||||||
|
|
||||||
|
static int stmt_read_row_unbuffered(MYSQL_STMT *stmt, unsigned char **row);
|
||||||
|
static int stmt_read_row_buffered(MYSQL_STMT *stmt, unsigned char **row);
|
||||||
|
static int stmt_read_row_no_data(MYSQL_STMT *stmt, unsigned char **row);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Read the prepared statement results ..
|
Read the prepared statement results ..
|
||||||
|
|
||||||
@ -1591,13 +1602,12 @@ static my_bool my_realloc_str(NET *net, ulong length)
|
|||||||
my_bool cli_read_prepare_result(MYSQL *mysql, MYSQL_STMT *stmt)
|
my_bool cli_read_prepare_result(MYSQL *mysql, MYSQL_STMT *stmt)
|
||||||
{
|
{
|
||||||
uchar *pos;
|
uchar *pos;
|
||||||
uint field_count;
|
uint field_count, param_count;
|
||||||
ulong length, param_count;
|
|
||||||
MYSQL_DATA *fields_data;
|
MYSQL_DATA *fields_data;
|
||||||
DBUG_ENTER("read_prepare_result");
|
DBUG_ENTER("read_prepare_result");
|
||||||
|
|
||||||
mysql= mysql->last_used_con;
|
mysql= mysql->last_used_con;
|
||||||
if ((length= net_safe_read(mysql)) == packet_error)
|
if (net_safe_read(mysql) == packet_error)
|
||||||
DBUG_RETURN(1);
|
DBUG_RETURN(1);
|
||||||
|
|
||||||
pos= (uchar*) mysql->net.read_pos;
|
pos= (uchar*) mysql->net.read_pos;
|
||||||
@ -1634,7 +1644,7 @@ MYSQL_STMT * STDCALL mysql_prepare(MYSQL *mysql, const char *query,
|
|||||||
stmt= mysql_stmt_init(mysql);
|
stmt= mysql_stmt_init(mysql);
|
||||||
if (stmt && mysql_stmt_prepare(stmt, query, query_length))
|
if (stmt && mysql_stmt_prepare(stmt, query, query_length))
|
||||||
{
|
{
|
||||||
stmt_close(stmt, 0);
|
mysql_stmt_close(stmt);
|
||||||
DBUG_RETURN(0);
|
DBUG_RETURN(0);
|
||||||
}
|
}
|
||||||
DBUG_RETURN(stmt);
|
DBUG_RETURN(stmt);
|
||||||
@ -1646,6 +1656,7 @@ MYSQL_STMT * STDCALL mysql_prepare(MYSQL *mysql, const char *query,
|
|||||||
SYNOPSIS
|
SYNOPSIS
|
||||||
mysql_stmt_init()
|
mysql_stmt_init()
|
||||||
mysql connection handle
|
mysql connection handle
|
||||||
|
|
||||||
RETURN VALUE
|
RETURN VALUE
|
||||||
statement structure upon success and NULL if out of
|
statement structure upon success and NULL if out of
|
||||||
memory
|
memory
|
||||||
@ -1664,20 +1675,35 @@ mysql_stmt_init(MYSQL *mysql)
|
|||||||
DBUG_RETURN(0);
|
DBUG_RETURN(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
init_alloc_root(&stmt->mem_root,8192,0);
|
init_alloc_root(&stmt->mem_root, 2048, 2048);
|
||||||
mysql->stmts= list_add(mysql->stmts, &stmt->list);
|
mysql->stmts= list_add(mysql->stmts, &stmt->list);
|
||||||
stmt->list.data= stmt;
|
stmt->list.data= stmt;
|
||||||
stmt->state= MY_ST_UNKNOWN;
|
stmt->state= MYSQL_STMT_INIT_DONE;
|
||||||
stmt->mysql= mysql;
|
stmt->mysql= mysql;
|
||||||
|
stmt->read_row_func= stmt_read_row_no_data;
|
||||||
|
/* The rest of statement members was bzeroed inside malloc */
|
||||||
|
|
||||||
DBUG_RETURN(stmt);
|
DBUG_RETURN(stmt);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Prepare server side statement with query.
|
Prepare server side statement with query:
|
||||||
|
SYNOPSIS
|
||||||
|
mysql_stmt_prepare()
|
||||||
|
query statement to prepare
|
||||||
|
length statement length
|
||||||
|
|
||||||
Also update the total parameter count along with resultset
|
DESCRIPTION
|
||||||
metadata information by reading from server
|
- if this is a re-prepare of the statement, first close previous data
|
||||||
|
structure on the server and free old statement data
|
||||||
|
- send the query to server and get back number of placeholders,
|
||||||
|
number of columns in result set (if any), and result set metadata.
|
||||||
|
At the same time allocate memory for input and output parameters
|
||||||
|
to have less checks in mysql_stmt_bind_{param, result}.
|
||||||
|
|
||||||
|
RETURN VALUES
|
||||||
|
0 success
|
||||||
|
!0 error
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
@ -1687,17 +1713,44 @@ mysql_stmt_prepare(MYSQL_STMT *stmt, const char *query, ulong length)
|
|||||||
MYSQL *mysql= stmt->mysql;
|
MYSQL *mysql= stmt->mysql;
|
||||||
DBUG_ENTER("mysql_stmt_prepare");
|
DBUG_ENTER("mysql_stmt_prepare");
|
||||||
|
|
||||||
DBUG_ASSERT(mysql != 0);
|
if (!mysql)
|
||||||
|
|
||||||
/* In case we reprepare this handle with another statement */
|
|
||||||
free_root(&stmt->mem_root, MYF(0));
|
|
||||||
|
|
||||||
/* stmt->query is never used yet */
|
|
||||||
if (!(stmt->query= strmake_root(&stmt->mem_root, query, length)))
|
|
||||||
{
|
{
|
||||||
set_stmt_error(stmt, CR_OUT_OF_MEMORY, unknown_sqlstate);
|
/* mysql can be reset in mysql_close called from mysql_reconnect */
|
||||||
|
set_stmt_error(stmt, CR_SERVER_LOST, unknown_sqlstate);
|
||||||
DBUG_RETURN(1);
|
DBUG_RETURN(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if ((int) stmt->state > (int) MYSQL_STMT_INIT_DONE)
|
||||||
|
{
|
||||||
|
/* This is second prepare with another statement */
|
||||||
|
char buff[4];
|
||||||
|
|
||||||
|
mysql_stmt_free_result(stmt);
|
||||||
|
/*
|
||||||
|
These members must be reset for API to
|
||||||
|
function in case of error or misuse.
|
||||||
|
*/
|
||||||
|
stmt->bind_param_done= stmt->bind_result_done= FALSE;
|
||||||
|
stmt->param_count= stmt->field_count= 0;
|
||||||
|
stmt->last_errno= 0;
|
||||||
|
stmt->last_error[0]= '\0';
|
||||||
|
free_root(&stmt->mem_root, MYF(MY_KEEP_PREALLOC));
|
||||||
|
|
||||||
|
int4store(buff, stmt->stmt_id);
|
||||||
|
/*
|
||||||
|
If there was a 'use' result from another statement, or from
|
||||||
|
mysql_use_result it won't be freed in mysql_stmt_free_result and
|
||||||
|
we should get 'Commands out of sync' here.
|
||||||
|
*/
|
||||||
|
if (simple_command(mysql, COM_CLOSE_STMT, buff, 4, 1))
|
||||||
|
{
|
||||||
|
set_stmt_errmsg(stmt, mysql->net.last_error, mysql->net.last_errno,
|
||||||
|
mysql->net.sqlstate);
|
||||||
|
DBUG_RETURN(1);
|
||||||
|
}
|
||||||
|
stmt->state= MYSQL_STMT_INIT_DONE;
|
||||||
|
}
|
||||||
|
|
||||||
if (simple_command(mysql, COM_PREPARE, query, length, 1))
|
if (simple_command(mysql, COM_PREPARE, query, length, 1))
|
||||||
{
|
{
|
||||||
set_stmt_errmsg(stmt, mysql->net.last_error, mysql->net.last_errno,
|
set_stmt_errmsg(stmt, mysql->net.last_error, mysql->net.last_errno,
|
||||||
@ -1706,8 +1759,18 @@ mysql_stmt_prepare(MYSQL_STMT *stmt, const char *query, ulong length)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if ((*mysql->methods->read_prepare_result)(mysql, stmt))
|
if ((*mysql->methods->read_prepare_result)(mysql, stmt))
|
||||||
|
{
|
||||||
|
set_stmt_errmsg(stmt, mysql->net.last_error, mysql->net.last_errno,
|
||||||
|
mysql->net.sqlstate);
|
||||||
DBUG_RETURN(1);
|
DBUG_RETURN(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
alloc_root will return valid address even in case param_count
|
||||||
|
and field_count are zero. Thus we should never rely on stmt->bind
|
||||||
|
or stmt->params when checking for existence of placeholders or
|
||||||
|
result set.
|
||||||
|
*/
|
||||||
if (!(stmt->params= (MYSQL_BIND *) alloc_root(&stmt->mem_root,
|
if (!(stmt->params= (MYSQL_BIND *) alloc_root(&stmt->mem_root,
|
||||||
sizeof(MYSQL_BIND)*
|
sizeof(MYSQL_BIND)*
|
||||||
(stmt->param_count +
|
(stmt->param_count +
|
||||||
@ -1717,26 +1780,22 @@ mysql_stmt_prepare(MYSQL_STMT *stmt, const char *query, ulong length)
|
|||||||
DBUG_RETURN(1);
|
DBUG_RETURN(1);
|
||||||
}
|
}
|
||||||
stmt->bind= stmt->params + stmt->param_count;
|
stmt->bind= stmt->params + stmt->param_count;
|
||||||
stmt->state= MY_ST_PREPARE;
|
stmt->state= MYSQL_STMT_PREPARE_DONE;
|
||||||
mysql->status= MYSQL_STATUS_READY;
|
|
||||||
DBUG_PRINT("info", ("Parameter count: %ld", stmt->param_count));
|
DBUG_PRINT("info", ("Parameter count: %ld", stmt->param_count));
|
||||||
DBUG_RETURN(0);
|
DBUG_RETURN(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Get the execute query meta information for non-select
|
Get the execute query meta information for non-select
|
||||||
statements (on demand).
|
statements.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
unsigned int alloc_stmt_fields(MYSQL_STMT *stmt)
|
static unsigned int alloc_stmt_fields(MYSQL_STMT *stmt)
|
||||||
{
|
{
|
||||||
MYSQL_FIELD *fields, *field, *end;
|
MYSQL_FIELD *fields, *field, *end;
|
||||||
MEM_ROOT *alloc= &stmt->mem_root;
|
MEM_ROOT *alloc= &stmt->mem_root;
|
||||||
MYSQL *mysql= stmt->mysql->last_used_con;
|
MYSQL *mysql= stmt->mysql->last_used_con;
|
||||||
|
|
||||||
if (stmt->state != MY_ST_EXECUTE || !mysql->field_count)
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
stmt->field_count= mysql->field_count;
|
stmt->field_count= mysql->field_count;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -1782,20 +1841,25 @@ mysql_stmt_result_metadata(MYSQL_STMT *stmt)
|
|||||||
MYSQL_RES *result;
|
MYSQL_RES *result;
|
||||||
DBUG_ENTER("mysql_stmt_result_metadata");
|
DBUG_ENTER("mysql_stmt_result_metadata");
|
||||||
|
|
||||||
if (!stmt->field_count || !stmt->fields)
|
/*
|
||||||
|
stmt->fields is only defined if stmt->field_count is not null;
|
||||||
|
stmt->field_count is initialized in prepare.
|
||||||
|
*/
|
||||||
|
if (!stmt->field_count)
|
||||||
|
DBUG_RETURN(0);
|
||||||
|
|
||||||
|
if (!(result=(MYSQL_RES*) my_malloc(sizeof(*result),
|
||||||
|
MYF(MY_WME | MY_ZEROFILL))))
|
||||||
{
|
{
|
||||||
if (!alloc_stmt_fields(stmt))
|
set_stmt_error(stmt, CR_OUT_OF_MEMORY, unknown_sqlstate);
|
||||||
DBUG_RETURN(0);
|
DBUG_RETURN(0);
|
||||||
}
|
}
|
||||||
if (!(result=(MYSQL_RES*) my_malloc(sizeof(*result)+
|
|
||||||
sizeof(ulong)*stmt->field_count,
|
|
||||||
MYF(MY_WME | MY_ZEROFILL))))
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
result->methods= stmt->mysql->methods;
|
result->methods= stmt->mysql->methods;
|
||||||
result->eof=1; /* Marker for buffered */
|
result->eof= 1; /* Marker for buffered */
|
||||||
result->fields= stmt->fields;
|
result->fields= stmt->fields;
|
||||||
result->field_count= stmt->field_count;
|
result->field_count= stmt->field_count;
|
||||||
|
/* The rest of members of 'result' was bzeroed inside malloc */
|
||||||
DBUG_RETURN(result);
|
DBUG_RETURN(result);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1989,11 +2053,9 @@ static void store_param_null(NET *net, MYSQL_BIND *param)
|
|||||||
client application
|
client application
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
static my_bool store_param(MYSQL_STMT *stmt, MYSQL_BIND *param)
|
static my_bool store_param(MYSQL_STMT *stmt, MYSQL_BIND *param)
|
||||||
{
|
{
|
||||||
MYSQL *mysql= stmt->mysql;
|
NET *net= &stmt->mysql->net;
|
||||||
NET *net = &mysql->net;
|
|
||||||
DBUG_ENTER("store_param");
|
DBUG_ENTER("store_param");
|
||||||
DBUG_PRINT("enter",("type: %d, buffer:%lx, length: %lu is_null: %d",
|
DBUG_PRINT("enter",("type: %d, buffer:%lx, length: %lu is_null: %d",
|
||||||
param->buffer_type,
|
param->buffer_type,
|
||||||
@ -2059,6 +2121,12 @@ int cli_stmt_execute(MYSQL_STMT *stmt)
|
|||||||
uint null_count;
|
uint null_count;
|
||||||
my_bool result;
|
my_bool result;
|
||||||
|
|
||||||
|
if (!stmt->bind_param_done)
|
||||||
|
{
|
||||||
|
set_stmt_error(stmt, CR_PARAMS_NOT_BOUND, unknown_sqlstate);
|
||||||
|
DBUG_RETURN(1);
|
||||||
|
}
|
||||||
|
|
||||||
net_clear(net); /* Sets net->write_pos */
|
net_clear(net); /* Sets net->write_pos */
|
||||||
/* Reserve place for null-marker bytes */
|
/* Reserve place for null-marker bytes */
|
||||||
null_count= (stmt->param_count+7) /8;
|
null_count= (stmt->param_count+7) /8;
|
||||||
@ -2093,7 +2161,6 @@ int cli_stmt_execute(MYSQL_STMT *stmt)
|
|||||||
set_stmt_error(stmt, CR_OUT_OF_MEMORY, unknown_sqlstate);
|
set_stmt_error(stmt, CR_OUT_OF_MEMORY, unknown_sqlstate);
|
||||||
DBUG_RETURN(1);
|
DBUG_RETURN(1);
|
||||||
}
|
}
|
||||||
net->write_pos= net->buff; /* Reset for net_write() */
|
|
||||||
result= execute(stmt, param_data, length);
|
result= execute(stmt, param_data, length);
|
||||||
stmt->send_types_to_server=0;
|
stmt->send_types_to_server=0;
|
||||||
my_free(param_data, MYF(MY_WME));
|
my_free(param_data, MYF(MY_WME));
|
||||||
@ -2102,22 +2169,146 @@ int cli_stmt_execute(MYSQL_STMT *stmt)
|
|||||||
DBUG_RETURN((int) execute(stmt,0,0));
|
DBUG_RETURN((int) execute(stmt,0,0));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
Read one row from buffered result set. Result set is created by prior
|
||||||
|
call to mysql_stmt_store_result().
|
||||||
|
SYNOPSIS
|
||||||
|
stmt_read_row_buffered()
|
||||||
|
|
||||||
|
RETURN VALUE
|
||||||
|
0 - success; *row is set to valid row pointer (row data
|
||||||
|
is stored in result set buffer)
|
||||||
|
MYSQL_NO_DATA - end of result set. *row is set to NULL
|
||||||
|
*/
|
||||||
|
|
||||||
|
static int stmt_read_row_buffered(MYSQL_STMT *stmt, unsigned char **row)
|
||||||
|
{
|
||||||
|
MYSQL_RES *result= stmt->result;
|
||||||
|
|
||||||
|
if (result && result->data_cursor)
|
||||||
|
{
|
||||||
|
*row= (uchar *) result->data_cursor->data;
|
||||||
|
result->data_cursor= result->data_cursor->next;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
*row= 0;
|
||||||
|
return MYSQL_NO_DATA;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
Read one row from network: unbuffered non-cursor fetch.
|
||||||
|
If last row was read, or error occured, erase this statement
|
||||||
|
from record pointing to object unbuffered fetch is performed from.
|
||||||
|
|
||||||
|
SYNOPSIS
|
||||||
|
stmt_read_row_unbuffered()
|
||||||
|
stmt statement handle
|
||||||
|
row pointer to write pointer to row data;
|
||||||
|
|
||||||
|
RETURN VALUE
|
||||||
|
0 - success; *row contains valid address of a row;
|
||||||
|
row data is stored in network buffer
|
||||||
|
1 - error; error code is written to
|
||||||
|
stmt->last_{errno,error}; *row is not changed
|
||||||
|
MYSQL_NO_DATA - end of file was read from network;
|
||||||
|
*row is to NULL
|
||||||
|
*/
|
||||||
|
|
||||||
|
static int stmt_read_row_unbuffered(MYSQL_STMT *stmt, unsigned char **row)
|
||||||
|
{
|
||||||
|
int rc= 1;
|
||||||
|
MYSQL *mysql= stmt->mysql;
|
||||||
|
/*
|
||||||
|
This function won't be called if stmt->field_count is zero
|
||||||
|
or execution wasn't done: this is ensured by mysql_stmt_execute.
|
||||||
|
*/
|
||||||
|
if (!mysql)
|
||||||
|
{
|
||||||
|
set_stmt_error(stmt, CR_SERVER_LOST, unknown_sqlstate);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
if (mysql->status != MYSQL_STATUS_GET_RESULT)
|
||||||
|
{
|
||||||
|
set_stmt_error(stmt, stmt->unbuffered_fetch_cancelled ?
|
||||||
|
CR_FETCH_CANCELLED : CR_COMMANDS_OUT_OF_SYNC,
|
||||||
|
unknown_sqlstate);
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
if ((*mysql->methods->unbuffered_fetch)(mysql, (char**) row))
|
||||||
|
{
|
||||||
|
set_stmt_errmsg(stmt, mysql->net.last_error, mysql->net.last_errno,
|
||||||
|
mysql->net.sqlstate);
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
if (!*row)
|
||||||
|
{
|
||||||
|
mysql->status= MYSQL_STATUS_READY;
|
||||||
|
rc= MYSQL_NO_DATA;
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
error:
|
||||||
|
if (mysql->unbuffered_fetch_owner == &stmt->unbuffered_fetch_cancelled)
|
||||||
|
mysql->unbuffered_fetch_owner= 0;
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
Default read row function to not SIGSEGV in client in
|
||||||
|
case of wrong sequence of API calls.
|
||||||
|
*/
|
||||||
|
|
||||||
|
static int
|
||||||
|
stmt_read_row_no_data(MYSQL_STMT *stmt __attribute__((unused)),
|
||||||
|
unsigned char **row __attribute__((unused)))
|
||||||
|
{
|
||||||
|
if ((int) stmt->state < (int) MYSQL_STMT_PREPARE_DONE)
|
||||||
|
{
|
||||||
|
set_stmt_error(stmt, CR_NO_PREPARE_STMT, unknown_sqlstate);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
return MYSQL_NO_DATA;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Execute the prepared query
|
Execute the prepared query
|
||||||
*/
|
*/
|
||||||
|
|
||||||
int STDCALL mysql_stmt_execute(MYSQL_STMT *stmt)
|
int STDCALL mysql_stmt_execute(MYSQL_STMT *stmt)
|
||||||
{
|
{
|
||||||
|
MYSQL *mysql= stmt->mysql;
|
||||||
DBUG_ENTER("mysql_stmt_execute");
|
DBUG_ENTER("mysql_stmt_execute");
|
||||||
|
|
||||||
if ((*stmt->mysql->methods->stmt_execute)(stmt))
|
if (!mysql)
|
||||||
|
{
|
||||||
|
set_stmt_error(stmt, CR_SERVER_LOST, unknown_sqlstate);
|
||||||
DBUG_RETURN(1);
|
DBUG_RETURN(1);
|
||||||
|
}
|
||||||
|
|
||||||
stmt->state= MY_ST_EXECUTE;
|
mysql_stmt_free_result(stmt);
|
||||||
mysql_free_result(stmt->result);
|
/*
|
||||||
stmt->result= (MYSQL_RES *)0;
|
No need to check for stmt->state: if the statement wasn't
|
||||||
stmt->result_buffered= 0;
|
prepared we'll get 'unknown statemenet handler' error from server.
|
||||||
stmt->current_row= 0;
|
*/
|
||||||
|
if (mysql->methods->stmt_execute(stmt))
|
||||||
|
DBUG_RETURN(1);
|
||||||
|
if (!stmt->field_count && mysql->field_count)
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
This is 'SHOW'/'EXPLAIN'-like query. Current implementation of
|
||||||
|
prepared statements can't send result set metadata for this queries
|
||||||
|
on prepare stage. Read it now.
|
||||||
|
*/
|
||||||
|
alloc_stmt_fields(stmt);
|
||||||
|
}
|
||||||
|
|
||||||
|
stmt->state= MYSQL_STMT_EXECUTE_DONE;
|
||||||
|
if (stmt->field_count)
|
||||||
|
{
|
||||||
|
stmt->mysql->unbuffered_fetch_owner= &stmt->unbuffered_fetch_cancelled;
|
||||||
|
stmt->unbuffered_fetch_cancelled= FALSE;
|
||||||
|
stmt->read_row_func= stmt_read_row_unbuffered;
|
||||||
|
}
|
||||||
DBUG_RETURN(0);
|
DBUG_RETURN(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2155,6 +2346,16 @@ my_bool STDCALL mysql_stmt_bind_param(MYSQL_STMT *stmt, MYSQL_BIND * bind)
|
|||||||
MYSQL_BIND *param, *end;
|
MYSQL_BIND *param, *end;
|
||||||
DBUG_ENTER("mysql_stmt_bind_param");
|
DBUG_ENTER("mysql_stmt_bind_param");
|
||||||
|
|
||||||
|
if (!stmt->param_count)
|
||||||
|
{
|
||||||
|
if ((int) stmt->state < (int) MYSQL_STMT_PREPARE_DONE)
|
||||||
|
{
|
||||||
|
set_stmt_error(stmt, CR_NO_PREPARE_STMT, unknown_sqlstate);
|
||||||
|
DBUG_RETURN(1);
|
||||||
|
}
|
||||||
|
DBUG_RETURN(0);
|
||||||
|
}
|
||||||
|
|
||||||
/* Allocated on prepare */
|
/* Allocated on prepare */
|
||||||
memcpy((char*) stmt->params, (char*) bind,
|
memcpy((char*) stmt->params, (char*) bind,
|
||||||
sizeof(MYSQL_BIND) * stmt->param_count);
|
sizeof(MYSQL_BIND) * stmt->param_count);
|
||||||
@ -2166,13 +2367,6 @@ my_bool STDCALL mysql_stmt_bind_param(MYSQL_STMT *stmt, MYSQL_BIND * bind)
|
|||||||
param->param_number= count++;
|
param->param_number= count++;
|
||||||
param->long_data_used= 0;
|
param->long_data_used= 0;
|
||||||
|
|
||||||
/*
|
|
||||||
If param->length is not given, change it to point to buffer_length.
|
|
||||||
This way we can always use *param->length to get the length of data
|
|
||||||
*/
|
|
||||||
if (!param->length)
|
|
||||||
param->length= ¶m->buffer_length;
|
|
||||||
|
|
||||||
/* If param->is_null is not set, then the value can never be NULL */
|
/* If param->is_null is not set, then the value can never be NULL */
|
||||||
if (!param->is_null)
|
if (!param->is_null)
|
||||||
param->is_null= &int_is_null_false;
|
param->is_null= &int_is_null_false;
|
||||||
@ -2239,10 +2433,16 @@ my_bool STDCALL mysql_stmt_bind_param(MYSQL_STMT *stmt, MYSQL_BIND * bind)
|
|||||||
param->buffer_type, count);
|
param->buffer_type, count);
|
||||||
DBUG_RETURN(1);
|
DBUG_RETURN(1);
|
||||||
}
|
}
|
||||||
|
/*
|
||||||
|
If param->length is not given, change it to point to buffer_length.
|
||||||
|
This way we can always use *param->length to get the length of data
|
||||||
|
*/
|
||||||
|
if (!param->length)
|
||||||
|
param->length= ¶m->buffer_length;
|
||||||
}
|
}
|
||||||
/* We have to send/resendtype information to MySQL */
|
/* We have to send/resendtype information to MySQL */
|
||||||
stmt->send_types_to_server= 1;
|
stmt->send_types_to_server= TRUE;
|
||||||
stmt->param_buffers= 1;
|
stmt->bind_param_done= TRUE;
|
||||||
DBUG_RETURN(0);
|
DBUG_RETURN(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2277,6 +2477,16 @@ mysql_stmt_send_long_data(MYSQL_STMT *stmt, uint param_number,
|
|||||||
DBUG_PRINT("enter",("param no : %d, data : %lx, length : %ld",
|
DBUG_PRINT("enter",("param no : %d, data : %lx, length : %ld",
|
||||||
param_number, data, length));
|
param_number, data, length));
|
||||||
|
|
||||||
|
/*
|
||||||
|
We only need to check for stmt->param_count, if it's not null
|
||||||
|
prepare was done.
|
||||||
|
*/
|
||||||
|
if (param_number >= stmt->param_count)
|
||||||
|
{
|
||||||
|
set_stmt_error(stmt, CR_INVALID_PARAMETER_NO, unknown_sqlstate);
|
||||||
|
DBUG_RETURN(1);
|
||||||
|
}
|
||||||
|
|
||||||
param= stmt->params+param_number;
|
param= stmt->params+param_number;
|
||||||
if (param->buffer_type < MYSQL_TYPE_TINY_BLOB ||
|
if (param->buffer_type < MYSQL_TYPE_TINY_BLOB ||
|
||||||
param->buffer_type > MYSQL_TYPE_STRING)
|
param->buffer_type > MYSQL_TYPE_STRING)
|
||||||
@ -2846,9 +3056,20 @@ my_bool STDCALL mysql_stmt_bind_result(MYSQL_STMT *stmt, MYSQL_BIND *bind)
|
|||||||
DBUG_ENTER("mysql_stmt_bind_result");
|
DBUG_ENTER("mysql_stmt_bind_result");
|
||||||
DBUG_ASSERT(stmt != 0);
|
DBUG_ASSERT(stmt != 0);
|
||||||
|
|
||||||
if (!(bind_count= stmt->field_count) &&
|
if (!stmt->field_count)
|
||||||
!(bind_count= alloc_stmt_fields(stmt)))
|
{
|
||||||
|
if ((int) stmt->state < (int) MYSQL_STMT_PREPARE_DONE)
|
||||||
|
{
|
||||||
|
set_stmt_error(stmt, CR_NO_PREPARE_STMT, unknown_sqlstate);
|
||||||
|
}
|
||||||
DBUG_RETURN(0);
|
DBUG_RETURN(0);
|
||||||
|
}
|
||||||
|
bind_count= stmt->field_count;
|
||||||
|
|
||||||
|
/*
|
||||||
|
We only need to check that stmt->field_count - if it is not null
|
||||||
|
stmt->bind was initialized in mysql_stmt_prepare
|
||||||
|
*/
|
||||||
|
|
||||||
memcpy((char*) stmt->bind, (char*) bind,
|
memcpy((char*) stmt->bind, (char*) bind,
|
||||||
sizeof(MYSQL_BIND)*bind_count);
|
sizeof(MYSQL_BIND)*bind_count);
|
||||||
@ -2929,7 +3150,7 @@ my_bool STDCALL mysql_stmt_bind_result(MYSQL_STMT *stmt, MYSQL_BIND *bind)
|
|||||||
DBUG_RETURN(1);
|
DBUG_RETURN(1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
stmt->res_buffers= 1;
|
stmt->bind_result_done= TRUE;
|
||||||
DBUG_RETURN(0);
|
DBUG_RETURN(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2943,9 +3164,18 @@ static int stmt_fetch_row(MYSQL_STMT *stmt, uchar *row)
|
|||||||
MYSQL_BIND *bind, *end;
|
MYSQL_BIND *bind, *end;
|
||||||
MYSQL_FIELD *field, *field_end;
|
MYSQL_FIELD *field, *field_end;
|
||||||
uchar *null_ptr, bit;
|
uchar *null_ptr, bit;
|
||||||
|
/*
|
||||||
|
Precondition: if stmt->field_count is zero or row is NULL, read_row_*
|
||||||
|
function must return no data.
|
||||||
|
*/
|
||||||
|
DBUG_ASSERT(stmt->field_count);
|
||||||
|
DBUG_ASSERT(row);
|
||||||
|
|
||||||
if (!row || !stmt->res_buffers)
|
if (!stmt->bind_result_done)
|
||||||
|
{
|
||||||
|
/* If output parameters were not bound we should just return success */
|
||||||
return 0;
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
null_ptr= row;
|
null_ptr= row;
|
||||||
row+= (stmt->field_count+9)/8; /* skip null bits */
|
row+= (stmt->field_count+9)/8; /* skip null bits */
|
||||||
@ -2994,57 +3224,22 @@ int cli_unbuffered_fetch(MYSQL *mysql, char **row)
|
|||||||
|
|
||||||
int STDCALL mysql_stmt_fetch(MYSQL_STMT *stmt)
|
int STDCALL mysql_stmt_fetch(MYSQL_STMT *stmt)
|
||||||
{
|
{
|
||||||
MYSQL *mysql= stmt->mysql;
|
int rc;
|
||||||
uchar *row;
|
uchar *row;
|
||||||
DBUG_ENTER("mysql_stmt_fetch");
|
DBUG_ENTER("mysql_stmt_fetch");
|
||||||
|
|
||||||
stmt->last_fetched_column= 0; /* reset */
|
if ((rc= (*stmt->read_row_func)(stmt, &row)) ||
|
||||||
if (stmt->result_buffered) /* buffered */
|
(rc= stmt_fetch_row(stmt, row)))
|
||||||
{
|
{
|
||||||
MYSQL_RES *res;
|
stmt->state= MYSQL_STMT_PREPARE_DONE; /* XXX: this is buggy */
|
||||||
|
stmt->read_row_func= stmt_read_row_no_data;
|
||||||
if (!(res= stmt->result))
|
}
|
||||||
goto no_data;
|
else
|
||||||
|
|
||||||
if (!res->data_cursor)
|
|
||||||
{
|
{
|
||||||
stmt->current_row= 0;
|
/* This is to know in mysql_stmt_fetch_column that data was fetched */
|
||||||
goto no_data;
|
stmt->state= MYSQL_STMT_FETCH_DONE;
|
||||||
}
|
}
|
||||||
row= (uchar *)res->data_cursor->data;
|
DBUG_RETURN(rc);
|
||||||
res->data_cursor= res->data_cursor->next;
|
|
||||||
}
|
|
||||||
else /* un-buffered */
|
|
||||||
{
|
|
||||||
if (mysql->status != MYSQL_STATUS_GET_RESULT)
|
|
||||||
{
|
|
||||||
if (!stmt->field_count)
|
|
||||||
goto no_data;
|
|
||||||
|
|
||||||
set_stmt_error(stmt, CR_COMMANDS_OUT_OF_SYNC, unknown_sqlstate);
|
|
||||||
DBUG_RETURN(1);
|
|
||||||
}
|
|
||||||
|
|
||||||
if ((*mysql->methods->unbuffered_fetch)(mysql, (char**) &row))
|
|
||||||
{
|
|
||||||
set_stmt_errmsg(stmt, mysql->net.last_error, mysql->net.last_errno,
|
|
||||||
mysql->net.sqlstate);
|
|
||||||
DBUG_RETURN(1);
|
|
||||||
}
|
|
||||||
if (!row)
|
|
||||||
{
|
|
||||||
mysql->status= MYSQL_STATUS_READY;
|
|
||||||
stmt->current_row= 0;
|
|
||||||
goto no_data;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
stmt->current_row= row;
|
|
||||||
DBUG_RETURN(stmt_fetch_row(stmt, row));
|
|
||||||
|
|
||||||
no_data:
|
|
||||||
DBUG_PRINT("info", ("end of data"));
|
|
||||||
DBUG_RETURN(MYSQL_NO_DATA); /* no more data */
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -3070,8 +3265,17 @@ int STDCALL mysql_stmt_fetch_column(MYSQL_STMT *stmt, MYSQL_BIND *bind,
|
|||||||
MYSQL_BIND *param= stmt->bind+column;
|
MYSQL_BIND *param= stmt->bind+column;
|
||||||
DBUG_ENTER("mysql_stmt_fetch_column");
|
DBUG_ENTER("mysql_stmt_fetch_column");
|
||||||
|
|
||||||
if (!stmt->current_row)
|
if ((int) stmt->state < (int) MYSQL_STMT_FETCH_DONE)
|
||||||
goto no_data;
|
{
|
||||||
|
set_stmt_error(stmt, CR_NO_DATA, unknown_sqlstate);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
if (column >= stmt->field_count)
|
||||||
|
{
|
||||||
|
set_stmt_error(stmt, CR_INVALID_PARAMETER_NO, unknown_sqlstate);
|
||||||
|
DBUG_RETURN(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
if (param->null_field)
|
if (param->null_field)
|
||||||
{
|
{
|
||||||
@ -3092,10 +3296,6 @@ int STDCALL mysql_stmt_fetch_column(MYSQL_STMT *stmt, MYSQL_BIND *bind,
|
|||||||
fetch_results(bind, field, &row);
|
fetch_results(bind, field, &row);
|
||||||
}
|
}
|
||||||
DBUG_RETURN(0);
|
DBUG_RETURN(0);
|
||||||
|
|
||||||
no_data:
|
|
||||||
DBUG_PRINT("info", ("end of data"));
|
|
||||||
DBUG_RETURN(MYSQL_NO_DATA); /* no more data */
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -3111,7 +3311,7 @@ MYSQL_DATA *cli_read_binary_rows(MYSQL_STMT *stmt)
|
|||||||
MYSQL_DATA *result;
|
MYSQL_DATA *result;
|
||||||
MYSQL_ROWS *cur, **prev_ptr;
|
MYSQL_ROWS *cur, **prev_ptr;
|
||||||
NET *net = &mysql->net;
|
NET *net = &mysql->net;
|
||||||
DBUG_ENTER("read_binary_rows");
|
DBUG_ENTER("cli_read_binary_rows");
|
||||||
|
|
||||||
mysql= mysql->last_used_con;
|
mysql= mysql->last_used_con;
|
||||||
if ((pkt_len= net_safe_read(mysql)) == packet_error)
|
if ((pkt_len= net_safe_read(mysql)) == packet_error)
|
||||||
@ -3181,33 +3381,37 @@ int STDCALL mysql_stmt_store_result(MYSQL_STMT *stmt)
|
|||||||
|
|
||||||
if (!stmt->field_count)
|
if (!stmt->field_count)
|
||||||
DBUG_RETURN(0);
|
DBUG_RETURN(0);
|
||||||
if (mysql->status != MYSQL_STATUS_GET_RESULT)
|
if ((int) stmt->state < (int) MYSQL_STMT_EXECUTE_DONE ||
|
||||||
|
mysql->status != MYSQL_STATUS_GET_RESULT)
|
||||||
{
|
{
|
||||||
set_stmt_error(stmt, CR_COMMANDS_OUT_OF_SYNC, unknown_sqlstate);
|
set_stmt_error(stmt, CR_COMMANDS_OUT_OF_SYNC, unknown_sqlstate);
|
||||||
DBUG_RETURN(1);
|
DBUG_RETURN(1);
|
||||||
}
|
}
|
||||||
mysql->status= MYSQL_STATUS_READY; /* server is ready */
|
if (!(result= (MYSQL_RES*) my_malloc(sizeof(MYSQL_RES),
|
||||||
if (!(result= (MYSQL_RES*) my_malloc((uint) (sizeof(MYSQL_RES)+
|
|
||||||
sizeof(ulong) *
|
|
||||||
stmt->field_count),
|
|
||||||
MYF(MY_WME | MY_ZEROFILL))))
|
MYF(MY_WME | MY_ZEROFILL))))
|
||||||
{
|
{
|
||||||
set_stmt_error(stmt, CR_OUT_OF_MEMORY, unknown_sqlstate);
|
set_stmt_error(stmt, CR_OUT_OF_MEMORY, unknown_sqlstate);
|
||||||
DBUG_RETURN(1);
|
DBUG_RETURN(1);
|
||||||
}
|
}
|
||||||
result->methods= mysql->methods;
|
result->methods= mysql->methods;
|
||||||
stmt->result_buffered= 1;
|
if ((result->data= (*mysql->methods->read_binary_rows)(stmt)))
|
||||||
if (!(result->data= (*stmt->mysql->methods->read_binary_rows)(stmt)))
|
{
|
||||||
|
result->row_count= result->data->rows;
|
||||||
|
result->data_cursor= result->data->data;
|
||||||
|
}
|
||||||
|
else if (stmt->last_errno)
|
||||||
{
|
{
|
||||||
my_free((gptr) result,MYF(0));
|
my_free((gptr) result,MYF(0));
|
||||||
DBUG_RETURN(0);
|
DBUG_RETURN(1);
|
||||||
}
|
}
|
||||||
mysql->affected_rows= result->row_count= result->data->rows;
|
mysql->affected_rows= stmt->affected_rows= result->row_count;
|
||||||
stmt->affected_rows= result->row_count;
|
|
||||||
result->data_cursor= result->data->data;
|
|
||||||
result->fields= stmt->fields;
|
result->fields= stmt->fields;
|
||||||
result->field_count= stmt->field_count;
|
result->field_count= stmt->field_count;
|
||||||
|
/* The rest of MYSQL_RES members were bzeroed inside my_malloc */
|
||||||
stmt->result= result;
|
stmt->result= result;
|
||||||
|
stmt->read_row_func= stmt_read_row_buffered;
|
||||||
|
mysql->unbuffered_fetch_owner= 0; /* set in stmt_execute */
|
||||||
|
mysql->status= MYSQL_STATUS_READY; /* server is ready */
|
||||||
DBUG_RETURN(0); /* Data buffered, must be fetched with mysql_stmt_fetch() */
|
DBUG_RETURN(0); /* Data buffered, must be fetched with mysql_stmt_fetch() */
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -3292,6 +3496,40 @@ my_ulonglong STDCALL mysql_stmt_num_rows(MYSQL_STMT *stmt)
|
|||||||
DBUG_RETURN(0);
|
DBUG_RETURN(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
my_bool STDCALL mysql_stmt_free_result(MYSQL_STMT *stmt)
|
||||||
|
{
|
||||||
|
DBUG_ENTER("mysql_stmt_free_result");
|
||||||
|
|
||||||
|
DBUG_ASSERT(stmt != 0);
|
||||||
|
|
||||||
|
if ((int) stmt->state > (int) MYSQL_STMT_INIT_DONE)
|
||||||
|
{
|
||||||
|
MYSQL *mysql= stmt->mysql;
|
||||||
|
|
||||||
|
if (stmt->result)
|
||||||
|
{
|
||||||
|
/* Result buffered */
|
||||||
|
mysql_free_result(stmt->result);
|
||||||
|
stmt->result= 0;
|
||||||
|
}
|
||||||
|
else if (mysql && stmt->field_count
|
||||||
|
&& (int) stmt->state > (int) MYSQL_STMT_PREPARE_DONE)
|
||||||
|
{
|
||||||
|
if (mysql->unbuffered_fetch_owner == &stmt->unbuffered_fetch_cancelled)
|
||||||
|
mysql->unbuffered_fetch_owner= 0;
|
||||||
|
if (mysql->status != MYSQL_STATUS_READY)
|
||||||
|
{
|
||||||
|
/* There is a result set and it belongs to this statement */
|
||||||
|
flush_use_result(mysql);
|
||||||
|
mysql->status= MYSQL_STATUS_READY;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
stmt->state= MYSQL_STMT_PREPARE_DONE;
|
||||||
|
stmt->read_row_func= stmt_read_row_no_data;
|
||||||
|
}
|
||||||
|
DBUG_RETURN(0);
|
||||||
|
}
|
||||||
|
|
||||||
/********************************************************************
|
/********************************************************************
|
||||||
statement error handling and close
|
statement error handling and close
|
||||||
*********************************************************************/
|
*********************************************************************/
|
||||||
@ -3300,82 +3538,55 @@ my_ulonglong STDCALL mysql_stmt_num_rows(MYSQL_STMT *stmt)
|
|||||||
Close the statement handle by freeing all alloced resources
|
Close the statement handle by freeing all alloced resources
|
||||||
|
|
||||||
SYNOPSIS
|
SYNOPSIS
|
||||||
mysql_stmt_free_result()
|
mysql_stmt_close()
|
||||||
stmt Statement handle
|
stmt Statement handle
|
||||||
skip_list Flag to indicate delete from list or not
|
|
||||||
RETURN VALUES
|
RETURN VALUES
|
||||||
0 ok
|
0 ok
|
||||||
1 error
|
1 error
|
||||||
*/
|
*/
|
||||||
|
|
||||||
my_bool STDCALL mysql_stmt_free_result(MYSQL_STMT *stmt)
|
my_bool STDCALL mysql_stmt_close(MYSQL_STMT *stmt)
|
||||||
{
|
{
|
||||||
MYSQL *mysql;
|
MYSQL *mysql= stmt->mysql;
|
||||||
DBUG_ENTER("mysql_stmt_free_result");
|
int rc= 0;
|
||||||
|
DBUG_ENTER("mysql_stmt_close");
|
||||||
|
|
||||||
DBUG_ASSERT(stmt != 0);
|
mysql_free_result(stmt->result); /* if result is buffered */
|
||||||
|
free_root(&stmt->mem_root, MYF(0));
|
||||||
|
|
||||||
mysql= stmt->mysql;
|
if (mysql)
|
||||||
if (mysql->status != MYSQL_STATUS_READY)
|
|
||||||
{
|
{
|
||||||
/* Clear the current execution status */
|
mysql->stmts= list_delete(mysql->stmts, &stmt->list);
|
||||||
DBUG_PRINT("warning",("Not all packets read, clearing them"));
|
if ((int) stmt->state > (int) MYSQL_STMT_INIT_DONE)
|
||||||
for (;;)
|
|
||||||
{
|
|
||||||
ulong pkt_len;
|
|
||||||
if ((pkt_len= net_safe_read(mysql)) == packet_error)
|
|
||||||
break;
|
|
||||||
if (pkt_len <= 8 && mysql->net.read_pos[0] == 254)
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
mysql->status= MYSQL_STATUS_READY;
|
|
||||||
}
|
|
||||||
mysql_free_result(stmt->result);
|
|
||||||
stmt->result= 0;
|
|
||||||
stmt->result_buffered= 0;
|
|
||||||
stmt->current_row= 0;
|
|
||||||
DBUG_RETURN(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
my_bool stmt_close(MYSQL_STMT *stmt, my_bool skip_free)
|
|
||||||
{
|
|
||||||
MYSQL *mysql;
|
|
||||||
DBUG_ENTER("stmt_close");
|
|
||||||
|
|
||||||
DBUG_ASSERT(stmt != 0);
|
|
||||||
|
|
||||||
if (!(mysql= stmt->mysql))
|
|
||||||
{
|
|
||||||
if (!skip_free)
|
|
||||||
my_free((gptr) stmt, MYF(MY_WME));
|
|
||||||
DBUG_RETURN(0);
|
|
||||||
}
|
|
||||||
mysql_stmt_free_result(stmt);
|
|
||||||
if (stmt->state == MY_ST_PREPARE || stmt->state == MY_ST_EXECUTE)
|
|
||||||
{
|
{
|
||||||
char buff[4];
|
char buff[4];
|
||||||
|
|
||||||
|
if (mysql->unbuffered_fetch_owner == &stmt->unbuffered_fetch_cancelled)
|
||||||
|
mysql->unbuffered_fetch_owner= 0;
|
||||||
|
if (mysql->status != MYSQL_STATUS_READY)
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
Flush result set of the connection. If it does not belong
|
||||||
|
to this statement, set a warning.
|
||||||
|
*/
|
||||||
|
flush_use_result(mysql);
|
||||||
|
if (mysql->unbuffered_fetch_owner)
|
||||||
|
*mysql->unbuffered_fetch_owner= TRUE;
|
||||||
|
mysql->status= MYSQL_STATUS_READY;
|
||||||
|
}
|
||||||
int4store(buff, stmt->stmt_id);
|
int4store(buff, stmt->stmt_id);
|
||||||
if (skip_free || simple_command(mysql, COM_CLOSE_STMT, buff, 4, 1))
|
if ((rc= simple_command(mysql, COM_CLOSE_STMT, buff, 4, 1)))
|
||||||
{
|
{
|
||||||
set_stmt_errmsg(stmt, mysql->net.last_error, mysql->net.last_errno,
|
set_stmt_errmsg(stmt, mysql->net.last_error, mysql->net.last_errno,
|
||||||
mysql->net.sqlstate);
|
mysql->net.sqlstate);
|
||||||
stmt->mysql= NULL; /* connection isn't valid anymore */
|
|
||||||
DBUG_RETURN(1);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
stmt->field_count= 0;
|
}
|
||||||
free_root(&stmt->mem_root, MYF(0));
|
|
||||||
mysql->stmts= list_delete(mysql->stmts, &stmt->list);
|
|
||||||
mysql->status= MYSQL_STATUS_READY;
|
|
||||||
my_free((gptr) stmt, MYF(MY_WME));
|
my_free((gptr) stmt, MYF(MY_WME));
|
||||||
DBUG_RETURN(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
DBUG_RETURN(test(rc));
|
||||||
my_bool STDCALL mysql_stmt_close(MYSQL_STMT *stmt)
|
|
||||||
{
|
|
||||||
return stmt_close(stmt, 0);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -3389,6 +3600,10 @@ my_bool STDCALL mysql_stmt_reset(MYSQL_STMT *stmt)
|
|||||||
DBUG_ENTER("mysql_stmt_reset");
|
DBUG_ENTER("mysql_stmt_reset");
|
||||||
DBUG_ASSERT(stmt != 0);
|
DBUG_ASSERT(stmt != 0);
|
||||||
|
|
||||||
|
/* If statement hasnt been prepared there is nothing to reset */
|
||||||
|
if ((int) stmt->state < (int) MYSQL_STMT_PREPARE_DONE)
|
||||||
|
DBUG_RETURN(0);
|
||||||
|
|
||||||
mysql= stmt->mysql->last_used_con;
|
mysql= stmt->mysql->last_used_con;
|
||||||
int4store(buff, stmt->stmt_id); /* Send stmt id to server */
|
int4store(buff, stmt->stmt_id); /* Send stmt id to server */
|
||||||
if ((*mysql->methods->advanced_command)(mysql, COM_RESET_STMT,buff,MYSQL_STMT_HEADER,0,0,1))
|
if ((*mysql->methods->advanced_command)(mysql, COM_RESET_STMT,buff,MYSQL_STMT_HEADER,0,0,1))
|
||||||
|
@ -78,11 +78,11 @@ select str_to_date(concat('15-01-2001',' 2:59:58.999'),
|
|||||||
concat('%d-%m-%Y',' ','%H:%i:%s.%f'));
|
concat('%d-%m-%Y',' ','%H:%i:%s.%f'));
|
||||||
str_to_date(concat('15-01-2001',' 2:59:58.999'),
|
str_to_date(concat('15-01-2001',' 2:59:58.999'),
|
||||||
concat('%d-%m-%Y',' ','%H:%i:%s.%f'))
|
concat('%d-%m-%Y',' ','%H:%i:%s.%f'))
|
||||||
2001-01-15 02:59:58.000999
|
2001-01-15 02:59:58.999000
|
||||||
create table t1 (date char(30), format char(30) not null);
|
create table t1 (date char(30), format char(30) not null);
|
||||||
insert into t1 values
|
insert into t1 values
|
||||||
('2003-01-02 10:11:12', '%Y-%m-%d %H:%i:%S'),
|
('2003-01-02 10:11:12', '%Y-%m-%d %H:%i:%S'),
|
||||||
('03-01-02 8:11:2.123456', '%y-%m-%d %H:%i:%S'),
|
('03-01-02 8:11:2.123456', '%y-%m-%d %H:%i:%S.%#'),
|
||||||
('2003-01-02 10:11:12 PM', '%Y-%m-%d %h:%i:%S %p'),
|
('2003-01-02 10:11:12 PM', '%Y-%m-%d %h:%i:%S %p'),
|
||||||
('2003-01-02 01:11:12.12345AM', '%Y-%m-%d %h:%i:%S.%f%p'),
|
('2003-01-02 01:11:12.12345AM', '%Y-%m-%d %h:%i:%S.%f%p'),
|
||||||
('2003-01-02 02:11:12.12345AM', '%Y-%m-%d %h:%i:%S.%f %p'),
|
('2003-01-02 02:11:12.12345AM', '%Y-%m-%d %h:%i:%S.%f %p'),
|
||||||
@ -106,16 +106,16 @@ insert into t1 values
|
|||||||
select date,format,str_to_date(date, format) as str_to_date from t1;
|
select date,format,str_to_date(date, format) as str_to_date from t1;
|
||||||
date format str_to_date
|
date format str_to_date
|
||||||
2003-01-02 10:11:12 %Y-%m-%d %H:%i:%S 2003-01-02 10:11:12
|
2003-01-02 10:11:12 %Y-%m-%d %H:%i:%S 2003-01-02 10:11:12
|
||||||
03-01-02 8:11:2.123456 %y-%m-%d %H:%i:%S 2003-01-02 08:11:02
|
03-01-02 8:11:2.123456 %y-%m-%d %H:%i:%S.%# 2003-01-02 08:11:02
|
||||||
2003-01-02 10:11:12 PM %Y-%m-%d %h:%i:%S %p 2003-01-02 22:11:12
|
2003-01-02 10:11:12 PM %Y-%m-%d %h:%i:%S %p 2003-01-02 22:11:12
|
||||||
2003-01-02 01:11:12.12345AM %Y-%m-%d %h:%i:%S.%f%p 2003-01-02 01:11:12.012345
|
2003-01-02 01:11:12.12345AM %Y-%m-%d %h:%i:%S.%f%p 2003-01-02 01:11:12.123450
|
||||||
2003-01-02 02:11:12.12345AM %Y-%m-%d %h:%i:%S.%f %p 2003-01-02 02:11:12.012345
|
2003-01-02 02:11:12.12345AM %Y-%m-%d %h:%i:%S.%f %p 2003-01-02 02:11:12.123450
|
||||||
2003-01-02 12:11:12.12345 am %Y-%m-%d %h:%i:%S.%f%p 2003-01-02 00:11:12.012345
|
2003-01-02 12:11:12.12345 am %Y-%m-%d %h:%i:%S.%f%p 2003-01-02 00:11:12.123450
|
||||||
2003-01-02 11:11:12Pm %Y-%m-%d %h:%i:%S%p 2003-01-02 23:11:12
|
2003-01-02 11:11:12Pm %Y-%m-%d %h:%i:%S%p 2003-01-02 23:11:12
|
||||||
10:20:10 %H:%i:%s 0000-00-00 10:20:10
|
10:20:10 %H:%i:%s 0000-00-00 10:20:10
|
||||||
10:20:10 %h:%i:%s.%f 0000-00-00 10:20:10
|
10:20:10 %h:%i:%s.%f 0000-00-00 10:20:10
|
||||||
10:20:10AM %h:%i:%s%p 0000-00-00 10:20:10
|
10:20:10AM %h:%i:%s%p 0000-00-00 10:20:10
|
||||||
10:20:10.44AM %h:%i:%s.%f%p 0000-00-00 10:20:10.000044
|
10:20:10.44AM %h:%i:%s.%f%p 0000-00-00 10:20:10.440000
|
||||||
15-01-2001 12:59:58 %d-%m-%Y %H:%i:%S 2001-01-15 12:59:58
|
15-01-2001 12:59:58 %d-%m-%Y %H:%i:%S 2001-01-15 12:59:58
|
||||||
15 September 2001 %d %M %Y 2001-09-15 00:00:00
|
15 September 2001 %d %M %Y 2001-09-15 00:00:00
|
||||||
15 SEPTEMB 2001 %d %M %Y 2001-09-15 00:00:00
|
15 SEPTEMB 2001 %d %M %Y 2001-09-15 00:00:00
|
||||||
@ -130,16 +130,16 @@ Thursday 53 1998 %W %u %Y 1998-12-31 00:00:00
|
|||||||
select date,format,concat('',str_to_date(date, format)) as con from t1;
|
select date,format,concat('',str_to_date(date, format)) as con from t1;
|
||||||
date format con
|
date format con
|
||||||
2003-01-02 10:11:12 %Y-%m-%d %H:%i:%S 2003-01-02 10:11:12
|
2003-01-02 10:11:12 %Y-%m-%d %H:%i:%S 2003-01-02 10:11:12
|
||||||
03-01-02 8:11:2.123456 %y-%m-%d %H:%i:%S 2003-01-02 08:11:02
|
03-01-02 8:11:2.123456 %y-%m-%d %H:%i:%S.%# 2003-01-02 08:11:02
|
||||||
2003-01-02 10:11:12 PM %Y-%m-%d %h:%i:%S %p 2003-01-02 22:11:12
|
2003-01-02 10:11:12 PM %Y-%m-%d %h:%i:%S %p 2003-01-02 22:11:12
|
||||||
2003-01-02 01:11:12.12345AM %Y-%m-%d %h:%i:%S.%f%p 2003-01-02 01:11:12.012345
|
2003-01-02 01:11:12.12345AM %Y-%m-%d %h:%i:%S.%f%p 2003-01-02 01:11:12.123450
|
||||||
2003-01-02 02:11:12.12345AM %Y-%m-%d %h:%i:%S.%f %p 2003-01-02 02:11:12.012345
|
2003-01-02 02:11:12.12345AM %Y-%m-%d %h:%i:%S.%f %p 2003-01-02 02:11:12.123450
|
||||||
2003-01-02 12:11:12.12345 am %Y-%m-%d %h:%i:%S.%f%p 2003-01-02 00:11:12.012345
|
2003-01-02 12:11:12.12345 am %Y-%m-%d %h:%i:%S.%f%p 2003-01-02 00:11:12.123450
|
||||||
2003-01-02 11:11:12Pm %Y-%m-%d %h:%i:%S%p 2003-01-02 23:11:12
|
2003-01-02 11:11:12Pm %Y-%m-%d %h:%i:%S%p 2003-01-02 23:11:12
|
||||||
10:20:10 %H:%i:%s 0000-00-00 10:20:10
|
10:20:10 %H:%i:%s 0000-00-00 10:20:10
|
||||||
10:20:10 %h:%i:%s.%f 0000-00-00 10:20:10
|
10:20:10 %h:%i:%s.%f 0000-00-00 10:20:10
|
||||||
10:20:10AM %h:%i:%s%p 0000-00-00 10:20:10
|
10:20:10AM %h:%i:%s%p 0000-00-00 10:20:10
|
||||||
10:20:10.44AM %h:%i:%s.%f%p 0000-00-00 10:20:10.000044
|
10:20:10.44AM %h:%i:%s.%f%p 0000-00-00 10:20:10.440000
|
||||||
15-01-2001 12:59:58 %d-%m-%Y %H:%i:%S 2001-01-15 12:59:58
|
15-01-2001 12:59:58 %d-%m-%Y %H:%i:%S 2001-01-15 12:59:58
|
||||||
15 September 2001 %d %M %Y 2001-09-15 00:00:00
|
15 September 2001 %d %M %Y 2001-09-15 00:00:00
|
||||||
15 SEPTEMB 2001 %d %M %Y 2001-09-15 00:00:00
|
15 SEPTEMB 2001 %d %M %Y 2001-09-15 00:00:00
|
||||||
@ -154,16 +154,16 @@ Thursday 53 1998 %W %u %Y 1998-12-31 00:00:00
|
|||||||
select date,format,cast(str_to_date(date, format) as datetime) as datetime from t1;
|
select date,format,cast(str_to_date(date, format) as datetime) as datetime from t1;
|
||||||
date format datetime
|
date format datetime
|
||||||
2003-01-02 10:11:12 %Y-%m-%d %H:%i:%S 2003-01-02 10:11:12
|
2003-01-02 10:11:12 %Y-%m-%d %H:%i:%S 2003-01-02 10:11:12
|
||||||
03-01-02 8:11:2.123456 %y-%m-%d %H:%i:%S 2003-01-02 08:11:02
|
03-01-02 8:11:2.123456 %y-%m-%d %H:%i:%S.%# 2003-01-02 08:11:02
|
||||||
2003-01-02 10:11:12 PM %Y-%m-%d %h:%i:%S %p 2003-01-02 22:11:12
|
2003-01-02 10:11:12 PM %Y-%m-%d %h:%i:%S %p 2003-01-02 22:11:12
|
||||||
2003-01-02 01:11:12.12345AM %Y-%m-%d %h:%i:%S.%f%p 2003-01-02 01:11:12.012345
|
2003-01-02 01:11:12.12345AM %Y-%m-%d %h:%i:%S.%f%p 2003-01-02 01:11:12.123450
|
||||||
2003-01-02 02:11:12.12345AM %Y-%m-%d %h:%i:%S.%f %p 2003-01-02 02:11:12.012345
|
2003-01-02 02:11:12.12345AM %Y-%m-%d %h:%i:%S.%f %p 2003-01-02 02:11:12.123450
|
||||||
2003-01-02 12:11:12.12345 am %Y-%m-%d %h:%i:%S.%f%p 2003-01-02 00:11:12.012345
|
2003-01-02 12:11:12.12345 am %Y-%m-%d %h:%i:%S.%f%p 2003-01-02 00:11:12.123450
|
||||||
2003-01-02 11:11:12Pm %Y-%m-%d %h:%i:%S%p 2003-01-02 23:11:12
|
2003-01-02 11:11:12Pm %Y-%m-%d %h:%i:%S%p 2003-01-02 23:11:12
|
||||||
10:20:10 %H:%i:%s 0000-00-00 10:20:10
|
10:20:10 %H:%i:%s 0000-00-00 10:20:10
|
||||||
10:20:10 %h:%i:%s.%f 0000-00-00 10:20:10
|
10:20:10 %h:%i:%s.%f 0000-00-00 10:20:10
|
||||||
10:20:10AM %h:%i:%s%p 0000-00-00 10:20:10
|
10:20:10AM %h:%i:%s%p 0000-00-00 10:20:10
|
||||||
10:20:10.44AM %h:%i:%s.%f%p 0000-00-00 10:20:10.000044
|
10:20:10.44AM %h:%i:%s.%f%p 0000-00-00 10:20:10.440000
|
||||||
15-01-2001 12:59:58 %d-%m-%Y %H:%i:%S 2001-01-15 12:59:58
|
15-01-2001 12:59:58 %d-%m-%Y %H:%i:%S 2001-01-15 12:59:58
|
||||||
15 September 2001 %d %M %Y 2001-09-15 00:00:00
|
15 September 2001 %d %M %Y 2001-09-15 00:00:00
|
||||||
15 SEPTEMB 2001 %d %M %Y 2001-09-15 00:00:00
|
15 SEPTEMB 2001 %d %M %Y 2001-09-15 00:00:00
|
||||||
@ -178,7 +178,7 @@ Thursday 53 1998 %W %u %Y 1998-12-31 00:00:00
|
|||||||
select date,format,DATE(str_to_date(date, format)) as date2 from t1;
|
select date,format,DATE(str_to_date(date, format)) as date2 from t1;
|
||||||
date format date2
|
date format date2
|
||||||
2003-01-02 10:11:12 %Y-%m-%d %H:%i:%S 2003-01-02
|
2003-01-02 10:11:12 %Y-%m-%d %H:%i:%S 2003-01-02
|
||||||
03-01-02 8:11:2.123456 %y-%m-%d %H:%i:%S 2003-01-02
|
03-01-02 8:11:2.123456 %y-%m-%d %H:%i:%S.%# 2003-01-02
|
||||||
2003-01-02 10:11:12 PM %Y-%m-%d %h:%i:%S %p 2003-01-02
|
2003-01-02 10:11:12 PM %Y-%m-%d %h:%i:%S %p 2003-01-02
|
||||||
2003-01-02 01:11:12.12345AM %Y-%m-%d %h:%i:%S.%f%p 2003-01-02
|
2003-01-02 01:11:12.12345AM %Y-%m-%d %h:%i:%S.%f%p 2003-01-02
|
||||||
2003-01-02 02:11:12.12345AM %Y-%m-%d %h:%i:%S.%f %p 2003-01-02
|
2003-01-02 02:11:12.12345AM %Y-%m-%d %h:%i:%S.%f %p 2003-01-02
|
||||||
@ -202,16 +202,16 @@ Thursday 53 1998 %W %u %Y 1998-12-31
|
|||||||
select date,format,TIME(str_to_date(date, format)) as time from t1;
|
select date,format,TIME(str_to_date(date, format)) as time from t1;
|
||||||
date format time
|
date format time
|
||||||
2003-01-02 10:11:12 %Y-%m-%d %H:%i:%S 10:11:12
|
2003-01-02 10:11:12 %Y-%m-%d %H:%i:%S 10:11:12
|
||||||
03-01-02 8:11:2.123456 %y-%m-%d %H:%i:%S 08:11:02
|
03-01-02 8:11:2.123456 %y-%m-%d %H:%i:%S.%# 08:11:02
|
||||||
2003-01-02 10:11:12 PM %Y-%m-%d %h:%i:%S %p 22:11:12
|
2003-01-02 10:11:12 PM %Y-%m-%d %h:%i:%S %p 22:11:12
|
||||||
2003-01-02 01:11:12.12345AM %Y-%m-%d %h:%i:%S.%f%p 01:11:12.012345
|
2003-01-02 01:11:12.12345AM %Y-%m-%d %h:%i:%S.%f%p 01:11:12.123450
|
||||||
2003-01-02 02:11:12.12345AM %Y-%m-%d %h:%i:%S.%f %p 02:11:12.012345
|
2003-01-02 02:11:12.12345AM %Y-%m-%d %h:%i:%S.%f %p 02:11:12.123450
|
||||||
2003-01-02 12:11:12.12345 am %Y-%m-%d %h:%i:%S.%f%p 00:11:12.012345
|
2003-01-02 12:11:12.12345 am %Y-%m-%d %h:%i:%S.%f%p 00:11:12.123450
|
||||||
2003-01-02 11:11:12Pm %Y-%m-%d %h:%i:%S%p 23:11:12
|
2003-01-02 11:11:12Pm %Y-%m-%d %h:%i:%S%p 23:11:12
|
||||||
10:20:10 %H:%i:%s 10:20:10
|
10:20:10 %H:%i:%s 10:20:10
|
||||||
10:20:10 %h:%i:%s.%f 10:20:10
|
10:20:10 %h:%i:%s.%f 10:20:10
|
||||||
10:20:10AM %h:%i:%s%p 10:20:10
|
10:20:10AM %h:%i:%s%p 10:20:10
|
||||||
10:20:10.44AM %h:%i:%s.%f%p 10:20:10.000044
|
10:20:10.44AM %h:%i:%s.%f%p 10:20:10.440000
|
||||||
15-01-2001 12:59:58 %d-%m-%Y %H:%i:%S 12:59:58
|
15-01-2001 12:59:58 %d-%m-%Y %H:%i:%S 12:59:58
|
||||||
15 September 2001 %d %M %Y 00:00:00
|
15 September 2001 %d %M %Y 00:00:00
|
||||||
15 SEPTEMB 2001 %d %M %Y 00:00:00
|
15 SEPTEMB 2001 %d %M %Y 00:00:00
|
||||||
@ -226,16 +226,16 @@ Thursday 53 1998 %W %u %Y 00:00:00
|
|||||||
select date,format,concat(TIME(str_to_date(date, format))) as time2 from t1;
|
select date,format,concat(TIME(str_to_date(date, format))) as time2 from t1;
|
||||||
date format time2
|
date format time2
|
||||||
2003-01-02 10:11:12 %Y-%m-%d %H:%i:%S 10:11:12
|
2003-01-02 10:11:12 %Y-%m-%d %H:%i:%S 10:11:12
|
||||||
03-01-02 8:11:2.123456 %y-%m-%d %H:%i:%S 08:11:02
|
03-01-02 8:11:2.123456 %y-%m-%d %H:%i:%S.%# 08:11:02
|
||||||
2003-01-02 10:11:12 PM %Y-%m-%d %h:%i:%S %p 22:11:12
|
2003-01-02 10:11:12 PM %Y-%m-%d %h:%i:%S %p 22:11:12
|
||||||
2003-01-02 01:11:12.12345AM %Y-%m-%d %h:%i:%S.%f%p 01:11:12.012345
|
2003-01-02 01:11:12.12345AM %Y-%m-%d %h:%i:%S.%f%p 01:11:12.123450
|
||||||
2003-01-02 02:11:12.12345AM %Y-%m-%d %h:%i:%S.%f %p 02:11:12.012345
|
2003-01-02 02:11:12.12345AM %Y-%m-%d %h:%i:%S.%f %p 02:11:12.123450
|
||||||
2003-01-02 12:11:12.12345 am %Y-%m-%d %h:%i:%S.%f%p 00:11:12.012345
|
2003-01-02 12:11:12.12345 am %Y-%m-%d %h:%i:%S.%f%p 00:11:12.123450
|
||||||
2003-01-02 11:11:12Pm %Y-%m-%d %h:%i:%S%p 23:11:12
|
2003-01-02 11:11:12Pm %Y-%m-%d %h:%i:%S%p 23:11:12
|
||||||
10:20:10 %H:%i:%s 10:20:10
|
10:20:10 %H:%i:%s 10:20:10
|
||||||
10:20:10 %h:%i:%s.%f 10:20:10
|
10:20:10 %h:%i:%s.%f 10:20:10
|
||||||
10:20:10AM %h:%i:%s%p 10:20:10
|
10:20:10AM %h:%i:%s%p 10:20:10
|
||||||
10:20:10.44AM %h:%i:%s.%f%p 10:20:10.000044
|
10:20:10.44AM %h:%i:%s.%f%p 10:20:10.440000
|
||||||
15-01-2001 12:59:58 %d-%m-%Y %H:%i:%S 12:59:58
|
15-01-2001 12:59:58 %d-%m-%Y %H:%i:%S 12:59:58
|
||||||
15 September 2001 %d %M %Y 00:00:00
|
15 September 2001 %d %M %Y 00:00:00
|
||||||
15 SEPTEMB 2001 %d %M %Y 00:00:00
|
15 SEPTEMB 2001 %d %M %Y 00:00:00
|
||||||
@ -302,11 +302,15 @@ date format str_to_date
|
|||||||
10:20:10AM %h:%i:%s 0000-00-00 10:20:10
|
10:20:10AM %h:%i:%s 0000-00-00 10:20:10
|
||||||
2003-01-02 10:11:12 %Y-%m-%d %h:%i:%S 2003-01-02 10:11:12
|
2003-01-02 10:11:12 %Y-%m-%d %h:%i:%S 2003-01-02 10:11:12
|
||||||
03-01-02 10:11:12 PM %Y-%m-%d %h:%i:%S %p 0003-01-02 22:11:12
|
03-01-02 10:11:12 PM %Y-%m-%d %h:%i:%S %p 0003-01-02 22:11:12
|
||||||
|
Warnings:
|
||||||
|
Note 1292 Truncated wrong string value: '10:20:10AM'
|
||||||
select date,format,concat(str_to_date(date, format),'') as con from t1;
|
select date,format,concat(str_to_date(date, format),'') as con from t1;
|
||||||
date format con
|
date format con
|
||||||
10:20:10AM %h:%i:%s 0000-00-00 10:20:10
|
10:20:10AM %h:%i:%s 0000-00-00 10:20:10
|
||||||
2003-01-02 10:11:12 %Y-%m-%d %h:%i:%S 2003-01-02 10:11:12
|
2003-01-02 10:11:12 %Y-%m-%d %h:%i:%S 2003-01-02 10:11:12
|
||||||
03-01-02 10:11:12 PM %Y-%m-%d %h:%i:%S %p 0003-01-02 22:11:12
|
03-01-02 10:11:12 PM %Y-%m-%d %h:%i:%S %p 0003-01-02 22:11:12
|
||||||
|
Warnings:
|
||||||
|
Note 1292 Truncated wrong string value: '10:20:10AM'
|
||||||
drop table t1;
|
drop table t1;
|
||||||
select get_format(DATE, 'USA') as a;
|
select get_format(DATE, 'USA') as a;
|
||||||
a
|
a
|
||||||
@ -335,3 +339,56 @@ date_format(d,"%d")
|
|||||||
14
|
14
|
||||||
14
|
14
|
||||||
drop table t1;
|
drop table t1;
|
||||||
|
select str_to_date("2003-....01ABCD-02 10:11:12.0012", "%Y-%.%m%@-%d %H:%i:%S.%f") as a;
|
||||||
|
a
|
||||||
|
2003-01-02 10:11:12.001200
|
||||||
|
create table t1 select str_to_date("2003-01-02 10:11:12.0012", "%Y-%m-%d %H:%i:%S.%f") as f1,
|
||||||
|
str_to_date("10:11:12.0012", "%H:%i:%S.%f") as f2,
|
||||||
|
str_to_date("2003-01-02", "%Y-%m-%d") as f3,
|
||||||
|
str_to_date("02", "%d") as f4, str_to_date("02 10", "%d %H") as f5;
|
||||||
|
describe t1;
|
||||||
|
Field Type Null Key Default Extra
|
||||||
|
f1 datetime YES NULL
|
||||||
|
f2 time YES NULL
|
||||||
|
f3 date YES NULL
|
||||||
|
f4 date YES NULL
|
||||||
|
f5 time YES NULL
|
||||||
|
select * from t1;
|
||||||
|
f1 f2 f3 f4 f5
|
||||||
|
2003-01-02 10:11:12 10:11:12 2003-01-02 0000-00-02 58:00:00
|
||||||
|
drop table t1;
|
||||||
|
create table t1 select "02 10" as a, "%d %H" as b;
|
||||||
|
select str_to_date(a,b) from t1;
|
||||||
|
str_to_date(a,b)
|
||||||
|
0000-00-02 10:00:00
|
||||||
|
create table t2 select str_to_date(a,b) from t1;
|
||||||
|
describe t2;
|
||||||
|
Field Type Null Key Default Extra
|
||||||
|
str_to_date(a,b) char(29) YES NULL
|
||||||
|
select str_to_date("2003-01-02 10:11:12.0012", "%Y-%m-%d %H:%i:%S.%f") as f1,
|
||||||
|
str_to_date("2003-01-02 10:11:12.0012", "%Y-%m-%d %H:%i:%S") as f2,
|
||||||
|
str_to_date("2003-01-02", "%Y-%m-%d") as f3,
|
||||||
|
str_to_date("02 10:11:12", "%d %H:%i:%S.%f") as f4,
|
||||||
|
str_to_date("02 10:11:12", "%d %H:%i:%S") as f5,
|
||||||
|
str_to_date("02 10", "%d %f") as f6;
|
||||||
|
f1 f2 f3 f4 f5 f6
|
||||||
|
2003-01-02 10:11:12.001200 2003-01-02 10:11:12 2003-01-02 58:11:12 58:11:12 48:00:00.100000
|
||||||
|
Warnings:
|
||||||
|
Note 1292 Truncated wrong datetime value: '2003-01-02 10:11:12.0012'
|
||||||
|
drop table t1, t2;
|
||||||
|
select str_to_date("2003-01-02 10:11:12.0012ABCD", "%Y-%m-%d %H:%i:%S.%f") as f1,
|
||||||
|
addtime("-01:01:01.01 GGG", "-23:59:59.1") as f2,
|
||||||
|
microsecond("1997-12-31 23:59:59.01XXXX") as f3;
|
||||||
|
f1 f2 f3
|
||||||
|
2003-01-02 10:11:12.001200 -25:01:00.110000 10000
|
||||||
|
Warnings:
|
||||||
|
Note 1292 Truncated wrong datetime value: '2003-01-02 10:11:12.0012ABCD'
|
||||||
|
Note 1292 Truncated wrong time value: '-01:01:01.01 GG'
|
||||||
|
Note 1292 Truncated wrong datetime value: '1997-12-31 23:59:59.01XXXX'
|
||||||
|
select str_to_date("2003-04-05 g", "%Y-%m-%d") as f1,
|
||||||
|
str_to_date("2003-04-05 10:11:12.101010234567", "%Y-%m-%d %H:%i:%S.%f") as f2;
|
||||||
|
f1 f2
|
||||||
|
2003-04-05 2003-04-05 10:11:12.101010
|
||||||
|
Warnings:
|
||||||
|
Note 1292 Truncated wrong date value: '2003-04-05 g'
|
||||||
|
Note 1292 Truncated wrong datetime value: '2003-04-05 10:11:12.101010234567'
|
||||||
|
@ -198,3 +198,18 @@ NULL NULL
|
|||||||
NULL NULL
|
NULL NULL
|
||||||
00:00:00 -24:00:00
|
00:00:00 -24:00:00
|
||||||
drop table t1, test;
|
drop table t1, test;
|
||||||
|
select addtime("-01:01:01.01", "-23:59:59.1") as a;
|
||||||
|
a
|
||||||
|
-25:01:00.110000
|
||||||
|
select microsecond("1997-12-31 23:59:59.01") as a;
|
||||||
|
a
|
||||||
|
10000
|
||||||
|
select microsecond(19971231235959.01) as a;
|
||||||
|
a
|
||||||
|
10000
|
||||||
|
select date_add("1997-12-31",INTERVAL "10.09" SECOND_MICROSECOND) as a;
|
||||||
|
a
|
||||||
|
1997-12-31 00:00:10.090000
|
||||||
|
select str_to_date("2003-01-02 10:11:12.0012", "%Y-%m-%d %H:%i:%S.%f");
|
||||||
|
str_to_date("2003-01-02 10:11:12.0012", "%Y-%m-%d %H:%i:%S.%f")
|
||||||
|
2003-01-02 10:11:12.001200
|
||||||
|
@ -624,6 +624,9 @@ Note 1003 select high_priority md5(_latin1'hello') AS `md5('hello')`,sha(_latin1
|
|||||||
SELECT lpad(12345, 5, "#");
|
SELECT lpad(12345, 5, "#");
|
||||||
lpad(12345, 5, "#")
|
lpad(12345, 5, "#")
|
||||||
12345
|
12345
|
||||||
|
SELECT conv(71, 10, 36), conv('1Z', 36, 10);
|
||||||
|
conv(71, 10, 36) conv('1Z', 36, 10)
|
||||||
|
1Z 71
|
||||||
create table t1 (id int(1), str varchar(10)) DEFAULT CHARSET=utf8;
|
create table t1 (id int(1), str varchar(10)) DEFAULT CHARSET=utf8;
|
||||||
insert into t1 values (1,'aaaaaaaaaa'), (2,'bbbbbbbbbb');
|
insert into t1 values (1,'aaaaaaaaaa'), (2,'bbbbbbbbbb');
|
||||||
create table t2 (id int(1), str varchar(10)) DEFAULT CHARSET=utf8;
|
create table t2 (id int(1), str varchar(10)) DEFAULT CHARSET=utf8;
|
||||||
|
@ -506,17 +506,32 @@ last_day('2001-01-01 01:01:01') as f5, last_day(NULL),
|
|||||||
last_day('2001-02-12');
|
last_day('2001-02-12');
|
||||||
f1 f2 f3 f4 f5 last_day(NULL) last_day('2001-02-12')
|
f1 f2 f3 f4 f5 last_day(NULL) last_day('2001-02-12')
|
||||||
2000-02-29 2002-12-31 NULL 2003-04-30 2001-01-31 NULL 2001-02-28
|
2000-02-29 2002-12-31 NULL 2003-04-30 2001-01-31 NULL 2001-02-28
|
||||||
create table t1 select last_day('2000-02-05') as a;
|
create table t1 select last_day('2000-02-05') as a,
|
||||||
|
from_days(to_days("960101")) as b;
|
||||||
describe t1;
|
describe t1;
|
||||||
Field Type Null Key Default Extra
|
Field Type Null Key Default Extra
|
||||||
a date 0000-00-00
|
a date 0000-00-00
|
||||||
|
b date YES NULL
|
||||||
select * from t1;
|
select * from t1;
|
||||||
a
|
a b
|
||||||
2000-02-29
|
2000-02-29 1996-01-01
|
||||||
drop table t1;
|
drop table t1;
|
||||||
select last_day('2000-02-05');
|
select last_day('2000-02-05') as a,
|
||||||
last_day('2000-02-05')
|
from_days(to_days("960101")) as b;
|
||||||
2000-02-29
|
a b
|
||||||
|
2000-02-29 1996-01-01
|
||||||
|
select date_add(last_day("1997-12-1"), INTERVAL 1 DAY);
|
||||||
|
date_add(last_day("1997-12-1"), INTERVAL 1 DAY)
|
||||||
|
1998-01-01
|
||||||
|
select length(last_day("1997-12-1"));
|
||||||
|
length(last_day("1997-12-1"))
|
||||||
|
10
|
||||||
|
select last_day("1997-12-1")+0;
|
||||||
|
last_day("1997-12-1")+0
|
||||||
|
19971231
|
||||||
|
select last_day("1997-12-1")+0.0;
|
||||||
|
last_day("1997-12-1")+0.0
|
||||||
|
19971231.0
|
||||||
select strcmp(date_sub(localtimestamp(), interval 3 hour), utc_timestamp())=0;
|
select strcmp(date_sub(localtimestamp(), interval 3 hour), utc_timestamp())=0;
|
||||||
strcmp(date_sub(localtimestamp(), interval 3 hour), utc_timestamp())=0
|
strcmp(date_sub(localtimestamp(), interval 3 hour), utc_timestamp())=0
|
||||||
1
|
1
|
||||||
|
@ -25,9 +25,11 @@ t
|
|||||||
36:30:31
|
36:30:31
|
||||||
insert into t1 values("10.22.22"),(1234567),(123456789),(123456789.10),("10 22:22"),("12.45a");
|
insert into t1 values("10.22.22"),(1234567),(123456789),(123456789.10),("10 22:22"),("12.45a");
|
||||||
Warnings:
|
Warnings:
|
||||||
|
Note 1292 Truncated wrong time value: '10.22.22'
|
||||||
Warning 1264 Data truncated, out of range for column 't' at row 2
|
Warning 1264 Data truncated, out of range for column 't' at row 2
|
||||||
Warning 1264 Data truncated, out of range for column 't' at row 3
|
Warning 1264 Data truncated, out of range for column 't' at row 3
|
||||||
Warning 1264 Data truncated, out of range for column 't' at row 4
|
Warning 1264 Data truncated, out of range for column 't' at row 4
|
||||||
|
Note 1292 Truncated wrong time value: '12.45a'
|
||||||
select * from t1;
|
select * from t1;
|
||||||
t
|
t
|
||||||
10:22:33
|
10:22:33
|
||||||
|
@ -124,7 +124,7 @@ select str_to_date(concat('15-01-2001',' 2:59:58.999'),
|
|||||||
create table t1 (date char(30), format char(30) not null);
|
create table t1 (date char(30), format char(30) not null);
|
||||||
insert into t1 values
|
insert into t1 values
|
||||||
('2003-01-02 10:11:12', '%Y-%m-%d %H:%i:%S'),
|
('2003-01-02 10:11:12', '%Y-%m-%d %H:%i:%S'),
|
||||||
('03-01-02 8:11:2.123456', '%y-%m-%d %H:%i:%S'),
|
('03-01-02 8:11:2.123456', '%y-%m-%d %H:%i:%S.%#'),
|
||||||
('2003-01-02 10:11:12 PM', '%Y-%m-%d %h:%i:%S %p'),
|
('2003-01-02 10:11:12 PM', '%Y-%m-%d %h:%i:%S %p'),
|
||||||
('2003-01-02 01:11:12.12345AM', '%Y-%m-%d %h:%i:%S.%f%p'),
|
('2003-01-02 01:11:12.12345AM', '%Y-%m-%d %h:%i:%S.%f%p'),
|
||||||
('2003-01-02 02:11:12.12345AM', '%Y-%m-%d %h:%i:%S.%f %p'),
|
('2003-01-02 02:11:12.12345AM', '%Y-%m-%d %h:%i:%S.%f %p'),
|
||||||
@ -209,3 +209,32 @@ create table t1 (d date);
|
|||||||
insert into t1 values ('2004-07-14'),('2005-07-14');
|
insert into t1 values ('2004-07-14'),('2005-07-14');
|
||||||
select date_format(d,"%d") from t1 order by 1;
|
select date_format(d,"%d") from t1 order by 1;
|
||||||
drop table t1;
|
drop table t1;
|
||||||
|
|
||||||
|
select str_to_date("2003-....01ABCD-02 10:11:12.0012", "%Y-%.%m%@-%d %H:%i:%S.%f") as a;
|
||||||
|
|
||||||
|
|
||||||
|
create table t1 select str_to_date("2003-01-02 10:11:12.0012", "%Y-%m-%d %H:%i:%S.%f") as f1,
|
||||||
|
str_to_date("10:11:12.0012", "%H:%i:%S.%f") as f2,
|
||||||
|
str_to_date("2003-01-02", "%Y-%m-%d") as f3,
|
||||||
|
str_to_date("02", "%d") as f4, str_to_date("02 10", "%d %H") as f5;
|
||||||
|
describe t1;
|
||||||
|
select * from t1;
|
||||||
|
drop table t1;
|
||||||
|
|
||||||
|
create table t1 select "02 10" as a, "%d %H" as b;
|
||||||
|
select str_to_date(a,b) from t1;
|
||||||
|
create table t2 select str_to_date(a,b) from t1;
|
||||||
|
describe t2;
|
||||||
|
select str_to_date("2003-01-02 10:11:12.0012", "%Y-%m-%d %H:%i:%S.%f") as f1,
|
||||||
|
str_to_date("2003-01-02 10:11:12.0012", "%Y-%m-%d %H:%i:%S") as f2,
|
||||||
|
str_to_date("2003-01-02", "%Y-%m-%d") as f3,
|
||||||
|
str_to_date("02 10:11:12", "%d %H:%i:%S.%f") as f4,
|
||||||
|
str_to_date("02 10:11:12", "%d %H:%i:%S") as f5,
|
||||||
|
str_to_date("02 10", "%d %f") as f6;
|
||||||
|
drop table t1, t2;
|
||||||
|
select str_to_date("2003-01-02 10:11:12.0012ABCD", "%Y-%m-%d %H:%i:%S.%f") as f1,
|
||||||
|
addtime("-01:01:01.01 GGG", "-23:59:59.1") as f2,
|
||||||
|
microsecond("1997-12-31 23:59:59.01XXXX") as f3;
|
||||||
|
|
||||||
|
select str_to_date("2003-04-05 g", "%Y-%m-%d") as f1,
|
||||||
|
str_to_date("2003-04-05 10:11:12.101010234567", "%Y-%m-%d %H:%i:%S.%f") as f2;
|
||||||
|
@ -97,3 +97,9 @@ SELECT ADDTIME(t1,t2) As ttt, ADDTIME(t2, t3) As qqq from test;
|
|||||||
SELECT TIMEDIFF(t1,t4) As ttt, TIMEDIFF(t2, t3) As qqq from test;
|
SELECT TIMEDIFF(t1,t4) As ttt, TIMEDIFF(t2, t3) As qqq from test;
|
||||||
|
|
||||||
drop table t1, test;
|
drop table t1, test;
|
||||||
|
|
||||||
|
select addtime("-01:01:01.01", "-23:59:59.1") as a;
|
||||||
|
select microsecond("1997-12-31 23:59:59.01") as a;
|
||||||
|
select microsecond(19971231235959.01) as a;
|
||||||
|
select date_add("1997-12-31",INTERVAL "10.09" SECOND_MICROSECOND) as a;
|
||||||
|
select str_to_date("2003-01-02 10:11:12.0012", "%Y-%m-%d %H:%i:%S.%f");
|
||||||
|
@ -361,6 +361,13 @@ explain extended select md5('hello'), sha('abc'), sha1('abc'), soundex(''), 'moo
|
|||||||
|
|
||||||
SELECT lpad(12345, 5, "#");
|
SELECT lpad(12345, 5, "#");
|
||||||
|
|
||||||
|
#
|
||||||
|
# Bug #2972
|
||||||
|
#
|
||||||
|
|
||||||
|
SELECT conv(71, 10, 36), conv('1Z', 36, 10);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#
|
#
|
||||||
# Bug #3089
|
# Bug #3089
|
||||||
|
@ -249,12 +249,18 @@ select last_day('2000-02-05') as f1, last_day('2002-12-31') as f2,
|
|||||||
last_day('2001-01-01 01:01:01') as f5, last_day(NULL),
|
last_day('2001-01-01 01:01:01') as f5, last_day(NULL),
|
||||||
last_day('2001-02-12');
|
last_day('2001-02-12');
|
||||||
|
|
||||||
create table t1 select last_day('2000-02-05') as a;
|
create table t1 select last_day('2000-02-05') as a,
|
||||||
|
from_days(to_days("960101")) as b;
|
||||||
describe t1;
|
describe t1;
|
||||||
select * from t1;
|
select * from t1;
|
||||||
drop table t1;
|
drop table t1;
|
||||||
select last_day('2000-02-05');
|
select last_day('2000-02-05') as a,
|
||||||
|
from_days(to_days("960101")) as b;
|
||||||
|
|
||||||
|
select date_add(last_day("1997-12-1"), INTERVAL 1 DAY);
|
||||||
|
select length(last_day("1997-12-1"));
|
||||||
|
select last_day("1997-12-1")+0;
|
||||||
|
select last_day("1997-12-1")+0.0;
|
||||||
|
|
||||||
# Test SAPDB UTC_% functions. This part is TZ dependant (It is supposed that
|
# Test SAPDB UTC_% functions. This part is TZ dependant (It is supposed that
|
||||||
# TZ variable set to GMT-3
|
# TZ variable set to GMT-3
|
||||||
|
@ -712,6 +712,34 @@ void set_mysql_error(MYSQL *mysql, int errcode, const char *sqlstate)
|
|||||||
net->last_errno= errcode;
|
net->last_errno= errcode;
|
||||||
strmov(net->last_error, ER(errcode));
|
strmov(net->last_error, ER(errcode));
|
||||||
strmov(net->sqlstate, sqlstate);
|
strmov(net->sqlstate, sqlstate);
|
||||||
|
|
||||||
|
DBUG_VOID_RETURN;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
Flush result set sent from server
|
||||||
|
*/
|
||||||
|
|
||||||
|
void flush_use_result(MYSQL *mysql)
|
||||||
|
{
|
||||||
|
/* Clear the current execution status */
|
||||||
|
DBUG_PRINT("warning",("Not all packets read, clearing them"));
|
||||||
|
for (;;)
|
||||||
|
{
|
||||||
|
ulong pkt_len;
|
||||||
|
if ((pkt_len=net_safe_read(mysql)) == packet_error)
|
||||||
|
break;
|
||||||
|
if (pkt_len <= 8 && mysql->net.read_pos[0] == 254)
|
||||||
|
{
|
||||||
|
if (protocol_41(mysql))
|
||||||
|
{
|
||||||
|
char *pos= (char*) mysql->net.read_pos;
|
||||||
|
mysql->warning_count=uint2korr(pos); pos+=2;
|
||||||
|
mysql->server_status=uint2korr(pos); pos+=2;
|
||||||
|
}
|
||||||
|
break; /* End of data */
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -752,26 +780,16 @@ mysql_free_result(MYSQL_RES *result)
|
|||||||
DBUG_PRINT("enter",("mysql_res: %lx",result));
|
DBUG_PRINT("enter",("mysql_res: %lx",result));
|
||||||
if (result)
|
if (result)
|
||||||
{
|
{
|
||||||
if (result->handle && result->handle->status == MYSQL_STATUS_USE_RESULT)
|
MYSQL *mysql= result->handle;
|
||||||
|
if (mysql)
|
||||||
{
|
{
|
||||||
DBUG_PRINT("warning",("Not all rows in set where read; Ignoring rows"));
|
if (mysql->unbuffered_fetch_owner == &result->unbuffered_fetch_cancelled)
|
||||||
for (;;)
|
mysql->unbuffered_fetch_owner= 0;
|
||||||
|
if (mysql->status == MYSQL_STATUS_USE_RESULT)
|
||||||
{
|
{
|
||||||
ulong pkt_len;
|
flush_use_result(mysql);
|
||||||
if ((pkt_len=net_safe_read(result->handle)) == packet_error)
|
mysql->status=MYSQL_STATUS_READY;
|
||||||
break;
|
|
||||||
if (pkt_len <= 8 && result->handle->net.read_pos[0] == 254)
|
|
||||||
{
|
|
||||||
if (protocol_41(result->handle))
|
|
||||||
{
|
|
||||||
char *pos= (char*) result->handle->net.read_pos;
|
|
||||||
result->handle->warning_count=uint2korr(pos); pos+=2;
|
|
||||||
result->handle->server_status=uint2korr(pos); pos+=2;
|
|
||||||
}
|
}
|
||||||
break; /* End of data */
|
|
||||||
}
|
|
||||||
}
|
|
||||||
result->handle->status=MYSQL_STATUS_READY;
|
|
||||||
}
|
}
|
||||||
free_rows(result->data);
|
free_rows(result->data);
|
||||||
if (result->fields)
|
if (result->fields)
|
||||||
@ -2177,12 +2195,13 @@ void STDCALL mysql_close(MYSQL *mysql)
|
|||||||
#ifdef MYSQL_CLIENT
|
#ifdef MYSQL_CLIENT
|
||||||
if (mysql->stmts)
|
if (mysql->stmts)
|
||||||
{
|
{
|
||||||
/* Free any open prepared statements */
|
/* Reset connection handle in all prepared statements. */
|
||||||
LIST *element, *next_element;
|
LIST *element;
|
||||||
for (element= mysql->stmts; element; element= next_element)
|
for (element= mysql->stmts; element; element= element->next)
|
||||||
{
|
{
|
||||||
next_element= element->next;
|
MYSQL_STMT *stmt= (MYSQL_STMT *) element->data;
|
||||||
stmt_close((MYSQL_STMT *)element->data, 1);
|
stmt->mysql= 0;
|
||||||
|
/* No need to call list_delete for statement here */
|
||||||
}
|
}
|
||||||
mysql->stmts= 0;
|
mysql->stmts= 0;
|
||||||
}
|
}
|
||||||
@ -2372,9 +2391,10 @@ MYSQL_RES * STDCALL mysql_store_result(MYSQL *mysql)
|
|||||||
result->fields= mysql->fields;
|
result->fields= mysql->fields;
|
||||||
result->field_alloc= mysql->field_alloc;
|
result->field_alloc= mysql->field_alloc;
|
||||||
result->field_count= mysql->field_count;
|
result->field_count= mysql->field_count;
|
||||||
result->current_field=0;
|
/* The rest of result members is bzeroed in malloc */
|
||||||
result->current_row=0; /* Must do a fetch first */
|
|
||||||
mysql->fields=0; /* fields is now in result */
|
mysql->fields=0; /* fields is now in result */
|
||||||
|
/* just in case this was mistakenly called after mysql_stmt_execute() */
|
||||||
|
mysql->unbuffered_fetch_owner= 0;
|
||||||
DBUG_RETURN(result); /* Data fetched */
|
DBUG_RETURN(result); /* Data fetched */
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2423,6 +2443,7 @@ static MYSQL_RES * cli_use_result(MYSQL *mysql)
|
|||||||
result->current_row= 0;
|
result->current_row= 0;
|
||||||
mysql->fields=0; /* fields is now in result */
|
mysql->fields=0; /* fields is now in result */
|
||||||
mysql->status=MYSQL_STATUS_USE_RESULT;
|
mysql->status=MYSQL_STATUS_USE_RESULT;
|
||||||
|
mysql->unbuffered_fetch_owner= &result->unbuffered_fetch_cancelled;
|
||||||
DBUG_RETURN(result); /* Data is read to be fetched */
|
DBUG_RETURN(result); /* Data is read to be fetched */
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2439,20 +2460,31 @@ mysql_fetch_row(MYSQL_RES *res)
|
|||||||
{ /* Unbufferred fetch */
|
{ /* Unbufferred fetch */
|
||||||
if (!res->eof)
|
if (!res->eof)
|
||||||
{
|
{
|
||||||
if (!(read_one_row(res->handle,res->field_count,res->row, res->lengths)))
|
MYSQL *mysql= res->handle;
|
||||||
|
if (mysql->status != MYSQL_STATUS_USE_RESULT)
|
||||||
|
{
|
||||||
|
set_mysql_error(mysql,
|
||||||
|
res->unbuffered_fetch_cancelled ?
|
||||||
|
CR_FETCH_CANCELLED : CR_COMMANDS_OUT_OF_SYNC,
|
||||||
|
unknown_sqlstate);
|
||||||
|
}
|
||||||
|
else if (!(read_one_row(mysql, res->field_count, res->row, res->lengths)))
|
||||||
{
|
{
|
||||||
res->row_count++;
|
res->row_count++;
|
||||||
DBUG_RETURN(res->current_row=res->row);
|
DBUG_RETURN(res->current_row=res->row);
|
||||||
}
|
}
|
||||||
else
|
|
||||||
{
|
|
||||||
DBUG_PRINT("info",("end of data"));
|
DBUG_PRINT("info",("end of data"));
|
||||||
res->eof=1;
|
res->eof=1;
|
||||||
res->handle->status=MYSQL_STATUS_READY;
|
mysql->status=MYSQL_STATUS_READY;
|
||||||
/* Don't clear handle in mysql_free_results */
|
/*
|
||||||
|
Reset only if owner points to us: there is a chance that somebody
|
||||||
|
started new query after mysql_stmt_close():
|
||||||
|
*/
|
||||||
|
if (mysql->unbuffered_fetch_owner == &res->unbuffered_fetch_cancelled)
|
||||||
|
mysql->unbuffered_fetch_owner= 0;
|
||||||
|
/* Don't clear handle in mysql_free_result */
|
||||||
res->handle=0;
|
res->handle=0;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
DBUG_RETURN((MYSQL_ROW) NULL);
|
DBUG_RETURN((MYSQL_ROW) NULL);
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
|
@ -24,7 +24,7 @@
|
|||||||
enum Gis_read_stream::enum_tok_types Gis_read_stream::get_next_toc_type()
|
enum Gis_read_stream::enum_tok_types Gis_read_stream::get_next_toc_type()
|
||||||
{
|
{
|
||||||
skip_space();
|
skip_space();
|
||||||
if (!*m_cur)
|
if (m_cur >= m_limit)
|
||||||
return eostream;
|
return eostream;
|
||||||
if (my_isvar_start(&my_charset_bin, *m_cur))
|
if (my_isvar_start(&my_charset_bin, *m_cur))
|
||||||
return word;
|
return word;
|
||||||
@ -53,7 +53,7 @@ bool Gis_read_stream::get_next_word(LEX_STRING *res)
|
|||||||
my_isvar() is a macro that would cause side effects
|
my_isvar() is a macro that would cause side effects
|
||||||
*/
|
*/
|
||||||
m_cur++;
|
m_cur++;
|
||||||
while (my_isvar(&my_charset_bin, *m_cur))
|
while ((m_cur < m_limit) && my_isvar(&my_charset_bin, *m_cur))
|
||||||
m_cur++;
|
m_cur++;
|
||||||
|
|
||||||
res->length= (uint32) (m_cur - res->str);
|
res->length= (uint32) (m_cur - res->str);
|
||||||
@ -71,16 +71,21 @@ bool Gis_read_stream::get_next_word(LEX_STRING *res)
|
|||||||
bool Gis_read_stream::get_next_number(double *d)
|
bool Gis_read_stream::get_next_number(double *d)
|
||||||
{
|
{
|
||||||
char *endptr;
|
char *endptr;
|
||||||
|
int err;
|
||||||
|
|
||||||
skip_space();
|
skip_space();
|
||||||
/* The following will also test for end \0 */
|
|
||||||
if ((*m_cur < '0' || *m_cur > '9') && *m_cur != '-' && *m_cur != '+')
|
if ((m_cur >= m_limit) ||
|
||||||
|
(*m_cur < '0' || *m_cur > '9') && *m_cur != '-' && *m_cur != '+')
|
||||||
{
|
{
|
||||||
set_error_msg("Numeric constant expected");
|
set_error_msg("Numeric constant expected");
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
*d = my_strtod(m_cur, &endptr);
|
*d = my_strntod(m_charset, (char *)m_cur,
|
||||||
|
m_limit-m_cur, &endptr, &err);
|
||||||
|
if (err)
|
||||||
|
return 1;
|
||||||
if (endptr)
|
if (endptr)
|
||||||
m_cur = endptr;
|
m_cur = endptr;
|
||||||
return 0;
|
return 0;
|
||||||
@ -90,7 +95,7 @@ bool Gis_read_stream::get_next_number(double *d)
|
|||||||
bool Gis_read_stream::check_next_symbol(char symbol)
|
bool Gis_read_stream::check_next_symbol(char symbol)
|
||||||
{
|
{
|
||||||
skip_space();
|
skip_space();
|
||||||
if (*m_cur != symbol)
|
if ((m_cur >= m_limit) || (*m_cur != symbol))
|
||||||
{
|
{
|
||||||
char buff[32];
|
char buff[32];
|
||||||
strmov(buff, "'?' expected");
|
strmov(buff, "'?' expected");
|
||||||
|
@ -29,8 +29,8 @@ public:
|
|||||||
comma
|
comma
|
||||||
};
|
};
|
||||||
|
|
||||||
Gis_read_stream(const char *buffer, int size)
|
Gis_read_stream(CHARSET_INFO *charset, const char *buffer, int size)
|
||||||
:m_cur(buffer), m_limit(buffer + size), m_err_msg(NULL)
|
:m_cur(buffer), m_limit(buffer + size), m_err_msg(NULL), m_charset(charset)
|
||||||
{}
|
{}
|
||||||
Gis_read_stream(): m_cur(NullS), m_limit(NullS), m_err_msg(NullS)
|
Gis_read_stream(): m_cur(NullS), m_limit(NullS), m_err_msg(NullS)
|
||||||
{}
|
{}
|
||||||
@ -46,14 +46,14 @@ public:
|
|||||||
|
|
||||||
inline void skip_space()
|
inline void skip_space()
|
||||||
{
|
{
|
||||||
while (my_isspace(&my_charset_latin1, *m_cur))
|
while ((m_cur < m_limit) && my_isspace(&my_charset_latin1, *m_cur))
|
||||||
m_cur++;
|
m_cur++;
|
||||||
}
|
}
|
||||||
/* Skip next character, if match. Return 1 if no match */
|
/* Skip next character, if match. Return 1 if no match */
|
||||||
inline bool skip_char(char skip)
|
inline bool skip_char(char skip)
|
||||||
{
|
{
|
||||||
skip_space();
|
skip_space();
|
||||||
if (*m_cur != skip)
|
if ((m_cur >= m_limit) || *m_cur != skip)
|
||||||
return 1; /* Didn't find char */
|
return 1; /* Didn't find char */
|
||||||
m_cur++;
|
m_cur++;
|
||||||
return 0;
|
return 0;
|
||||||
@ -72,4 +72,5 @@ protected:
|
|||||||
const char *m_cur;
|
const char *m_cur;
|
||||||
const char *m_limit;
|
const char *m_limit;
|
||||||
char *m_err_msg;
|
char *m_err_msg;
|
||||||
|
CHARSET_INFO *m_charset;
|
||||||
};
|
};
|
||||||
|
28
sql/item.cc
28
sql/item.cc
@ -517,7 +517,33 @@ String *Item_null::val_str(String *str)
|
|||||||
{ null_value=1; return 0;}
|
{ null_value=1; return 0;}
|
||||||
|
|
||||||
|
|
||||||
/* Item_param related */
|
/*********************** Item_param related ******************************/
|
||||||
|
|
||||||
|
/*
|
||||||
|
Default function of Item_param::set_param_func, so in case
|
||||||
|
of malformed packet the server won't SIGSEGV
|
||||||
|
*/
|
||||||
|
|
||||||
|
static void
|
||||||
|
default_set_param_func(Item_param *param,
|
||||||
|
uchar **pos __attribute__((unused)),
|
||||||
|
ulong len __attribute__((unused)))
|
||||||
|
{
|
||||||
|
param->set_null();
|
||||||
|
}
|
||||||
|
|
||||||
|
Item_param::Item_param(unsigned position) :
|
||||||
|
value_is_set(FALSE),
|
||||||
|
item_result_type(STRING_RESULT),
|
||||||
|
item_type(STRING_ITEM),
|
||||||
|
item_is_time(FALSE),
|
||||||
|
long_data_supplied(FALSE),
|
||||||
|
pos_in_query(position),
|
||||||
|
set_param_func(default_set_param_func)
|
||||||
|
{
|
||||||
|
name= (char*) "?";
|
||||||
|
}
|
||||||
|
|
||||||
void Item_param::set_null()
|
void Item_param::set_null()
|
||||||
{
|
{
|
||||||
DBUG_ENTER("Item_param::set_null");
|
DBUG_ENTER("Item_param::set_null");
|
||||||
|
24
sql/item.h
24
sql/item.h
@ -348,16 +348,7 @@ public:
|
|||||||
bool long_data_supplied;
|
bool long_data_supplied;
|
||||||
uint pos_in_query;
|
uint pos_in_query;
|
||||||
|
|
||||||
Item_param(uint position)
|
Item_param(uint position);
|
||||||
{
|
|
||||||
name= (char*) "?";
|
|
||||||
pos_in_query= position;
|
|
||||||
item_type= STRING_ITEM;
|
|
||||||
item_result_type = STRING_RESULT;
|
|
||||||
item_is_time= false;
|
|
||||||
long_data_supplied= false;
|
|
||||||
value_is_set= 0;
|
|
||||||
}
|
|
||||||
enum Type type() const { return item_type; }
|
enum Type type() const { return item_type; }
|
||||||
double val();
|
double val();
|
||||||
longlong val_int();
|
longlong val_int();
|
||||||
@ -374,11 +365,14 @@ public:
|
|||||||
void set_time(TIME *tm, timestamp_type type);
|
void set_time(TIME *tm, timestamp_type type);
|
||||||
bool get_time(TIME *tm);
|
bool get_time(TIME *tm);
|
||||||
void reset() {}
|
void reset() {}
|
||||||
#ifndef EMBEDDED_LIBRARY
|
/*
|
||||||
void (*set_param_func)(Item_param *param, uchar **pos);
|
Assign placeholder value from bind data.
|
||||||
#else
|
Note, that 'len' has different semantics in embedded library (as we
|
||||||
void (*set_param_func)(Item_param *param, uchar **pos, ulong data_len);
|
don't need to check that packet is not broken there). See
|
||||||
#endif
|
sql_prepare.cc for details.
|
||||||
|
*/
|
||||||
|
void (*set_param_func)(Item_param *param, uchar **pos, ulong len);
|
||||||
|
|
||||||
enum Item_result result_type () const
|
enum Item_result result_type () const
|
||||||
{ return item_result_type; }
|
{ return item_result_type; }
|
||||||
String *query_val_str(String *str);
|
String *query_val_str(String *str);
|
||||||
|
@ -1728,7 +1728,7 @@ bool udf_handler::get_arguments() { return 0; }
|
|||||||
pthread_mutex_t LOCK_user_locks;
|
pthread_mutex_t LOCK_user_locks;
|
||||||
static HASH hash_user_locks;
|
static HASH hash_user_locks;
|
||||||
|
|
||||||
class ULL
|
class User_level_lock
|
||||||
{
|
{
|
||||||
char *key;
|
char *key;
|
||||||
uint key_length;
|
uint key_length;
|
||||||
@ -1740,7 +1740,7 @@ public:
|
|||||||
pthread_t thread;
|
pthread_t thread;
|
||||||
ulong thread_id;
|
ulong thread_id;
|
||||||
|
|
||||||
ULL(const char *key_arg,uint length, ulong id)
|
User_level_lock(const char *key_arg,uint length, ulong id)
|
||||||
:key_length(length),count(1),locked(1), thread_id(id)
|
:key_length(length),count(1),locked(1), thread_id(id)
|
||||||
{
|
{
|
||||||
key=(char*) my_memdup((byte*) key_arg,length,MYF(0));
|
key=(char*) my_memdup((byte*) key_arg,length,MYF(0));
|
||||||
@ -1754,7 +1754,7 @@ public:
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
~ULL()
|
~User_level_lock()
|
||||||
{
|
{
|
||||||
if (key)
|
if (key)
|
||||||
{
|
{
|
||||||
@ -1764,11 +1764,12 @@ public:
|
|||||||
pthread_cond_destroy(&cond);
|
pthread_cond_destroy(&cond);
|
||||||
}
|
}
|
||||||
inline bool initialized() { return key != 0; }
|
inline bool initialized() { return key != 0; }
|
||||||
friend void item_user_lock_release(ULL *ull);
|
friend void item_user_lock_release(User_level_lock *ull);
|
||||||
friend char *ull_get_key(const ULL *ull,uint *length,my_bool not_used);
|
friend char *ull_get_key(const User_level_lock *ull, uint *length,
|
||||||
|
my_bool not_used);
|
||||||
};
|
};
|
||||||
|
|
||||||
char *ull_get_key(const ULL *ull,uint *length,
|
char *ull_get_key(const User_level_lock *ull, uint *length,
|
||||||
my_bool not_used __attribute__((unused)))
|
my_bool not_used __attribute__((unused)))
|
||||||
{
|
{
|
||||||
*length=(uint) ull->key_length;
|
*length=(uint) ull->key_length;
|
||||||
@ -1796,7 +1797,7 @@ void item_user_lock_free(void)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void item_user_lock_release(ULL *ull)
|
void item_user_lock_release(User_level_lock *ull)
|
||||||
{
|
{
|
||||||
ull->locked=0;
|
ull->locked=0;
|
||||||
if (mysql_bin_log.is_open())
|
if (mysql_bin_log.is_open())
|
||||||
@ -1852,7 +1853,7 @@ longlong Item_master_pos_wait::val_int()
|
|||||||
void debug_sync_point(const char* lock_name, uint lock_timeout)
|
void debug_sync_point(const char* lock_name, uint lock_timeout)
|
||||||
{
|
{
|
||||||
THD* thd=current_thd;
|
THD* thd=current_thd;
|
||||||
ULL* ull;
|
User_level_lock* ull;
|
||||||
struct timespec abstime;
|
struct timespec abstime;
|
||||||
int lock_name_len,error=0;
|
int lock_name_len,error=0;
|
||||||
lock_name_len=strlen(lock_name);
|
lock_name_len=strlen(lock_name);
|
||||||
@ -1870,7 +1871,7 @@ void debug_sync_point(const char* lock_name, uint lock_timeout)
|
|||||||
this case, we will not be waiting, but rather, just waste CPU and
|
this case, we will not be waiting, but rather, just waste CPU and
|
||||||
memory on the whole deal
|
memory on the whole deal
|
||||||
*/
|
*/
|
||||||
if (!(ull= ((ULL*) hash_search(&hash_user_locks,lock_name,
|
if (!(ull= ((User_level_lock*) hash_search(&hash_user_locks, lock_name,
|
||||||
lock_name_len))))
|
lock_name_len))))
|
||||||
{
|
{
|
||||||
pthread_mutex_unlock(&LOCK_user_locks);
|
pthread_mutex_unlock(&LOCK_user_locks);
|
||||||
@ -1931,7 +1932,7 @@ longlong Item_func_get_lock::val_int()
|
|||||||
longlong timeout=args[1]->val_int();
|
longlong timeout=args[1]->val_int();
|
||||||
struct timespec abstime;
|
struct timespec abstime;
|
||||||
THD *thd=current_thd;
|
THD *thd=current_thd;
|
||||||
ULL *ull;
|
User_level_lock *ull;
|
||||||
int error=0;
|
int error=0;
|
||||||
|
|
||||||
pthread_mutex_lock(&LOCK_user_locks);
|
pthread_mutex_lock(&LOCK_user_locks);
|
||||||
@ -1950,10 +1951,11 @@ longlong Item_func_get_lock::val_int()
|
|||||||
thd->ull=0;
|
thd->ull=0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!(ull= ((ULL*) hash_search(&hash_user_locks,(byte*) res->ptr(),
|
if (!(ull= ((User_level_lock *) hash_search(&hash_user_locks,
|
||||||
|
(byte*) res->ptr(),
|
||||||
res->length()))))
|
res->length()))))
|
||||||
{
|
{
|
||||||
ull=new ULL(res->ptr(),res->length(), thd->thread_id);
|
ull=new User_level_lock(res->ptr(),res->length(), thd->thread_id);
|
||||||
if (!ull || !ull->initialized())
|
if (!ull || !ull->initialized())
|
||||||
{
|
{
|
||||||
delete ull;
|
delete ull;
|
||||||
@ -2022,7 +2024,7 @@ longlong Item_func_get_lock::val_int()
|
|||||||
longlong Item_func_release_lock::val_int()
|
longlong Item_func_release_lock::val_int()
|
||||||
{
|
{
|
||||||
String *res=args[0]->val_str(&value);
|
String *res=args[0]->val_str(&value);
|
||||||
ULL *ull;
|
User_level_lock *ull;
|
||||||
longlong result;
|
longlong result;
|
||||||
if (!res || !res->length())
|
if (!res || !res->length())
|
||||||
{
|
{
|
||||||
@ -2033,7 +2035,8 @@ longlong Item_func_release_lock::val_int()
|
|||||||
|
|
||||||
result=0;
|
result=0;
|
||||||
pthread_mutex_lock(&LOCK_user_locks);
|
pthread_mutex_lock(&LOCK_user_locks);
|
||||||
if (!(ull= ((ULL*) hash_search(&hash_user_locks,(const byte*) res->ptr(),
|
if (!(ull= ((User_level_lock*) hash_search(&hash_user_locks,
|
||||||
|
(const byte*) res->ptr(),
|
||||||
res->length()))))
|
res->length()))))
|
||||||
{
|
{
|
||||||
null_value=1;
|
null_value=1;
|
||||||
@ -3041,7 +3044,7 @@ longlong Item_func_is_free_lock::val_int()
|
|||||||
{
|
{
|
||||||
String *res=args[0]->val_str(&value);
|
String *res=args[0]->val_str(&value);
|
||||||
THD *thd=current_thd;
|
THD *thd=current_thd;
|
||||||
ULL *ull;
|
User_level_lock *ull;
|
||||||
|
|
||||||
null_value=0;
|
null_value=0;
|
||||||
if (!res || !res->length())
|
if (!res || !res->length())
|
||||||
@ -3051,7 +3054,7 @@ longlong Item_func_is_free_lock::val_int()
|
|||||||
}
|
}
|
||||||
|
|
||||||
pthread_mutex_lock(&LOCK_user_locks);
|
pthread_mutex_lock(&LOCK_user_locks);
|
||||||
ull= (ULL*) hash_search(&hash_user_locks,(byte*) res->ptr(),
|
ull= (User_level_lock *) hash_search(&hash_user_locks, (byte*) res->ptr(),
|
||||||
res->length());
|
res->length());
|
||||||
pthread_mutex_unlock(&LOCK_user_locks);
|
pthread_mutex_unlock(&LOCK_user_locks);
|
||||||
if (!ull || !ull->locked)
|
if (!ull || !ull->locked)
|
||||||
@ -3063,14 +3066,14 @@ longlong Item_func_is_used_lock::val_int()
|
|||||||
{
|
{
|
||||||
String *res=args[0]->val_str(&value);
|
String *res=args[0]->val_str(&value);
|
||||||
THD *thd=current_thd;
|
THD *thd=current_thd;
|
||||||
ULL *ull;
|
User_level_lock *ull;
|
||||||
|
|
||||||
null_value=1;
|
null_value=1;
|
||||||
if (!res || !res->length())
|
if (!res || !res->length())
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
pthread_mutex_lock(&LOCK_user_locks);
|
pthread_mutex_lock(&LOCK_user_locks);
|
||||||
ull= (ULL*) hash_search(&hash_user_locks,(byte*) res->ptr(),
|
ull= (User_level_lock *) hash_search(&hash_user_locks, (byte*) res->ptr(),
|
||||||
res->length());
|
res->length());
|
||||||
pthread_mutex_unlock(&LOCK_user_locks);
|
pthread_mutex_unlock(&LOCK_user_locks);
|
||||||
if (!ull || !ull->locked)
|
if (!ull || !ull->locked)
|
||||||
|
@ -864,9 +864,9 @@ public:
|
|||||||
** User level locks
|
** User level locks
|
||||||
*/
|
*/
|
||||||
|
|
||||||
class ULL;
|
class User_level_lock;
|
||||||
void item_user_lock_init(void);
|
void item_user_lock_init(void);
|
||||||
void item_user_lock_release(ULL *ull);
|
void item_user_lock_release(User_level_lock *ull);
|
||||||
void item_user_lock_free(void);
|
void item_user_lock_free(void);
|
||||||
|
|
||||||
class Item_func_get_lock :public Item_int_func
|
class Item_func_get_lock :public Item_int_func
|
||||||
|
@ -31,10 +31,13 @@
|
|||||||
String *Item_func_geometry_from_text::val_str(String *str)
|
String *Item_func_geometry_from_text::val_str(String *str)
|
||||||
{
|
{
|
||||||
Geometry_buffer buffer;
|
Geometry_buffer buffer;
|
||||||
Geometry *geom;
|
|
||||||
String arg_val;
|
String arg_val;
|
||||||
String *wkt= args[0]->val_str(&arg_val);
|
String *wkt= args[0]->val_str(&arg_val);
|
||||||
Gis_read_stream trs(wkt->c_ptr(), wkt->length());
|
|
||||||
|
if ((null_value= args[0]->null_value))
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
Gis_read_stream trs(wkt->charset(), wkt->ptr(), wkt->length());
|
||||||
uint32 srid= 0;
|
uint32 srid= 0;
|
||||||
|
|
||||||
if ((arg_count == 2) && !args[1]->null_value)
|
if ((arg_count == 2) && !args[1]->null_value)
|
||||||
@ -44,8 +47,7 @@ String *Item_func_geometry_from_text::val_str(String *str)
|
|||||||
return 0;
|
return 0;
|
||||||
str->length(0);
|
str->length(0);
|
||||||
str->q_append(srid);
|
str->q_append(srid);
|
||||||
if ((null_value=(args[0]->null_value ||
|
if ((null_value= !Geometry::create_from_wkt(&buffer, &trs, str, 0)))
|
||||||
!(geom= Geometry::create_from_wkt(&buffer, &trs, str, 0)))))
|
|
||||||
return 0;
|
return 0;
|
||||||
return str;
|
return str;
|
||||||
}
|
}
|
||||||
|
@ -2241,7 +2241,7 @@ String *Item_func_hex::val_str(String *str)
|
|||||||
return &tmp_value;
|
return &tmp_value;
|
||||||
}
|
}
|
||||||
|
|
||||||
int inline hexchar_to_int(char c)
|
inline int hexchar_to_int(char c)
|
||||||
{
|
{
|
||||||
if (c <= '9' && c >= '0')
|
if (c <= '9' && c >= '0')
|
||||||
return c-'0';
|
return c-'0';
|
||||||
@ -2731,7 +2731,7 @@ String *Item_func_uuid::val_str(String *str)
|
|||||||
randominit() here
|
randominit() here
|
||||||
*/
|
*/
|
||||||
randominit(&uuid_rand, tmp + (ulong)current_thd, tmp + query_id);
|
randominit(&uuid_rand, tmp + (ulong)current_thd, tmp + query_id);
|
||||||
for (i=0; i < sizeof(mac); i++)
|
for (i=0; i < (int)sizeof(mac); i++)
|
||||||
mac[i]=(uchar)(my_rnd(&uuid_rand)*255);
|
mac[i]=(uchar)(my_rnd(&uuid_rand)*255);
|
||||||
}
|
}
|
||||||
s=clock_seq_and_node_str+sizeof(clock_seq_and_node_str)-1;
|
s=clock_seq_and_node_str+sizeof(clock_seq_and_node_str)-1;
|
||||||
|
@ -48,11 +48,6 @@ TYPELIB day_names_typelib=
|
|||||||
{ array_elements(day_names)-1,"", day_names};
|
{ array_elements(day_names)-1,"", day_names};
|
||||||
|
|
||||||
|
|
||||||
enum date_time_format_types
|
|
||||||
{
|
|
||||||
TIME_ONLY= 0, TIME_MICROSECOND, DATE_ONLY, DATE_TIME, DATE_TIME_MICROSECOND
|
|
||||||
};
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
OPTIMIZATION TODO:
|
OPTIMIZATION TODO:
|
||||||
- Replace the switch with a function that should be called for each
|
- Replace the switch with a function that should be called for each
|
||||||
@ -128,6 +123,9 @@ static bool make_datetime(date_time_format_types format, TIME *ltime,
|
|||||||
val String to decode
|
val String to decode
|
||||||
length Length of string
|
length Length of string
|
||||||
l_time Store result here
|
l_time Store result here
|
||||||
|
cached_timestamp_type
|
||||||
|
It uses to get an appropriate warning
|
||||||
|
in the case when the value is truncated.
|
||||||
|
|
||||||
RETURN
|
RETURN
|
||||||
0 ok
|
0 ok
|
||||||
@ -135,7 +133,8 @@ static bool make_datetime(date_time_format_types format, TIME *ltime,
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
static bool extract_date_time(DATE_TIME_FORMAT *format,
|
static bool extract_date_time(DATE_TIME_FORMAT *format,
|
||||||
const char *val, uint length, TIME *l_time)
|
const char *val, uint length, TIME *l_time,
|
||||||
|
timestamp_type cached_timestamp_type)
|
||||||
{
|
{
|
||||||
int weekday= 0, yearday= 0, daypart= 0;
|
int weekday= 0, yearday= 0, daypart= 0;
|
||||||
int week_number= -1;
|
int week_number= -1;
|
||||||
@ -143,9 +142,11 @@ static bool extract_date_time(DATE_TIME_FORMAT *format,
|
|||||||
int error= 0;
|
int error= 0;
|
||||||
bool usa_time= 0;
|
bool usa_time= 0;
|
||||||
bool sunday_first= 0;
|
bool sunday_first= 0;
|
||||||
|
int frac_part;
|
||||||
|
const char *val_begin= val;
|
||||||
const char *val_end= val + length;
|
const char *val_end= val + length;
|
||||||
const char *ptr= format->format.str;
|
const char *ptr= format->format.str;
|
||||||
const char *end= ptr+ format->format.length;
|
const char *end= ptr + format->format.length;
|
||||||
DBUG_ENTER("extract_date_time");
|
DBUG_ENTER("extract_date_time");
|
||||||
|
|
||||||
bzero((char*) l_time, sizeof(*l_time));
|
bzero((char*) l_time, sizeof(*l_time));
|
||||||
@ -235,7 +236,12 @@ static bool extract_date_time(DATE_TIME_FORMAT *format,
|
|||||||
/* Second part */
|
/* Second part */
|
||||||
case 'f':
|
case 'f':
|
||||||
tmp= (char*) val_end;
|
tmp= (char*) val_end;
|
||||||
|
if (tmp - val > 6)
|
||||||
|
tmp= (char*) val + 6;
|
||||||
l_time->second_part= (int) my_strtoll10(val, &tmp, &error);
|
l_time->second_part= (int) my_strtoll10(val, &tmp, &error);
|
||||||
|
frac_part= 6 - (tmp - val);
|
||||||
|
if (frac_part > 0)
|
||||||
|
l_time->second_part*= (ulong) log_10_int[frac_part];
|
||||||
val= tmp;
|
val= tmp;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@ -251,6 +257,7 @@ static bool extract_date_time(DATE_TIME_FORMAT *format,
|
|||||||
(const uchar *) val, 2,
|
(const uchar *) val, 2,
|
||||||
(const uchar *) "AM", 2))
|
(const uchar *) "AM", 2))
|
||||||
goto err;
|
goto err;
|
||||||
|
val+= 2;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
/* Exotic things */
|
/* Exotic things */
|
||||||
@ -281,6 +288,18 @@ static bool extract_date_time(DATE_TIME_FORMAT *format,
|
|||||||
val= tmp;
|
val= tmp;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case '.':
|
||||||
|
while (my_ispunct(cs, *val) && val != val_end)
|
||||||
|
val++;
|
||||||
|
break;
|
||||||
|
case '@':
|
||||||
|
while (my_isalpha(cs, *val) && val != val_end)
|
||||||
|
val++;
|
||||||
|
break;
|
||||||
|
case '#':
|
||||||
|
while (my_isdigit(cs, *val) && val != val_end)
|
||||||
|
val++;
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
goto err;
|
goto err;
|
||||||
}
|
}
|
||||||
@ -348,6 +367,18 @@ static bool extract_date_time(DATE_TIME_FORMAT *format,
|
|||||||
l_time->minute > 59 || l_time->second > 59)
|
l_time->minute > 59 || l_time->second > 59)
|
||||||
goto err;
|
goto err;
|
||||||
|
|
||||||
|
if (val != val_end)
|
||||||
|
{
|
||||||
|
do
|
||||||
|
{
|
||||||
|
if (!my_isspace(&my_charset_latin1,*val))
|
||||||
|
{
|
||||||
|
make_truncated_value_warning(current_thd, val_begin, length,
|
||||||
|
cached_timestamp_type);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
} while (++val != val_end);
|
||||||
|
}
|
||||||
DBUG_RETURN(0);
|
DBUG_RETURN(0);
|
||||||
|
|
||||||
err:
|
err:
|
||||||
@ -584,16 +615,27 @@ bool make_date_time(DATE_TIME_FORMAT *format, TIME *l_time,
|
|||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
** Get a array of positive numbers from a string object.
|
Get a array of positive numbers from a string object.
|
||||||
** Each number is separated by 1 non digit character
|
Each number is separated by 1 non digit character
|
||||||
** Return error if there is too many numbers.
|
Return error if there is too many numbers.
|
||||||
** If there is too few numbers, assume that the numbers are left out
|
If there is too few numbers, assume that the numbers are left out
|
||||||
** from the high end. This allows one to give:
|
from the high end. This allows one to give:
|
||||||
** DAY_TO_SECOND as "D MM:HH:SS", "MM:HH:SS" "HH:SS" or as seconds.
|
DAY_TO_SECOND as "D MM:HH:SS", "MM:HH:SS" "HH:SS" or as seconds.
|
||||||
|
|
||||||
|
SYNOPSIS
|
||||||
|
str: string value
|
||||||
|
length: length of str
|
||||||
|
cs: charset of str
|
||||||
|
values: array of results
|
||||||
|
count: count of elements in result array
|
||||||
|
transform_msec: if value is true we suppose
|
||||||
|
that the last part of string value is microseconds
|
||||||
|
and we should transform value to six digit value.
|
||||||
|
For example, '1.1' -> '1.100000'
|
||||||
*/
|
*/
|
||||||
|
|
||||||
bool get_interval_info(const char *str,uint length,CHARSET_INFO *cs,
|
bool get_interval_info(const char *str,uint length,CHARSET_INFO *cs,
|
||||||
uint count, long *values)
|
uint count, long *values, bool transform_msec)
|
||||||
{
|
{
|
||||||
const char *end=str+length;
|
const char *end=str+length;
|
||||||
uint i;
|
uint i;
|
||||||
@ -603,8 +645,15 @@ bool get_interval_info(const char *str,uint length,CHARSET_INFO *cs,
|
|||||||
for (i=0 ; i < count ; i++)
|
for (i=0 ; i < count ; i++)
|
||||||
{
|
{
|
||||||
long value;
|
long value;
|
||||||
|
const char *start= str;
|
||||||
for (value=0; str != end && my_isdigit(cs,*str) ; str++)
|
for (value=0; str != end && my_isdigit(cs,*str) ; str++)
|
||||||
value=value*10L + (long) (*str - '0');
|
value=value*10L + (long) (*str - '0');
|
||||||
|
if (transform_msec && i == count - 1) // microseconds always last
|
||||||
|
{
|
||||||
|
long msec_length= 6 - (str - start);
|
||||||
|
if (msec_length > 0)
|
||||||
|
value*= (long) log_10_int[msec_length];
|
||||||
|
}
|
||||||
values[i]= value;
|
values[i]= value;
|
||||||
while (str != end && !my_isdigit(cs,*str))
|
while (str != end && !my_isdigit(cs,*str))
|
||||||
str++;
|
str++;
|
||||||
@ -925,19 +974,19 @@ static bool get_interval_value(Item *args,interval_type int_type,
|
|||||||
interval->second=value;
|
interval->second=value;
|
||||||
break;
|
break;
|
||||||
case INTERVAL_YEAR_MONTH: // Allow YEAR-MONTH YYYYYMM
|
case INTERVAL_YEAR_MONTH: // Allow YEAR-MONTH YYYYYMM
|
||||||
if (get_interval_info(str,length,cs,2,array))
|
if (get_interval_info(str,length,cs,2,array,0))
|
||||||
return (1);
|
return (1);
|
||||||
interval->year=array[0];
|
interval->year=array[0];
|
||||||
interval->month=array[1];
|
interval->month=array[1];
|
||||||
break;
|
break;
|
||||||
case INTERVAL_DAY_HOUR:
|
case INTERVAL_DAY_HOUR:
|
||||||
if (get_interval_info(str,length,cs,2,array))
|
if (get_interval_info(str,length,cs,2,array,0))
|
||||||
return (1);
|
return (1);
|
||||||
interval->day=array[0];
|
interval->day=array[0];
|
||||||
interval->hour=array[1];
|
interval->hour=array[1];
|
||||||
break;
|
break;
|
||||||
case INTERVAL_DAY_MICROSECOND:
|
case INTERVAL_DAY_MICROSECOND:
|
||||||
if (get_interval_info(str,length,cs,5,array))
|
if (get_interval_info(str,length,cs,5,array,1))
|
||||||
return (1);
|
return (1);
|
||||||
interval->day=array[0];
|
interval->day=array[0];
|
||||||
interval->hour=array[1];
|
interval->hour=array[1];
|
||||||
@ -946,14 +995,14 @@ static bool get_interval_value(Item *args,interval_type int_type,
|
|||||||
interval->second_part=array[4];
|
interval->second_part=array[4];
|
||||||
break;
|
break;
|
||||||
case INTERVAL_DAY_MINUTE:
|
case INTERVAL_DAY_MINUTE:
|
||||||
if (get_interval_info(str,length,cs,3,array))
|
if (get_interval_info(str,length,cs,3,array,0))
|
||||||
return (1);
|
return (1);
|
||||||
interval->day=array[0];
|
interval->day=array[0];
|
||||||
interval->hour=array[1];
|
interval->hour=array[1];
|
||||||
interval->minute=array[2];
|
interval->minute=array[2];
|
||||||
break;
|
break;
|
||||||
case INTERVAL_DAY_SECOND:
|
case INTERVAL_DAY_SECOND:
|
||||||
if (get_interval_info(str,length,cs,4,array))
|
if (get_interval_info(str,length,cs,4,array,0))
|
||||||
return (1);
|
return (1);
|
||||||
interval->day=array[0];
|
interval->day=array[0];
|
||||||
interval->hour=array[1];
|
interval->hour=array[1];
|
||||||
@ -961,7 +1010,7 @@ static bool get_interval_value(Item *args,interval_type int_type,
|
|||||||
interval->second=array[3];
|
interval->second=array[3];
|
||||||
break;
|
break;
|
||||||
case INTERVAL_HOUR_MICROSECOND:
|
case INTERVAL_HOUR_MICROSECOND:
|
||||||
if (get_interval_info(str,length,cs,4,array))
|
if (get_interval_info(str,length,cs,4,array,1))
|
||||||
return (1);
|
return (1);
|
||||||
interval->hour=array[0];
|
interval->hour=array[0];
|
||||||
interval->minute=array[1];
|
interval->minute=array[1];
|
||||||
@ -969,33 +1018,33 @@ static bool get_interval_value(Item *args,interval_type int_type,
|
|||||||
interval->second_part=array[3];
|
interval->second_part=array[3];
|
||||||
break;
|
break;
|
||||||
case INTERVAL_HOUR_MINUTE:
|
case INTERVAL_HOUR_MINUTE:
|
||||||
if (get_interval_info(str,length,cs,2,array))
|
if (get_interval_info(str,length,cs,2,array,0))
|
||||||
return (1);
|
return (1);
|
||||||
interval->hour=array[0];
|
interval->hour=array[0];
|
||||||
interval->minute=array[1];
|
interval->minute=array[1];
|
||||||
break;
|
break;
|
||||||
case INTERVAL_HOUR_SECOND:
|
case INTERVAL_HOUR_SECOND:
|
||||||
if (get_interval_info(str,length,cs,3,array))
|
if (get_interval_info(str,length,cs,3,array,0))
|
||||||
return (1);
|
return (1);
|
||||||
interval->hour=array[0];
|
interval->hour=array[0];
|
||||||
interval->minute=array[1];
|
interval->minute=array[1];
|
||||||
interval->second=array[2];
|
interval->second=array[2];
|
||||||
break;
|
break;
|
||||||
case INTERVAL_MINUTE_MICROSECOND:
|
case INTERVAL_MINUTE_MICROSECOND:
|
||||||
if (get_interval_info(str,length,cs,3,array))
|
if (get_interval_info(str,length,cs,3,array,1))
|
||||||
return (1);
|
return (1);
|
||||||
interval->minute=array[0];
|
interval->minute=array[0];
|
||||||
interval->second=array[1];
|
interval->second=array[1];
|
||||||
interval->second_part=array[2];
|
interval->second_part=array[2];
|
||||||
break;
|
break;
|
||||||
case INTERVAL_MINUTE_SECOND:
|
case INTERVAL_MINUTE_SECOND:
|
||||||
if (get_interval_info(str,length,cs,2,array))
|
if (get_interval_info(str,length,cs,2,array,0))
|
||||||
return (1);
|
return (1);
|
||||||
interval->minute=array[0];
|
interval->minute=array[0];
|
||||||
interval->second=array[1];
|
interval->second=array[1];
|
||||||
break;
|
break;
|
||||||
case INTERVAL_SECOND_MICROSECOND:
|
case INTERVAL_SECOND_MICROSECOND:
|
||||||
if (get_interval_info(str,length,cs,2,array))
|
if (get_interval_info(str,length,cs,2,array,1))
|
||||||
return (1);
|
return (1);
|
||||||
interval->second=array[0];
|
interval->second=array[0];
|
||||||
interval->second_part=array[1];
|
interval->second_part=array[1];
|
||||||
@ -1008,22 +1057,13 @@ static bool get_interval_value(Item *args,interval_type int_type,
|
|||||||
String *Item_date::val_str(String *str)
|
String *Item_date::val_str(String *str)
|
||||||
{
|
{
|
||||||
TIME ltime;
|
TIME ltime;
|
||||||
ulong value=(ulong) val_int();
|
if (get_date(<ime, TIME_FUZZY_DATE))
|
||||||
if (null_value)
|
return (String *) 0;
|
||||||
return (String*) 0;
|
|
||||||
|
|
||||||
if (str->alloc(11))
|
if (str->alloc(11))
|
||||||
{
|
{
|
||||||
null_value= 1;
|
null_value= 1;
|
||||||
return (String *) 0;
|
return (String *) 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
ltime.year= (value/10000L) % 10000;
|
|
||||||
ltime.month= (value/100)%100;
|
|
||||||
ltime.day= (value%100);
|
|
||||||
ltime.neg= 0;
|
|
||||||
ltime.time_type=TIMESTAMP_DATE;
|
|
||||||
|
|
||||||
make_date((DATE_TIME_FORMAT *) 0, <ime, str);
|
make_date((DATE_TIME_FORMAT *) 0, <ime, str);
|
||||||
return str;
|
return str;
|
||||||
}
|
}
|
||||||
@ -1032,28 +1072,31 @@ String *Item_date::val_str(String *str)
|
|||||||
int Item_date::save_in_field(Field *field, bool no_conversions)
|
int Item_date::save_in_field(Field *field, bool no_conversions)
|
||||||
{
|
{
|
||||||
TIME ltime;
|
TIME ltime;
|
||||||
timestamp_type t_type=TIMESTAMP_DATETIME;
|
|
||||||
if (get_date(<ime, TIME_FUZZY_DATE))
|
if (get_date(<ime, TIME_FUZZY_DATE))
|
||||||
{
|
|
||||||
if (null_value)
|
|
||||||
return set_field_to_null(field);
|
return set_field_to_null(field);
|
||||||
t_type=TIMESTAMP_NONE; // Error
|
|
||||||
}
|
|
||||||
field->set_notnull();
|
field->set_notnull();
|
||||||
field->store_time(<ime,t_type);
|
field->store_time(<ime, TIMESTAMP_DATE);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
longlong Item_func_from_days::val_int()
|
longlong Item_date::val_int()
|
||||||
|
{
|
||||||
|
TIME ltime;
|
||||||
|
if (get_date(<ime, TIME_FUZZY_DATE))
|
||||||
|
return 0;
|
||||||
|
return (longlong) (ltime.year*10000L+ltime.month*100+ltime.day);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool Item_func_from_days::get_date(TIME *ltime, uint fuzzy_date)
|
||||||
{
|
{
|
||||||
longlong value=args[0]->val_int();
|
longlong value=args[0]->val_int();
|
||||||
if ((null_value=args[0]->null_value))
|
if ((null_value=args[0]->null_value))
|
||||||
return 0; /* purecov: inspected */
|
return 1;
|
||||||
|
get_date_from_daynr((long) value, <ime->year, <ime->month, <ime->day);
|
||||||
uint year,month,day;
|
ltime->time_type= TIMESTAMP_DATE;
|
||||||
get_date_from_daynr((long) value,&year,&month,&day);
|
return 0;
|
||||||
return (longlong) (year*10000L+month*100+day);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -1082,6 +1125,16 @@ void Item_func_curdate::fix_length_and_dec()
|
|||||||
ltime.time_type=TIMESTAMP_DATE;
|
ltime.time_type=TIMESTAMP_DATE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
String *Item_func_curdate::val_str(String *str)
|
||||||
|
{
|
||||||
|
if (str->alloc(11))
|
||||||
|
{
|
||||||
|
null_value= 1;
|
||||||
|
return (String *) 0;
|
||||||
|
}
|
||||||
|
make_date((DATE_TIME_FORMAT *) 0, <ime, str);
|
||||||
|
return str;
|
||||||
|
}
|
||||||
|
|
||||||
bool Item_func_curdate::get_date(TIME *res,
|
bool Item_func_curdate::get_date(TIME *res,
|
||||||
uint fuzzy_date __attribute__((unused)))
|
uint fuzzy_date __attribute__((unused)))
|
||||||
@ -2311,6 +2364,103 @@ void Item_func_get_format::print(String *str)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
check_result_type(s, l) returns DATE/TIME type
|
||||||
|
according to format string
|
||||||
|
|
||||||
|
s: DATE/TIME format string
|
||||||
|
l: length of s
|
||||||
|
Result: date_time_format_types value:
|
||||||
|
DATE_TIME_MICROSECOND, DATE_TIME,
|
||||||
|
TIME_MICROSECOND, TIME_ONLY
|
||||||
|
|
||||||
|
We don't process day format's characters('D', 'd', 'e')
|
||||||
|
because day may be a member of all date/time types.
|
||||||
|
If only day format's character and no time part present
|
||||||
|
the result type is MYSQL_TYPE_DATE
|
||||||
|
*/
|
||||||
|
|
||||||
|
date_time_format_types check_result_type(const char *format, uint length)
|
||||||
|
{
|
||||||
|
const char *time_part_frms= "HISThiklrs";
|
||||||
|
const char *date_part_frms= "MUYWabcjmuyw";
|
||||||
|
bool date_part_used= 0, time_part_used= 0, frac_second_used= 0;
|
||||||
|
|
||||||
|
const char *val= format;
|
||||||
|
const char *end= format + length;
|
||||||
|
|
||||||
|
for (; val != end && val != end; val++)
|
||||||
|
{
|
||||||
|
if (*val == '%' && val+1 != end)
|
||||||
|
{
|
||||||
|
val++;
|
||||||
|
if ((frac_second_used= (*val == 'f')) ||
|
||||||
|
(!time_part_used && strchr(time_part_frms, *val)))
|
||||||
|
time_part_used= 1;
|
||||||
|
else if (!date_part_used && strchr(date_part_frms, *val))
|
||||||
|
date_part_used= 1;
|
||||||
|
if (time_part_used && date_part_used && frac_second_used)
|
||||||
|
return DATE_TIME_MICROSECOND;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (time_part_used)
|
||||||
|
{
|
||||||
|
if (date_part_used)
|
||||||
|
return DATE_TIME;
|
||||||
|
if (frac_second_used)
|
||||||
|
return TIME_MICROSECOND;
|
||||||
|
return TIME_ONLY;
|
||||||
|
}
|
||||||
|
return DATE_ONLY;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Field *Item_func_str_to_date::tmp_table_field(TABLE *t_arg)
|
||||||
|
{
|
||||||
|
if (cached_field_type == MYSQL_TYPE_TIME)
|
||||||
|
return (new Field_time(maybe_null, name, t_arg, &my_charset_bin));
|
||||||
|
if (cached_field_type == MYSQL_TYPE_DATE)
|
||||||
|
return (new Field_date(maybe_null, name, t_arg, &my_charset_bin));
|
||||||
|
if (cached_field_type == MYSQL_TYPE_DATETIME)
|
||||||
|
return (new Field_datetime(maybe_null, name, t_arg, &my_charset_bin));
|
||||||
|
return (new Field_string(max_length, maybe_null, name, t_arg, &my_charset_bin));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void Item_func_str_to_date::fix_length_and_dec()
|
||||||
|
{
|
||||||
|
char format_buff[64];
|
||||||
|
String format_str(format_buff, sizeof(format_buff), &my_charset_bin), *format;
|
||||||
|
maybe_null= 1;
|
||||||
|
decimals=0;
|
||||||
|
cached_field_type= MYSQL_TYPE_STRING;
|
||||||
|
max_length= MAX_DATETIME_FULL_WIDTH*MY_CHARSET_BIN_MB_MAXLEN;
|
||||||
|
cached_timestamp_type= TIMESTAMP_NONE;
|
||||||
|
if ((const_item= args[1]->const_item()))
|
||||||
|
{
|
||||||
|
format= args[1]->val_str(&format_str);
|
||||||
|
cached_format_type= check_result_type(format->ptr(), format->length());
|
||||||
|
switch (cached_format_type) {
|
||||||
|
case DATE_ONLY:
|
||||||
|
cached_timestamp_type= TIMESTAMP_DATE;
|
||||||
|
cached_field_type= MYSQL_TYPE_DATE;
|
||||||
|
max_length= MAX_DATE_WIDTH*MY_CHARSET_BIN_MB_MAXLEN;
|
||||||
|
break;
|
||||||
|
case TIME_ONLY:
|
||||||
|
case TIME_MICROSECOND:
|
||||||
|
cached_timestamp_type= TIMESTAMP_TIME;
|
||||||
|
cached_field_type= MYSQL_TYPE_TIME;
|
||||||
|
max_length= MAX_TIME_WIDTH*MY_CHARSET_BIN_MB_MAXLEN;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
cached_timestamp_type= TIMESTAMP_DATETIME;
|
||||||
|
cached_field_type= MYSQL_TYPE_DATETIME;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
bool Item_func_str_to_date::get_date(TIME *ltime, uint fuzzy_date)
|
bool Item_func_str_to_date::get_date(TIME *ltime, uint fuzzy_date)
|
||||||
{
|
{
|
||||||
DATE_TIME_FORMAT date_time_format;
|
DATE_TIME_FORMAT date_time_format;
|
||||||
@ -2328,8 +2478,18 @@ bool Item_func_str_to_date::get_date(TIME *ltime, uint fuzzy_date)
|
|||||||
date_time_format.format.str= (char*) format->ptr();
|
date_time_format.format.str= (char*) format->ptr();
|
||||||
date_time_format.format.length= format->length();
|
date_time_format.format.length= format->length();
|
||||||
if (extract_date_time(&date_time_format, val->ptr(), val->length(),
|
if (extract_date_time(&date_time_format, val->ptr(), val->length(),
|
||||||
ltime))
|
ltime, cached_timestamp_type))
|
||||||
goto null_date;
|
goto null_date;
|
||||||
|
if (cached_timestamp_type == TIMESTAMP_TIME && ltime->day)
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
Day part for time type can be nonzero value and so
|
||||||
|
we should add hours from day part to hour part to
|
||||||
|
keep valid time value.
|
||||||
|
*/
|
||||||
|
ltime->hour+= ltime->day*24;
|
||||||
|
ltime->day= 0;
|
||||||
|
}
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
null_date:
|
null_date:
|
||||||
@ -2344,29 +2504,22 @@ String *Item_func_str_to_date::val_str(String *str)
|
|||||||
if (Item_func_str_to_date::get_date(<ime, TIME_FUZZY_DATE))
|
if (Item_func_str_to_date::get_date(<ime, TIME_FUZZY_DATE))
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
/*
|
if (!make_datetime((const_item ? cached_format_type :
|
||||||
The following DATE_TIME should be done dynamicly based on the
|
(ltime.second_part ? DATE_TIME_MICROSECOND : DATE_TIME)),
|
||||||
format string (wen it's a constant). For example, we should only return
|
|
||||||
microseconds if there was an %f in the format
|
|
||||||
*/
|
|
||||||
if (!make_datetime(ltime.second_part ? DATE_TIME_MICROSECOND : DATE_TIME,
|
|
||||||
<ime, str))
|
<ime, str))
|
||||||
return str;
|
return str;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
String *Item_func_last_day::val_str(String *str)
|
bool Item_func_last_day::get_date(TIME *ltime, uint fuzzy_date)
|
||||||
{
|
{
|
||||||
TIME ltime;
|
if (get_arg0_date(ltime,fuzzy_date))
|
||||||
if (!get_arg0_date(<ime,0))
|
return 1;
|
||||||
{
|
uint month_idx= ltime->month-1;
|
||||||
uint month_idx= ltime.month-1;
|
ltime->day= days_in_month[month_idx];
|
||||||
ltime.day= days_in_month[month_idx];
|
if ( month_idx == 1 && calc_days_in_year(ltime->year) == 366)
|
||||||
if ( month_idx == 1 && calc_days_in_year(ltime.year) == 366)
|
ltime->day= 29;
|
||||||
ltime.day+= 1;
|
ltime->time_type= TIMESTAMP_DATE;
|
||||||
if (!make_datetime(DATE_ONLY, <ime, str))
|
|
||||||
return str;
|
|
||||||
}
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -21,6 +21,11 @@
|
|||||||
#pragma interface /* gcc class implementation */
|
#pragma interface /* gcc class implementation */
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
enum date_time_format_types
|
||||||
|
{
|
||||||
|
TIME_ONLY= 0, TIME_MICROSECOND, DATE_ONLY, DATE_TIME, DATE_TIME_MICROSECOND
|
||||||
|
};
|
||||||
|
|
||||||
class Item_func_period_add :public Item_int_func
|
class Item_func_period_add :public Item_int_func
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
@ -318,6 +323,7 @@ public:
|
|||||||
enum Item_result result_type () const { return STRING_RESULT; }
|
enum Item_result result_type () const { return STRING_RESULT; }
|
||||||
enum_field_types field_type() const { return MYSQL_TYPE_DATE; }
|
enum_field_types field_type() const { return MYSQL_TYPE_DATE; }
|
||||||
String *val_str(String *str);
|
String *val_str(String *str);
|
||||||
|
longlong val_int();
|
||||||
double val() { return (double) val_int(); }
|
double val() { return (double) val_int(); }
|
||||||
const char *func_name() const { return "date"; }
|
const char *func_name() const { return "date"; }
|
||||||
void fix_length_and_dec()
|
void fix_length_and_dec()
|
||||||
@ -407,6 +413,7 @@ public:
|
|||||||
Item_func_curdate() :Item_date() {}
|
Item_func_curdate() :Item_date() {}
|
||||||
void set_result_from_tm(struct tm *now);
|
void set_result_from_tm(struct tm *now);
|
||||||
longlong val_int() { return (value) ; }
|
longlong val_int() { return (value) ; }
|
||||||
|
String *val_str(String *str);
|
||||||
void fix_length_and_dec();
|
void fix_length_and_dec();
|
||||||
bool get_date(TIME *res, uint fuzzy_date);
|
bool get_date(TIME *res, uint fuzzy_date);
|
||||||
virtual void store_now_in_tm(time_t now, struct tm *now_tm)=0;
|
virtual void store_now_in_tm(time_t now, struct tm *now_tm)=0;
|
||||||
@ -477,8 +484,8 @@ class Item_func_from_days :public Item_date
|
|||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
Item_func_from_days(Item *a) :Item_date(a) {}
|
Item_func_from_days(Item *a) :Item_date(a) {}
|
||||||
longlong val_int();
|
|
||||||
const char *func_name() const { return "from_days"; }
|
const char *func_name() const { return "from_days"; }
|
||||||
|
bool get_date(TIME *res, uint fuzzy_date);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
@ -806,37 +813,29 @@ public:
|
|||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
class Item_func_str_to_date :public Item_date_func
|
class Item_func_str_to_date :public Item_str_func
|
||||||
{
|
{
|
||||||
|
enum_field_types cached_field_type;
|
||||||
|
date_time_format_types cached_format_type;
|
||||||
|
timestamp_type cached_timestamp_type;
|
||||||
|
bool const_item;
|
||||||
public:
|
public:
|
||||||
Item_func_str_to_date(Item *a, Item *b)
|
Item_func_str_to_date(Item *a, Item *b)
|
||||||
:Item_date_func(a, b)
|
:Item_str_func(a, b)
|
||||||
{}
|
{}
|
||||||
String *val_str(String *str);
|
String *val_str(String *str);
|
||||||
bool get_date(TIME *ltime, uint fuzzy_date);
|
bool get_date(TIME *ltime, uint fuzzy_date);
|
||||||
const char *func_name() const { return "str_to_date"; }
|
const char *func_name() const { return "str_to_date"; }
|
||||||
void fix_length_and_dec()
|
enum_field_types field_type() const { return cached_field_type; }
|
||||||
{
|
void fix_length_and_dec();
|
||||||
maybe_null= 1;
|
Field *tmp_table_field(TABLE *t_arg);
|
||||||
decimals=0;
|
|
||||||
max_length=MAX_DATETIME_FULL_WIDTH*MY_CHARSET_BIN_MB_MAXLEN;
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
class Item_func_last_day :public Item_str_func
|
|
||||||
|
class Item_func_last_day :public Item_date
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
Item_func_last_day(Item *a) :Item_str_func(a) {}
|
Item_func_last_day(Item *a) :Item_date(a) {}
|
||||||
String *val_str(String *str);
|
|
||||||
const char *func_name() const { return "last_day"; }
|
const char *func_name() const { return "last_day"; }
|
||||||
enum_field_types field_type() const { return MYSQL_TYPE_DATE; }
|
bool get_date(TIME *res, uint fuzzy_date);
|
||||||
void fix_length_and_dec()
|
|
||||||
{
|
|
||||||
decimals=0;
|
|
||||||
max_length=MAX_DATE_WIDTH*MY_CHARSET_BIN_MB_MAXLEN;
|
|
||||||
}
|
|
||||||
Field *tmp_table_field(TABLE *t_arg)
|
|
||||||
{
|
|
||||||
return (new Field_date(maybe_null, name, t_arg, &my_charset_bin));
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
@ -64,14 +64,6 @@ char* query_table_status(THD *thd,const char *db,const char *table_name);
|
|||||||
#define PREV_BITS(type,A) ((type) (((type) 1 << (A)) -1))
|
#define PREV_BITS(type,A) ((type) (((type) 1 << (A)) -1))
|
||||||
#define all_bits_set(A,B) ((A) & (B) != (B))
|
#define all_bits_set(A,B) ((A) & (B) != (B))
|
||||||
|
|
||||||
#ifndef LL
|
|
||||||
#ifdef HAVE_LONG_LONG
|
|
||||||
#define LL(A) A ## LL
|
|
||||||
#else
|
|
||||||
#define LL(A) A ## L
|
|
||||||
#endif
|
|
||||||
#endif
|
|
||||||
|
|
||||||
extern CHARSET_INFO *system_charset_info, *files_charset_info ;
|
extern CHARSET_INFO *system_charset_info, *files_charset_info ;
|
||||||
extern CHARSET_INFO *national_charset_info, *table_alias_charset;
|
extern CHARSET_INFO *national_charset_info, *table_alias_charset;
|
||||||
|
|
||||||
@ -621,7 +613,7 @@ int mysqld_help (THD *thd, const char *text);
|
|||||||
|
|
||||||
/* sql_prepare.cc */
|
/* sql_prepare.cc */
|
||||||
void mysql_stmt_prepare(THD *thd, char *packet, uint packet_length);
|
void mysql_stmt_prepare(THD *thd, char *packet, uint packet_length);
|
||||||
void mysql_stmt_execute(THD *thd, char *packet);
|
void mysql_stmt_execute(THD *thd, char *packet, uint packet_length);
|
||||||
void mysql_stmt_free(THD *thd, char *packet);
|
void mysql_stmt_free(THD *thd, char *packet);
|
||||||
void mysql_stmt_reset(THD *thd, char *packet);
|
void mysql_stmt_reset(THD *thd, char *packet);
|
||||||
void mysql_stmt_get_longdata(THD *thd, char *pos, ulong packet_length);
|
void mysql_stmt_get_longdata(THD *thd, char *pos, ulong packet_length);
|
||||||
@ -799,6 +791,7 @@ extern char glob_hostname[FN_REFLEN], mysql_home[FN_REFLEN];
|
|||||||
extern char pidfile_name[FN_REFLEN], time_zone[30], *opt_init_file;
|
extern char pidfile_name[FN_REFLEN], time_zone[30], *opt_init_file;
|
||||||
extern char log_error_file[FN_REFLEN];
|
extern char log_error_file[FN_REFLEN];
|
||||||
extern double log_10[32];
|
extern double log_10[32];
|
||||||
|
extern ulonglong log_10_int[20];
|
||||||
extern ulonglong keybuff_size;
|
extern ulonglong keybuff_size;
|
||||||
extern ulong refresh_version,flush_version, thread_id,query_id,opened_tables;
|
extern ulong refresh_version,flush_version, thread_id,query_id,opened_tables;
|
||||||
extern ulong created_tmp_tables, created_tmp_disk_tables, bytes_sent;
|
extern ulong created_tmp_tables, created_tmp_disk_tables, bytes_sent;
|
||||||
@ -958,6 +951,8 @@ timestamp_type str_to_TIME(const char *str, uint length, TIME *l_time,
|
|||||||
void localtime_to_TIME(TIME *to, struct tm *from);
|
void localtime_to_TIME(TIME *to, struct tm *from);
|
||||||
void calc_time_from_sec(TIME *to, long seconds, long microseconds);
|
void calc_time_from_sec(TIME *to, long seconds, long microseconds);
|
||||||
|
|
||||||
|
void make_truncated_value_warning(THD *thd, const char *str_val,
|
||||||
|
uint str_length, timestamp_type time_type);
|
||||||
extern DATE_TIME_FORMAT *date_time_format_make(timestamp_type format_type,
|
extern DATE_TIME_FORMAT *date_time_format_make(timestamp_type format_type,
|
||||||
const char *format_str,
|
const char *format_str,
|
||||||
uint format_length);
|
uint format_length);
|
||||||
|
@ -305,6 +305,14 @@ ulong my_bind_addr; /* the address we bind to */
|
|||||||
volatile ulong cached_thread_count= 0;
|
volatile ulong cached_thread_count= 0;
|
||||||
|
|
||||||
double log_10[32]; /* 10 potences */
|
double log_10[32]; /* 10 potences */
|
||||||
|
ulonglong log_10_int[20]=
|
||||||
|
{
|
||||||
|
1, 10, 100, 1000, 10000UL, 100000UL, 1000000UL, 10000000UL,
|
||||||
|
ULL(100000000), ULL(1000000000), ULL(10000000000), ULL(100000000000),
|
||||||
|
ULL(1000000000000), ULL(10000000000000), ULL(100000000000000),
|
||||||
|
ULL(1000000000000000), ULL(10000000000000000), ULL(100000000000000000),
|
||||||
|
ULL(1000000000000000000), ULL(10000000000000000000)
|
||||||
|
};
|
||||||
|
|
||||||
time_t start_time;
|
time_t start_time;
|
||||||
|
|
||||||
|
@ -304,3 +304,4 @@ character-set=latin2
|
|||||||
"The '%s' feature was disabled; you need MySQL built with '%s' to have it working",
|
"The '%s' feature was disabled; you need MySQL built with '%s' to have it working",
|
||||||
"The MySQL server is running with the %s option so it cannot execute this statement",
|
"The MySQL server is running with the %s option so it cannot execute this statement",
|
||||||
"Column '%-.100s' has duplicated value '%-.64s' in %s"
|
"Column '%-.100s' has duplicated value '%-.64s' in %s"
|
||||||
|
"Truncated wrong %-.32s value: '%-.128s'"
|
||||||
|
@ -298,3 +298,4 @@ character-set=latin1
|
|||||||
"The '%s' feature was disabled; you need MySQL built with '%s' to have it working",
|
"The '%s' feature was disabled; you need MySQL built with '%s' to have it working",
|
||||||
"The MySQL server is running with the %s option so it cannot execute this statement",
|
"The MySQL server is running with the %s option so it cannot execute this statement",
|
||||||
"Column '%-.100s' has duplicated value '%-.64s' in %s"
|
"Column '%-.100s' has duplicated value '%-.64s' in %s"
|
||||||
|
"Truncated wrong %-.32s value: '%-.128s'"
|
||||||
|
@ -306,3 +306,4 @@ character-set=latin1
|
|||||||
"The '%s' feature was disabled; you need MySQL built with '%s' to have it working",
|
"The '%s' feature was disabled; you need MySQL built with '%s' to have it working",
|
||||||
"The MySQL server is running with the %s option so it cannot execute this statement",
|
"The MySQL server is running with the %s option so it cannot execute this statement",
|
||||||
"Column '%-.100s' has duplicated value '%-.64s' in %s"
|
"Column '%-.100s' has duplicated value '%-.64s' in %s"
|
||||||
|
"Truncated wrong %-.32s value: '%-.128s'"
|
||||||
|
@ -295,3 +295,4 @@ character-set=latin1
|
|||||||
"The '%s' feature was disabled; you need MySQL built with '%s' to have it working",
|
"The '%s' feature was disabled; you need MySQL built with '%s' to have it working",
|
||||||
"The MySQL server is running with the %s option so it cannot execute this statement",
|
"The MySQL server is running with the %s option so it cannot execute this statement",
|
||||||
"Column '%-.100s' has duplicated value '%-.64s' in %s"
|
"Column '%-.100s' has duplicated value '%-.64s' in %s"
|
||||||
|
"Truncated wrong %-.32s value: '%-.128s'"
|
||||||
|
@ -300,3 +300,4 @@ character-set=latin7
|
|||||||
"The '%s' feature was disabled; you need MySQL built with '%s' to have it working",
|
"The '%s' feature was disabled; you need MySQL built with '%s' to have it working",
|
||||||
"The MySQL server is running with the %s option so it cannot execute this statement",
|
"The MySQL server is running with the %s option so it cannot execute this statement",
|
||||||
"Column '%-.100s' has duplicated value '%-.64s' in %s"
|
"Column '%-.100s' has duplicated value '%-.64s' in %s"
|
||||||
|
"Truncated wrong %-.32s value: '%-.128s'"
|
||||||
|
@ -295,3 +295,4 @@ character-set=latin1
|
|||||||
"The '%s' feature was disabled; you need MySQL built with '%s' to have it working",
|
"The '%s' feature was disabled; you need MySQL built with '%s' to have it working",
|
||||||
"The MySQL server is running with the %s option so it cannot execute this statement",
|
"The MySQL server is running with the %s option so it cannot execute this statement",
|
||||||
"Column '%-.100s' has duplicated value '%-.64s' in %s"
|
"Column '%-.100s' has duplicated value '%-.64s' in %s"
|
||||||
|
"Truncated wrong %-.32s value: '%-.128s'"
|
||||||
|
@ -307,3 +307,4 @@ character-set=latin1
|
|||||||
"The '%s' feature was disabled; you need MySQL built with '%s' to have it working",
|
"The '%s' feature was disabled; you need MySQL built with '%s' to have it working",
|
||||||
"The MySQL server is running with the %s option so it cannot execute this statement",
|
"The MySQL server is running with the %s option so it cannot execute this statement",
|
||||||
"Column '%-.100s' has duplicated value '%-.64s' in %s"
|
"Column '%-.100s' has duplicated value '%-.64s' in %s"
|
||||||
|
"Truncated wrong %-.32s value: '%-.128s'"
|
||||||
|
@ -295,3 +295,4 @@ character-set=greek
|
|||||||
"The '%s' feature was disabled; you need MySQL built with '%s' to have it working",
|
"The '%s' feature was disabled; you need MySQL built with '%s' to have it working",
|
||||||
"The MySQL server is running with the %s option so it cannot execute this statement",
|
"The MySQL server is running with the %s option so it cannot execute this statement",
|
||||||
"Column '%-.100s' has duplicated value '%-.64s' in %s"
|
"Column '%-.100s' has duplicated value '%-.64s' in %s"
|
||||||
|
"Truncated wrong %-.32s value: '%-.128s'"
|
||||||
|
@ -297,3 +297,4 @@ character-set=latin2
|
|||||||
"The '%s' feature was disabled; you need MySQL built with '%s' to have it working",
|
"The '%s' feature was disabled; you need MySQL built with '%s' to have it working",
|
||||||
"The MySQL server is running with the %s option so it cannot execute this statement",
|
"The MySQL server is running with the %s option so it cannot execute this statement",
|
||||||
"Column '%-.100s' has duplicated value '%-.64s' in %s"
|
"Column '%-.100s' has duplicated value '%-.64s' in %s"
|
||||||
|
"Truncated wrong %-.32s value: '%-.128s'"
|
||||||
|
@ -295,3 +295,4 @@ character-set=latin1
|
|||||||
"The '%s' feature was disabled; you need MySQL built with '%s' to have it working",
|
"The '%s' feature was disabled; you need MySQL built with '%s' to have it working",
|
||||||
"The MySQL server is running with the %s option so it cannot execute this statement",
|
"The MySQL server is running with the %s option so it cannot execute this statement",
|
||||||
"Column '%-.100s' has duplicated value '%-.64s' in %s"
|
"Column '%-.100s' has duplicated value '%-.64s' in %s"
|
||||||
|
"Truncated wrong %-.32s value: '%-.128s'"
|
||||||
|
@ -297,3 +297,4 @@ character-set=ujis
|
|||||||
"The '%s' feature was disabled; you need MySQL built with '%s' to have it working",
|
"The '%s' feature was disabled; you need MySQL built with '%s' to have it working",
|
||||||
"The MySQL server is running with the %s option so it cannot execute this statement",
|
"The MySQL server is running with the %s option so it cannot execute this statement",
|
||||||
"Column '%-.100s' has duplicated value '%-.64s' in %s"
|
"Column '%-.100s' has duplicated value '%-.64s' in %s"
|
||||||
|
"Truncated wrong %-.32s value: '%-.128s'"
|
||||||
|
@ -295,3 +295,4 @@ character-set=euckr
|
|||||||
"The '%s' feature was disabled; you need MySQL built with '%s' to have it working",
|
"The '%s' feature was disabled; you need MySQL built with '%s' to have it working",
|
||||||
"The MySQL server is running with the %s option so it cannot execute this statement",
|
"The MySQL server is running with the %s option so it cannot execute this statement",
|
||||||
"Column '%-.100s' has duplicated value '%-.64s' in %s"
|
"Column '%-.100s' has duplicated value '%-.64s' in %s"
|
||||||
|
"Truncated wrong %-.32s value: '%-.128s'"
|
||||||
|
@ -297,3 +297,4 @@ character-set=latin1
|
|||||||
"The '%s' feature was disabled; you need MySQL built with '%s' to have it working",
|
"The '%s' feature was disabled; you need MySQL built with '%s' to have it working",
|
||||||
"The MySQL server is running with the %s option so it cannot execute this statement",
|
"The MySQL server is running with the %s option so it cannot execute this statement",
|
||||||
"Column '%-.100s' has duplicated value '%-.64s' in %s"
|
"Column '%-.100s' has duplicated value '%-.64s' in %s"
|
||||||
|
"Truncated wrong %-.32s value: '%-.128s'"
|
||||||
|
@ -297,3 +297,4 @@ character-set=latin1
|
|||||||
"The '%s' feature was disabled; you need MySQL built with '%s' to have it working",
|
"The '%s' feature was disabled; you need MySQL built with '%s' to have it working",
|
||||||
"The MySQL server is running with the %s option so it cannot execute this statement",
|
"The MySQL server is running with the %s option so it cannot execute this statement",
|
||||||
"Column '%-.100s' has duplicated value '%-.64s' in %s"
|
"Column '%-.100s' has duplicated value '%-.64s' in %s"
|
||||||
|
"Truncated wrong %-.32s value: '%-.128s'"
|
||||||
|
@ -299,3 +299,4 @@ character-set=latin2
|
|||||||
"The '%s' feature was disabled; you need MySQL built with '%s' to have it working",
|
"The '%s' feature was disabled; you need MySQL built with '%s' to have it working",
|
||||||
"The MySQL server is running with the %s option so it cannot execute this statement",
|
"The MySQL server is running with the %s option so it cannot execute this statement",
|
||||||
"Column '%-.100s' has duplicated value '%-.64s' in %s"
|
"Column '%-.100s' has duplicated value '%-.64s' in %s"
|
||||||
|
"Truncated wrong %-.32s value: '%-.128s'"
|
||||||
|
@ -296,3 +296,4 @@ character-set=latin1
|
|||||||
"The '%s' feature was disabled; you need MySQL built with '%s' to have it working",
|
"The '%s' feature was disabled; you need MySQL built with '%s' to have it working",
|
||||||
"The MySQL server is running with the %s option so it cannot execute this statement",
|
"The MySQL server is running with the %s option so it cannot execute this statement",
|
||||||
"Column '%-.100s' has duplicated value '%-.64s' in %s"
|
"Column '%-.100s' has duplicated value '%-.64s' in %s"
|
||||||
|
"Truncated wrong %-.32s value: '%-.128s'"
|
||||||
|
@ -299,3 +299,4 @@ character-set=latin2
|
|||||||
"The '%s' feature was disabled; you need MySQL built with '%s' to have it working",
|
"The '%s' feature was disabled; you need MySQL built with '%s' to have it working",
|
||||||
"The MySQL server is running with the %s option so it cannot execute this statement",
|
"The MySQL server is running with the %s option so it cannot execute this statement",
|
||||||
"Column '%-.100s' has duplicated value '%-.64s' in %s"
|
"Column '%-.100s' has duplicated value '%-.64s' in %s"
|
||||||
|
"Truncated wrong %-.32s value: '%-.128s'"
|
||||||
|
@ -297,3 +297,4 @@ character-set=koi8r
|
|||||||
"The '%s' feature was disabled; you need MySQL built with '%s' to have it working",
|
"The '%s' feature was disabled; you need MySQL built with '%s' to have it working",
|
||||||
"The MySQL server is running with the %s option so it cannot execute this statement",
|
"The MySQL server is running with the %s option so it cannot execute this statement",
|
||||||
"Column '%-.100s' has duplicated value '%-.64s' in %s"
|
"Column '%-.100s' has duplicated value '%-.64s' in %s"
|
||||||
|
"Truncated wrong %-.32s value: '%-.128s'"
|
||||||
|
@ -289,3 +289,4 @@ character-set=cp1250
|
|||||||
"The '%s' feature was disabled; you need MySQL built with '%s' to have it working"
|
"The '%s' feature was disabled; you need MySQL built with '%s' to have it working"
|
||||||
"The MySQL server is running with the %s option so it cannot execute this statement"
|
"The MySQL server is running with the %s option so it cannot execute this statement"
|
||||||
"Column '%-.100s' has duplicated value '%-.64s' in %s"
|
"Column '%-.100s' has duplicated value '%-.64s' in %s"
|
||||||
|
"Truncated wrong %-.32s value: '%-.128s'"
|
||||||
|
@ -303,3 +303,4 @@ character-set=latin2
|
|||||||
"The '%s' feature was disabled; you need MySQL built with '%s' to have it working",
|
"The '%s' feature was disabled; you need MySQL built with '%s' to have it working",
|
||||||
"The MySQL server is running with the %s option so it cannot execute this statement",
|
"The MySQL server is running with the %s option so it cannot execute this statement",
|
||||||
"Column '%-.100s' has duplicated value '%-.64s' in %s"
|
"Column '%-.100s' has duplicated value '%-.64s' in %s"
|
||||||
|
"Truncated wrong %-.32s value: '%-.128s'"
|
||||||
|
@ -297,3 +297,4 @@ character-set=latin1
|
|||||||
"The '%s' feature was disabled; you need MySQL built with '%s' to have it working",
|
"The '%s' feature was disabled; you need MySQL built with '%s' to have it working",
|
||||||
"The MySQL server is running with the %s option so it cannot execute this statement",
|
"The MySQL server is running with the %s option so it cannot execute this statement",
|
||||||
"Column '%-.100s' has duplicated value '%-.64s' in %s"
|
"Column '%-.100s' has duplicated value '%-.64s' in %s"
|
||||||
|
"Truncated wrong %-.32s value: '%-.128s'"
|
||||||
|
@ -295,3 +295,4 @@ character-set=latin1
|
|||||||
"MySQL är started i --skip-grant-tables mod. Pga av detta kan du inte använda detta program",
|
"MySQL är started i --skip-grant-tables mod. Pga av detta kan du inte använda detta program",
|
||||||
|
|
||||||
"Column '%-.100s' has duplicated value '%-.64s' in %s"
|
"Column '%-.100s' has duplicated value '%-.64s' in %s"
|
||||||
|
"Truncated wrong %-.32s value: '%-.128s'"
|
||||||
|
@ -300,3 +300,4 @@ character-set=koi8u
|
|||||||
"The '%s' feature was disabled; you need MySQL built with '%s' to have it working",
|
"The '%s' feature was disabled; you need MySQL built with '%s' to have it working",
|
||||||
"The MySQL server is running with the %s option so it cannot execute this statement",
|
"The MySQL server is running with the %s option so it cannot execute this statement",
|
||||||
"Column '%-.100s' has duplicated value '%-.64s' in %s"
|
"Column '%-.100s' has duplicated value '%-.64s' in %s"
|
||||||
|
"Truncated wrong %-.32s value: '%-.128s'"
|
||||||
|
@ -25,7 +25,7 @@ Geometry::Class_info *Geometry::ci_collection[Geometry::wkb_end]=
|
|||||||
};
|
};
|
||||||
|
|
||||||
static Geometry::Class_info **ci_collection_end=
|
static Geometry::Class_info **ci_collection_end=
|
||||||
Geometry::ci_collection+Geometry::wkb_end;
|
Geometry::ci_collection+Geometry::wkb_end + 1;
|
||||||
|
|
||||||
Geometry::Class_info::Class_info(const char *name, int type_id,
|
Geometry::Class_info::Class_info(const char *name, int type_id,
|
||||||
void(*create_func)(void *)):
|
void(*create_func)(void *)):
|
||||||
|
@ -157,7 +157,7 @@ struct Geometry_buffer;
|
|||||||
class Geometry
|
class Geometry
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
static void *operator new(unsigned size_t, void *buffer)
|
static void *operator new(size_t size, void *buffer)
|
||||||
{
|
{
|
||||||
return buffer;
|
return buffer;
|
||||||
}
|
}
|
||||||
|
@ -657,7 +657,7 @@ public:
|
|||||||
points to a lock object if the lock is present. See item_func.cc and
|
points to a lock object if the lock is present. See item_func.cc and
|
||||||
chapter 'Miscellaneous functions', for functions GET_LOCK, RELEASE_LOCK.
|
chapter 'Miscellaneous functions', for functions GET_LOCK, RELEASE_LOCK.
|
||||||
*/
|
*/
|
||||||
ULL *ull;
|
User_level_lock *ull;
|
||||||
#ifndef DBUG_OFF
|
#ifndef DBUG_OFF
|
||||||
uint dbug_sentry; // watch out for memory corruption
|
uint dbug_sentry; // watch out for memory corruption
|
||||||
#endif
|
#endif
|
||||||
|
@ -1405,7 +1405,7 @@ bool dispatch_command(enum enum_server_command command, THD *thd,
|
|||||||
}
|
}
|
||||||
case COM_EXECUTE:
|
case COM_EXECUTE:
|
||||||
{
|
{
|
||||||
mysql_stmt_execute(thd, packet);
|
mysql_stmt_execute(thd, packet, packet_length);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case COM_LONG_DATA:
|
case COM_LONG_DATA:
|
||||||
|
@ -94,7 +94,8 @@ public:
|
|||||||
bool long_data_used;
|
bool long_data_used;
|
||||||
bool log_full_query;
|
bool log_full_query;
|
||||||
#ifndef EMBEDDED_LIBRARY
|
#ifndef EMBEDDED_LIBRARY
|
||||||
bool (*set_params)(Prepared_statement *st, uchar *pos, uchar *read_pos);
|
bool (*set_params)(Prepared_statement *st, uchar *data, uchar *data_end,
|
||||||
|
uchar *read_pos);
|
||||||
#else
|
#else
|
||||||
bool (*set_params_data)(Prepared_statement *st);
|
bool (*set_params_data)(Prepared_statement *st);
|
||||||
#endif
|
#endif
|
||||||
@ -117,14 +118,6 @@ inline bool is_param_null(const uchar *pos, ulong param_no)
|
|||||||
|
|
||||||
enum { STMT_QUERY_LOG_LENGTH= 8192 };
|
enum { STMT_QUERY_LOG_LENGTH= 8192 };
|
||||||
|
|
||||||
#ifdef EMBEDDED_LIBRARY
|
|
||||||
#define SET_PARAM_FUNCTION(fn_name) \
|
|
||||||
static void fn_name(Item_param *param, uchar **pos, ulong data_len)
|
|
||||||
#else
|
|
||||||
#define SET_PARAM_FUNCTION(fn_name) \
|
|
||||||
static void fn_name(Item_param *param, uchar **pos)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
enum enum_send_error { DONT_SEND_ERROR= 0, SEND_ERROR };
|
enum enum_send_error { DONT_SEND_ERROR= 0, SEND_ERROR };
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -186,29 +179,38 @@ static bool send_prep_stmt(Prepared_statement *stmt,
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef EMBEDDED_LIBRARY
|
#ifndef EMBEDDED_LIBRARY
|
||||||
static ulong get_param_length(uchar **packet)
|
static ulong get_param_length(uchar **packet, ulong len)
|
||||||
{
|
{
|
||||||
reg1 uchar *pos= *packet;
|
reg1 uchar *pos= *packet;
|
||||||
|
if (len < 1)
|
||||||
|
return 0;
|
||||||
if (*pos < 251)
|
if (*pos < 251)
|
||||||
{
|
{
|
||||||
(*packet)++;
|
(*packet)++;
|
||||||
return (ulong) *pos;
|
return (ulong) *pos;
|
||||||
}
|
}
|
||||||
|
if (len < 3)
|
||||||
|
return 0;
|
||||||
if (*pos == 252)
|
if (*pos == 252)
|
||||||
{
|
{
|
||||||
(*packet)+=3;
|
(*packet)+=3;
|
||||||
return (ulong) uint2korr(pos+1);
|
return (ulong) uint2korr(pos+1);
|
||||||
}
|
}
|
||||||
|
if (len < 4)
|
||||||
|
return 0;
|
||||||
if (*pos == 253)
|
if (*pos == 253)
|
||||||
{
|
{
|
||||||
(*packet)+=4;
|
(*packet)+=4;
|
||||||
return (ulong) uint3korr(pos+1);
|
return (ulong) uint3korr(pos+1);
|
||||||
}
|
}
|
||||||
|
if (len < 5)
|
||||||
|
return 0;
|
||||||
(*packet)+=9; // Must be 254 when here
|
(*packet)+=9; // Must be 254 when here
|
||||||
|
/* TODO: why uint4korr here? (should be uint8korr) */
|
||||||
return (ulong) uint4korr(pos+1);
|
return (ulong) uint4korr(pos+1);
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
#define get_param_length(A) data_len
|
#define get_param_length(packet, len) len
|
||||||
#endif /*!EMBEDDED_LIBRARY*/
|
#endif /*!EMBEDDED_LIBRARY*/
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -230,55 +232,80 @@ static ulong get_param_length(uchar **packet)
|
|||||||
none
|
none
|
||||||
*/
|
*/
|
||||||
|
|
||||||
SET_PARAM_FUNCTION(set_param_tiny)
|
void set_param_tiny(Item_param *param, uchar **pos, ulong len)
|
||||||
{
|
{
|
||||||
|
#ifndef EMBEDDED_LIBRARY
|
||||||
|
if (len < 1)
|
||||||
|
return;
|
||||||
|
#endif
|
||||||
param->set_int((longlong)(**pos));
|
param->set_int((longlong)(**pos));
|
||||||
*pos+= 1;
|
*pos+= 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
SET_PARAM_FUNCTION(set_param_short)
|
void set_param_short(Item_param *param, uchar **pos, ulong len)
|
||||||
{
|
{
|
||||||
|
#ifndef EMBEDDED_LIBRARY
|
||||||
|
if (len < 2)
|
||||||
|
return;
|
||||||
|
#endif
|
||||||
param->set_int((longlong)sint2korr(*pos));
|
param->set_int((longlong)sint2korr(*pos));
|
||||||
*pos+= 2;
|
*pos+= 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
SET_PARAM_FUNCTION(set_param_int32)
|
void set_param_int32(Item_param *param, uchar **pos, ulong len)
|
||||||
{
|
{
|
||||||
|
#ifndef EMBEDDED_LIBRARY
|
||||||
|
if (len < 4)
|
||||||
|
return;
|
||||||
|
#endif
|
||||||
param->set_int((longlong)sint4korr(*pos));
|
param->set_int((longlong)sint4korr(*pos));
|
||||||
*pos+= 4;
|
*pos+= 4;
|
||||||
}
|
}
|
||||||
|
|
||||||
SET_PARAM_FUNCTION(set_param_int64)
|
void set_param_int64(Item_param *param, uchar **pos, ulong len)
|
||||||
{
|
{
|
||||||
|
#ifndef EMBEDDED_LIBRARY
|
||||||
|
if (len < 8)
|
||||||
|
return;
|
||||||
|
#endif
|
||||||
param->set_int((longlong)sint8korr(*pos));
|
param->set_int((longlong)sint8korr(*pos));
|
||||||
*pos+= 8;
|
*pos+= 8;
|
||||||
}
|
}
|
||||||
|
|
||||||
SET_PARAM_FUNCTION(set_param_float)
|
void set_param_float(Item_param *param, uchar **pos, ulong len)
|
||||||
{
|
{
|
||||||
|
#ifndef EMBEDDED_LIBRARY
|
||||||
|
if (len < 4)
|
||||||
|
return;
|
||||||
|
#endif
|
||||||
float data;
|
float data;
|
||||||
float4get(data,*pos);
|
float4get(data,*pos);
|
||||||
param->set_double((double) data);
|
param->set_double((double) data);
|
||||||
*pos+= 4;
|
*pos+= 4;
|
||||||
}
|
}
|
||||||
|
|
||||||
SET_PARAM_FUNCTION(set_param_double)
|
void set_param_double(Item_param *param, uchar **pos, ulong len)
|
||||||
{
|
{
|
||||||
|
#ifndef EMBEDDED_LIBRARY
|
||||||
|
if (len < 8)
|
||||||
|
return;
|
||||||
|
#endif
|
||||||
double data;
|
double data;
|
||||||
float8get(data,*pos);
|
float8get(data,*pos);
|
||||||
param->set_double((double) data);
|
param->set_double((double) data);
|
||||||
*pos+= 8;
|
*pos+= 8;
|
||||||
}
|
}
|
||||||
|
|
||||||
SET_PARAM_FUNCTION(set_param_time)
|
void set_param_time(Item_param *param, uchar **pos, ulong len)
|
||||||
{
|
{
|
||||||
ulong length;
|
ulong length;
|
||||||
|
|
||||||
if ((length= get_param_length(pos)))
|
if ((length= get_param_length(pos, len)) >= 8)
|
||||||
{
|
{
|
||||||
uchar *to= *pos;
|
uchar *to= *pos;
|
||||||
TIME tm;
|
TIME tm;
|
||||||
|
|
||||||
|
/* TODO: why length is compared with 8 here? */
|
||||||
tm.second_part= (length > 8 ) ? (ulong) sint4korr(to+7): 0;
|
tm.second_part= (length > 8 ) ? (ulong) sint4korr(to+7): 0;
|
||||||
|
|
||||||
tm.day= (ulong) sint4korr(to+1);
|
tm.day= (ulong) sint4korr(to+1);
|
||||||
@ -294,11 +321,11 @@ SET_PARAM_FUNCTION(set_param_time)
|
|||||||
*pos+= length;
|
*pos+= length;
|
||||||
}
|
}
|
||||||
|
|
||||||
SET_PARAM_FUNCTION(set_param_datetime)
|
void set_param_datetime(Item_param *param, uchar **pos, ulong len)
|
||||||
{
|
{
|
||||||
uint length;
|
uint length;
|
||||||
|
|
||||||
if ((length= get_param_length(pos)))
|
if ((length= get_param_length(pos, len)) >= 4)
|
||||||
{
|
{
|
||||||
uchar *to= *pos;
|
uchar *to= *pos;
|
||||||
TIME tm;
|
TIME tm;
|
||||||
@ -324,11 +351,11 @@ SET_PARAM_FUNCTION(set_param_datetime)
|
|||||||
*pos+= length;
|
*pos+= length;
|
||||||
}
|
}
|
||||||
|
|
||||||
SET_PARAM_FUNCTION(set_param_date)
|
void set_param_date(Item_param *param, uchar **pos, ulong len)
|
||||||
{
|
{
|
||||||
ulong length;
|
ulong length;
|
||||||
|
|
||||||
if ((length= get_param_length(pos)))
|
if ((length= get_param_length(pos, len)) >= 4)
|
||||||
{
|
{
|
||||||
uchar *to= *pos;
|
uchar *to= *pos;
|
||||||
TIME tm;
|
TIME tm;
|
||||||
@ -346,11 +373,11 @@ SET_PARAM_FUNCTION(set_param_date)
|
|||||||
*pos+= length;
|
*pos+= length;
|
||||||
}
|
}
|
||||||
|
|
||||||
SET_PARAM_FUNCTION(set_param_str)
|
void set_param_str(Item_param *param, uchar **pos, ulong len)
|
||||||
{
|
{
|
||||||
ulong len= get_param_length(pos);
|
ulong length= get_param_length(pos, len);
|
||||||
param->set_value((const char *)*pos, len);
|
param->set_value((const char *)*pos, length);
|
||||||
*pos+= len;
|
*pos+= length;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void setup_one_conversion_function(Item_param *param, uchar param_type)
|
static void setup_one_conversion_function(Item_param *param, uchar param_type)
|
||||||
@ -405,8 +432,8 @@ static void setup_one_conversion_function(Item_param *param, uchar param_type)
|
|||||||
and if binary/update log is set, generate the valid query.
|
and if binary/update log is set, generate the valid query.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
static bool insert_params_withlog(Prepared_statement *stmt, uchar *pos,
|
static bool insert_params_withlog(Prepared_statement *stmt, uchar *null_array,
|
||||||
uchar *read_pos)
|
uchar *read_pos, uchar *data_end)
|
||||||
{
|
{
|
||||||
THD *thd= stmt->thd;
|
THD *thd= stmt->thd;
|
||||||
Item_param **begin= stmt->param_array;
|
Item_param **begin= stmt->param_array;
|
||||||
@ -428,7 +455,7 @@ static bool insert_params_withlog(Prepared_statement *stmt, uchar *pos,
|
|||||||
res= param->query_val_str(&str);
|
res= param->query_val_str(&str);
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (is_param_null(pos, it - begin))
|
if (is_param_null(null_array, it - begin))
|
||||||
{
|
{
|
||||||
param->maybe_null= param->null_value= 1;
|
param->maybe_null= param->null_value= 1;
|
||||||
res= &my_null_string;
|
res= &my_null_string;
|
||||||
@ -436,7 +463,9 @@ static bool insert_params_withlog(Prepared_statement *stmt, uchar *pos,
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
param->maybe_null= param->null_value= 0;
|
param->maybe_null= param->null_value= 0;
|
||||||
param->set_param_func(param, &read_pos);
|
if (read_pos >= data_end)
|
||||||
|
DBUG_RETURN(1);
|
||||||
|
param->set_param_func(param, &read_pos, data_end - read_pos);
|
||||||
res= param->query_val_str(&str);
|
res= param->query_val_str(&str);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -452,8 +481,8 @@ static bool insert_params_withlog(Prepared_statement *stmt, uchar *pos,
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static bool insert_params(Prepared_statement *stmt, uchar *pos,
|
static bool insert_params(Prepared_statement *stmt, uchar *null_array,
|
||||||
uchar *read_pos)
|
uchar *read_pos, uchar *data_end)
|
||||||
{
|
{
|
||||||
Item_param **begin= stmt->param_array;
|
Item_param **begin= stmt->param_array;
|
||||||
Item_param **end= begin + stmt->param_count;
|
Item_param **end= begin + stmt->param_count;
|
||||||
@ -465,20 +494,23 @@ static bool insert_params(Prepared_statement *stmt, uchar *pos,
|
|||||||
Item_param *param= *it;
|
Item_param *param= *it;
|
||||||
if (!param->long_data_supplied)
|
if (!param->long_data_supplied)
|
||||||
{
|
{
|
||||||
if (is_param_null(pos, it - begin))
|
if (is_param_null(null_array, it - begin))
|
||||||
param->maybe_null= param->null_value= 1;
|
param->maybe_null= param->null_value= 1;
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
param->maybe_null= param->null_value= 0;
|
param->maybe_null= param->null_value= 0;
|
||||||
param->set_param_func(param, &read_pos);
|
if (read_pos >= data_end)
|
||||||
|
DBUG_RETURN(1);
|
||||||
|
param->set_param_func(param, &read_pos, data_end - read_pos);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
DBUG_RETURN(0);
|
DBUG_RETURN(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static bool setup_conversion_functions(Prepared_statement *stmt,
|
static bool setup_conversion_functions(Prepared_statement *stmt,
|
||||||
uchar **data)
|
uchar **data, uchar *data_end)
|
||||||
{
|
{
|
||||||
/* skip null bits */
|
/* skip null bits */
|
||||||
uchar *read_pos= *data + (stmt->param_count+7) / 8;
|
uchar *read_pos= *data + (stmt->param_count+7) / 8;
|
||||||
@ -495,6 +527,8 @@ static bool setup_conversion_functions(Prepared_statement *stmt,
|
|||||||
Item_param **end= it + stmt->param_count;
|
Item_param **end= it + stmt->param_count;
|
||||||
for (; it < end; ++it)
|
for (; it < end; ++it)
|
||||||
{
|
{
|
||||||
|
if (read_pos >= data_end)
|
||||||
|
DBUG_RETURN(1);
|
||||||
setup_one_conversion_function(*it, *read_pos);
|
setup_one_conversion_function(*it, *read_pos);
|
||||||
read_pos+= 2;
|
read_pos+= 2;
|
||||||
}
|
}
|
||||||
@ -1072,7 +1106,7 @@ static void reset_stmt_for_execute(Prepared_statement *stmt)
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
void mysql_stmt_execute(THD *thd, char *packet)
|
void mysql_stmt_execute(THD *thd, char *packet, uint packet_length)
|
||||||
{
|
{
|
||||||
ulong stmt_id= uint4korr(packet);
|
ulong stmt_id= uint4korr(packet);
|
||||||
Prepared_statement *stmt;
|
Prepared_statement *stmt;
|
||||||
@ -1097,10 +1131,11 @@ void mysql_stmt_execute(THD *thd, char *packet)
|
|||||||
#ifndef EMBEDDED_LIBRARY
|
#ifndef EMBEDDED_LIBRARY
|
||||||
if (stmt->param_count)
|
if (stmt->param_count)
|
||||||
{
|
{
|
||||||
|
uchar *packet_end= (uchar *) packet + packet_length - 1;
|
||||||
packet+= 4;
|
packet+= 4;
|
||||||
uchar *null_array= (uchar *) packet;
|
uchar *null_array= (uchar *) packet;
|
||||||
if (setup_conversion_functions(stmt, (uchar **) &packet) ||
|
if (setup_conversion_functions(stmt, (uchar **) &packet, packet_end) ||
|
||||||
stmt->set_params(stmt, null_array, (uchar *) packet))
|
stmt->set_params(stmt, null_array, (uchar *) packet, packet_end))
|
||||||
goto set_params_data_err;
|
goto set_params_data_err;
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
@ -1159,6 +1194,7 @@ set_params_data_err:
|
|||||||
|
|
||||||
void mysql_stmt_reset(THD *thd, char *packet)
|
void mysql_stmt_reset(THD *thd, char *packet)
|
||||||
{
|
{
|
||||||
|
/* There is always space for 4 bytes in buffer */
|
||||||
ulong stmt_id= uint4korr(packet);
|
ulong stmt_id= uint4korr(packet);
|
||||||
Prepared_statement *stmt;
|
Prepared_statement *stmt;
|
||||||
|
|
||||||
@ -1189,6 +1225,7 @@ void mysql_stmt_reset(THD *thd, char *packet)
|
|||||||
|
|
||||||
void mysql_stmt_free(THD *thd, char *packet)
|
void mysql_stmt_free(THD *thd, char *packet)
|
||||||
{
|
{
|
||||||
|
/* There is always space for 4 bytes in packet buffer */
|
||||||
ulong stmt_id= uint4korr(packet);
|
ulong stmt_id= uint4korr(packet);
|
||||||
Prepared_statement *stmt;
|
Prepared_statement *stmt;
|
||||||
|
|
||||||
|
72
sql/time.cc
72
sql/time.cc
@ -391,9 +391,11 @@ str_to_TIME(const char *str, uint length, TIME *l_time, uint flags)
|
|||||||
ulong not_zero_date, allow_space;
|
ulong not_zero_date, allow_space;
|
||||||
bool is_internal_format;
|
bool is_internal_format;
|
||||||
const char *pos, *last_field_pos;
|
const char *pos, *last_field_pos;
|
||||||
|
const char *str_begin= str;
|
||||||
const char *end=str+length;
|
const char *end=str+length;
|
||||||
const uchar *format_position;
|
const uchar *format_position;
|
||||||
bool found_delimitier= 0, found_space= 0;
|
bool found_delimitier= 0, found_space= 0;
|
||||||
|
uint frac_pos, frac_len;
|
||||||
DBUG_ENTER("str_to_TIME");
|
DBUG_ENTER("str_to_TIME");
|
||||||
DBUG_PRINT("ENTER",("str: %.*s",length,str));
|
DBUG_PRINT("ENTER",("str: %.*s",length,str));
|
||||||
|
|
||||||
@ -482,7 +484,7 @@ str_to_TIME(const char *str, uint length, TIME *l_time, uint flags)
|
|||||||
tmp_value=tmp_value*10 + (ulong) (uchar) (*str - '0');
|
tmp_value=tmp_value*10 + (ulong) (uchar) (*str - '0');
|
||||||
str++;
|
str++;
|
||||||
}
|
}
|
||||||
date_len[i]+= (uint) (str - start);
|
date_len[i]= (uint) (str - start);
|
||||||
if (tmp_value > 999999) // Impossible date part
|
if (tmp_value > 999999) // Impossible date part
|
||||||
DBUG_RETURN(TIMESTAMP_NONE);
|
DBUG_RETURN(TIMESTAMP_NONE);
|
||||||
date[i]=tmp_value;
|
date[i]=tmp_value;
|
||||||
@ -535,9 +537,9 @@ str_to_TIME(const char *str, uint length, TIME *l_time, uint flags)
|
|||||||
{
|
{
|
||||||
if (str+2 <= end && (str[1] == 'M' || str[1] == 'm'))
|
if (str+2 <= end && (str[1] == 'M' || str[1] == 'm'))
|
||||||
{
|
{
|
||||||
if (str[1] == 'p' || str[1] == 'P')
|
if (str[0] == 'p' || str[0] == 'P')
|
||||||
add_hours= 12;
|
add_hours= 12;
|
||||||
else if (str[1] != 'a' || str[1] != 'A')
|
else if (str[0] != 'a' || str[0] != 'A')
|
||||||
continue; // Not AM/PM
|
continue; // Not AM/PM
|
||||||
str+= 2; // Skip AM/PM
|
str+= 2; // Skip AM/PM
|
||||||
/* Skip space after AM/PM */
|
/* Skip space after AM/PM */
|
||||||
@ -569,7 +571,13 @@ str_to_TIME(const char *str, uint length, TIME *l_time, uint flags)
|
|||||||
l_time->hour= date[(uint) format_position[3]];
|
l_time->hour= date[(uint) format_position[3]];
|
||||||
l_time->minute= date[(uint) format_position[4]];
|
l_time->minute= date[(uint) format_position[4]];
|
||||||
l_time->second= date[(uint) format_position[5]];
|
l_time->second= date[(uint) format_position[5]];
|
||||||
l_time->second_part= date[(uint) format_position[6]];
|
|
||||||
|
frac_pos= (uint) format_position[6];
|
||||||
|
frac_len= date_len[frac_pos];
|
||||||
|
if (frac_len < 6)
|
||||||
|
date[frac_pos]*= (uint) log_10_int[6 - frac_len];
|
||||||
|
l_time->second_part= date[frac_pos];
|
||||||
|
|
||||||
if (format_position[7] != (uchar) 255)
|
if (format_position[7] != (uchar) 255)
|
||||||
{
|
{
|
||||||
if (l_time->hour > 12)
|
if (l_time->hour > 12)
|
||||||
@ -585,6 +593,8 @@ str_to_TIME(const char *str, uint length, TIME *l_time, uint flags)
|
|||||||
l_time->hour= date[3];
|
l_time->hour= date[3];
|
||||||
l_time->minute= date[4];
|
l_time->minute= date[4];
|
||||||
l_time->second= date[5];
|
l_time->second= date[5];
|
||||||
|
if (date_len[6] < 6)
|
||||||
|
date[6]*= (uint) log_10_int[6 - date_len[6]];
|
||||||
l_time->second_part=date[6];
|
l_time->second_part=date[6];
|
||||||
}
|
}
|
||||||
l_time->neg= 0;
|
l_time->neg= 0;
|
||||||
@ -614,17 +624,19 @@ str_to_TIME(const char *str, uint length, TIME *l_time, uint flags)
|
|||||||
current_thd->cuted_fields++;
|
current_thd->cuted_fields++;
|
||||||
goto err;
|
goto err;
|
||||||
}
|
}
|
||||||
if (str != end && current_thd->count_cuted_fields)
|
|
||||||
{
|
l_time->time_type= (number_of_fields <= 3 ?
|
||||||
|
TIMESTAMP_DATE : TIMESTAMP_DATETIME);
|
||||||
|
|
||||||
for (; str != end ; str++)
|
for (; str != end ; str++)
|
||||||
{
|
{
|
||||||
if (!my_isspace(&my_charset_latin1,*str))
|
if (!my_isspace(&my_charset_latin1,*str))
|
||||||
{
|
{
|
||||||
current_thd->cuted_fields++;
|
make_truncated_value_warning(current_thd, str_begin, length,
|
||||||
|
l_time->time_type);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
DBUG_RETURN(l_time->time_type=
|
DBUG_RETURN(l_time->time_type=
|
||||||
(number_of_fields <= 3 ? TIMESTAMP_DATE : TIMESTAMP_DATETIME));
|
(number_of_fields <= 3 ? TIMESTAMP_DATE : TIMESTAMP_DATETIME));
|
||||||
@ -686,6 +698,7 @@ bool str_to_time(const char *str,uint length,TIME *l_time)
|
|||||||
{
|
{
|
||||||
long date[5],value;
|
long date[5],value;
|
||||||
const char *end=str+length, *end_of_days;
|
const char *end=str+length, *end_of_days;
|
||||||
|
const char *str_begin= str;
|
||||||
bool found_days,found_hours;
|
bool found_days,found_hours;
|
||||||
uint state;
|
uint state;
|
||||||
|
|
||||||
@ -784,6 +797,8 @@ fractional:
|
|||||||
my_isdigit(&my_charset_latin1,str[0]) &&
|
my_isdigit(&my_charset_latin1,str[0]) &&
|
||||||
field_length--)
|
field_length--)
|
||||||
value=value*10 + (uint) (uchar) (*str - '0');
|
value=value*10 + (uint) (uchar) (*str - '0');
|
||||||
|
if (field_length)
|
||||||
|
value*= (long) log_10_int[field_length];
|
||||||
date[4]=value;
|
date[4]=value;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@ -796,12 +811,12 @@ fractional:
|
|||||||
str++;
|
str++;
|
||||||
if (str+2 <= end && (str[1] == 'M' || str[1] == 'm'))
|
if (str+2 <= end && (str[1] == 'M' || str[1] == 'm'))
|
||||||
{
|
{
|
||||||
if (str[1] == 'p' || str[1] == 'P')
|
if (str[0] == 'p' || str[0] == 'P')
|
||||||
{
|
{
|
||||||
str+= 2;
|
str+= 2;
|
||||||
date[1]= date[1]%12 + 12;
|
date[1]= date[1]%12 + 12;
|
||||||
}
|
}
|
||||||
else if (str[1] == 'a' || str[1] == 'A')
|
else if (str[0] == 'a' || str[0] == 'A')
|
||||||
str+=2;
|
str+=2;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -822,13 +837,14 @@ fractional:
|
|||||||
l_time->time_type= TIMESTAMP_TIME;
|
l_time->time_type= TIMESTAMP_TIME;
|
||||||
|
|
||||||
/* Check if there is garbage at end of the TIME specification */
|
/* Check if there is garbage at end of the TIME specification */
|
||||||
if (str != end && current_thd->count_cuted_fields)
|
if (str != end)
|
||||||
{
|
{
|
||||||
do
|
do
|
||||||
{
|
{
|
||||||
if (!my_isspace(&my_charset_latin1,*str))
|
if (!my_isspace(&my_charset_latin1,*str))
|
||||||
{
|
{
|
||||||
current_thd->cuted_fields++;
|
make_truncated_value_warning(current_thd, str_begin, length,
|
||||||
|
TIMESTAMP_TIME);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
} while (++str != end);
|
} while (++str != end);
|
||||||
@ -1265,3 +1281,35 @@ void make_datetime(DATE_TIME_FORMAT *format, TIME *l_time, String *str)
|
|||||||
str->length(length);
|
str->length(length);
|
||||||
str->set_charset(&my_charset_bin);
|
str->set_charset(&my_charset_bin);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void make_truncated_value_warning(THD *thd, const char *str_val,
|
||||||
|
uint str_length, timestamp_type time_type)
|
||||||
|
{
|
||||||
|
char warn_buff[MYSQL_ERRMSG_SIZE];
|
||||||
|
const char *type_str;
|
||||||
|
|
||||||
|
char buff[128];
|
||||||
|
String str(buff,(uint32) sizeof(buff), system_charset_info);
|
||||||
|
str.length(0);
|
||||||
|
str.append(str_val, str_length);
|
||||||
|
str.append('\0');
|
||||||
|
|
||||||
|
switch (time_type) {
|
||||||
|
case TIMESTAMP_DATE:
|
||||||
|
type_str= "date";
|
||||||
|
break;
|
||||||
|
case TIMESTAMP_DATETIME:
|
||||||
|
type_str= "datetime";
|
||||||
|
break;
|
||||||
|
case TIMESTAMP_TIME:
|
||||||
|
type_str= "time";
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
type_str= "string";
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
sprintf(warn_buff, ER(ER_TRUNCATED_WRONG_VALUE),
|
||||||
|
type_str, str.ptr());
|
||||||
|
push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_NOTE,
|
||||||
|
ER_TRUNCATED_WRONG_VALUE, warn_buff);
|
||||||
|
}
|
||||||
|
@ -262,9 +262,9 @@ long my_strntol_8bit(CHARSET_INFO *cs,
|
|||||||
{
|
{
|
||||||
if (c>='0' && c<='9')
|
if (c>='0' && c<='9')
|
||||||
c -= '0';
|
c -= '0';
|
||||||
else if (c>='A' && c<='F')
|
else if (c>='A' && c<='Z')
|
||||||
c = c - 'A' + 10;
|
c = c - 'A' + 10;
|
||||||
else if (c>='a' && c<='f')
|
else if (c>='a' && c<='z')
|
||||||
c = c - 'a' + 10;
|
c = c - 'a' + 10;
|
||||||
else
|
else
|
||||||
break;
|
break;
|
||||||
@ -384,9 +384,9 @@ ulong my_strntoul_8bit(CHARSET_INFO *cs,
|
|||||||
{
|
{
|
||||||
if (c>='0' && c<='9')
|
if (c>='0' && c<='9')
|
||||||
c -= '0';
|
c -= '0';
|
||||||
else if (c>='A' && c<='F')
|
else if (c>='A' && c<='Z')
|
||||||
c = c - 'A' + 10;
|
c = c - 'A' + 10;
|
||||||
else if (c>='a' && c<='f')
|
else if (c>='a' && c<='z')
|
||||||
c = c - 'a' + 10;
|
c = c - 'a' + 10;
|
||||||
else
|
else
|
||||||
break;
|
break;
|
||||||
@ -499,9 +499,9 @@ longlong my_strntoll_8bit(CHARSET_INFO *cs __attribute__((unused)),
|
|||||||
{
|
{
|
||||||
if (c>='0' && c<='9')
|
if (c>='0' && c<='9')
|
||||||
c -= '0';
|
c -= '0';
|
||||||
else if (c>='A' && c<='F')
|
else if (c>='A' && c<='Z')
|
||||||
c = c - 'A' + 10;
|
c = c - 'A' + 10;
|
||||||
else if (c>='a' && c<='f')
|
else if (c>='a' && c<='z')
|
||||||
c = c - 'a' + 10;
|
c = c - 'a' + 10;
|
||||||
else
|
else
|
||||||
break;
|
break;
|
||||||
@ -622,9 +622,9 @@ ulonglong my_strntoull_8bit(CHARSET_INFO *cs,
|
|||||||
{
|
{
|
||||||
if (c>='0' && c<='9')
|
if (c>='0' && c<='9')
|
||||||
c -= '0';
|
c -= '0';
|
||||||
else if (c>='A' && c<='F')
|
else if (c>='A' && c<='Z')
|
||||||
c = c - 'A' + 10;
|
c = c - 'A' + 10;
|
||||||
else if (c>='a' && c<='f')
|
else if (c>='a' && c<='z')
|
||||||
c = c - 'a' + 10;
|
c = c - 'a' + 10;
|
||||||
else
|
else
|
||||||
break;
|
break;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user