1
0
mirror of https://github.com/MariaDB/server.git synced 2025-08-05 13:16:09 +03:00

Merge sanja.is.com.ua:/home/bell/mysql/bk/mysql-4.1

into sanja.is.com.ua:/home/bell/mysql/bk/work-top-4.1
This commit is contained in:
unknown
2003-05-26 22:00:03 +03:00
27 changed files with 446 additions and 318 deletions

View File

@@ -1766,7 +1766,10 @@ following connection establishment sequence is followed:
+--------------------------------------------------------------------+ +--------------------------------------------------------------------+
| Header | CLIENT_xxx options supported | max_allowed_packet | | Header | CLIENT_xxx options supported | max_allowed_packet |
| | by client | for client | | | by client | for client |
| | 2 Bytes | 3 bytes | | | 4 Bytes | 4 bytes |
|--------------------------------------------------------------------|
| Character set | Reserved for the future |
| 1 Bytes | 23 bytes |
|--------------------------------------------------------------------| |--------------------------------------------------------------------|
| User Name | 0x00 | Crypted Password | 0x00 | Database Name | | User Name | 0x00 | Crypted Password | 0x00 | Database Name |
| n Bytes | 1 Byte | 8 Bytes | 1 Byte | n Bytes | | n Bytes | 1 Byte | 8 Bytes | 1 Byte | n Bytes |
@@ -2326,7 +2329,7 @@ Warnings
@item @item
Prepared statements Prepared statements
@item @item
Binary protocol (will be faster than the current protocol that Binary protocol (is be faster than the current protocol that
converts everything to strings) converts everything to strings)
@end itemize @end itemize
@@ -2335,7 +2338,7 @@ What has changed in 4.1 are:
@itemize @bullet @itemize @bullet
@item @item
A lot of new field information (database, real table name etc) A lot of new field information (catalog, database, real table name etc)
@item @item
The 'ok' packet has more status fields The 'ok' packet has more status fields
@item @item
@@ -2374,15 +2377,16 @@ The field description result set contains the meta info for a result set.
@multitable @columnfractions .20 .80 @multitable @columnfractions .20 .80
@item Type @tab Comment @item Type @tab Comment
@item string @tab Catalog name (for 5.x)
@item string @tab Database name @item string @tab Database name
@item string @tab Table name alias (or table name if no alias) @item string @tab Table name alias (or table name if no alias)
@item string @tab Real table name @item string @tab Real table name
@item string @tab Alias for column name (or column name if not used) @item string @tab Alias for column name (or column name if not used)
@item 11 byte @tab Fixed length fields in one field part: @item 12 byte @tab Fixed length fields in one field part:
@itemize @itemize
@item 2 byte int @tab Character set number @item 2 byte int @tab Character set number
@item 3 byte int @tab Length of column definition @item 4 byte int @tab Length of column definition
@item 1 byte int @tab Enum value for field type @item 1 byte int @tab Enum value for field type
@item 3 byte int @tab 2 byte column flags (NOT_NULL_FLAG etc..) + 1 byte number of decimals. @item 3 byte int @tab 2 byte column flags (NOT_NULL_FLAG etc..) + 1 byte number of decimals.
@item 2 byte int @tab zero (reserved for future use) @item 2 byte int @tab zero (reserved for future use)
@@ -2457,7 +2461,9 @@ The error packet has the following structure:
@item Size @tab Comment @item Size @tab Comment
@item 1 @tab 255 Error packet marker @item 1 @tab 255 Error packet marker
@item 2 @tab Error code @item 2 @tab Error code
@item 1-255 @tab Null terminated error message @item 1 @tab '#' marker that SQLSTATE follows
@item 6 @tab SQLSTATE code (000000 for many messages)
@item 1-512 @tab Null terminated error message
@end multitable @end multitable
The client/server protocol is designed in such a way that a packet The client/server protocol is designed in such a way that a packet

View File

@@ -68,40 +68,37 @@
/* Define charsets you want */ /* Define charsets you want */
#undef HAVE_CHARSET_armscii8 #undef HAVE_CHARSET_armscii8
#undef HAVE_CHARSET_ascii
#undef HAVE_CHARSET_big5 #undef HAVE_CHARSET_big5
#undef HAVE_CHARSET_cp1250
#undef HAVE_CHARSET_cp1251 #undef HAVE_CHARSET_cp1251
#undef HAVE_CHARSET_cp1256
#undef HAVE_CHARSET_cp1257 #undef HAVE_CHARSET_cp1257
#undef HAVE_CHARSET_croat #undef HAVE_CHARSET_cp850
#undef HAVE_CHARSET_czech #undef HAVE_CHARSET_cp852
#undef HAVE_CHARSET_danish #undef HAVE_CHARSET_cp866
#undef HAVE_CHARSET_dec8 #undef HAVE_CHARSET_dec8
#undef HAVE_CHARSET_dos #undef HAVE_CHARSET_euckr
#undef HAVE_CHARSET_estonia
#undef HAVE_CHARSET_euc_kr
#undef HAVE_CHARSET_gb2312 #undef HAVE_CHARSET_gb2312
#undef HAVE_CHARSET_gbk #undef HAVE_CHARSET_gbk
#undef HAVE_CHARSET_german1
#undef HAVE_CHARSET_greek #undef HAVE_CHARSET_greek
#undef HAVE_CHARSET_hebrew #undef HAVE_CHARSET_hebrew
#undef HAVE_CHARSET_hp8 #undef HAVE_CHARSET_hp8
#undef HAVE_CHARSET_hungarian #undef HAVE_CHARSET_keybcs2
#undef HAVE_CHARSET_koi8_ru #undef HAVE_CHARSET_koi8r
#undef HAVE_CHARSET_koi8_ukr #undef HAVE_CHARSET_koi8u
#undef HAVE_CHARSET_latin1 #undef HAVE_CHARSET_latin1
#undef HAVE_CHARSET_latin1_de
#undef HAVE_CHARSET_latin2 #undef HAVE_CHARSET_latin2
#undef HAVE_CHARSET_latin5 #undef HAVE_CHARSET_latin5
#undef HAVE_CHARSET_latin7
#undef HAVE_CHARSET_macce
#undef HAVE_CHARSET_macroman
#undef HAVE_CHARSET_sjis #undef HAVE_CHARSET_sjis
#undef HAVE_CHARSET_swe7 #undef HAVE_CHARSET_swe7
#undef HAVE_CHARSET_tis620 #undef HAVE_CHARSET_tis620
#undef HAVE_CHARSET_ucs2 #undef HAVE_CHARSET_ucs2
#undef HAVE_CHARSET_ujis #undef HAVE_CHARSET_ujis
#undef HAVE_CHARSET_usa7
#undef HAVE_CHARSET_utf8 #undef HAVE_CHARSET_utf8
#undef HAVE_CHARSET_win1250
#undef HAVE_CHARSET_win1250ch
#undef HAVE_CHARSET_win1251ukr
#undef HAVE_CHARSET_win1251
/* ZLIB and compress: */ /* ZLIB and compress: */
#undef HAVE_COMPRESS #undef HAVE_COMPRESS

View File

@@ -2226,29 +2226,36 @@ AC_SUBST(readline_h_ln_cmd)
dnl In order to add new charset, you must add charset name to dnl In order to add new charset, you must add charset name to
dnl this CHARSETS_AVAILABLE list and sql/share/charsets/Index. dnl this CHARSETS_AVAILABLE list and sql/share/charsets/Index.xml.
dnl If the character set uses strcoll or other special handling, dnl If the character set uses strcoll or other special handling,
dnl you must also create strings/ctype-$charset_name.c dnl you must also create strings/ctype-$charset_name.c
AC_DIVERT_PUSH(0) AC_DIVERT_PUSH(0)
CHARSETS_AVAILABLE="armscii8 big5 cp1251 cp1257
croat czech danish dec8 dos estonia euc_kr gb2312 gbk define(CHARSETS_AVAILABLE1,ascii armscii8 ascii big5 cp1250 cp1251 cp1256 cp1257)
german1 greek hebrew hp8 hungarian koi8_ru koi8_ukr define(CHARSETS_AVAILABLE2,cp850 cp852 cp866 dec8 euckr gb2312 gbk)
latin1 latin1_de latin2 latin5 sjis swe7 tis620 ucs2 ujis define(CHARSETS_AVAILABLE3,greek hebrew hp8 keybcs2 koi8r koi8u)
usa7 utf8 win1250 win1250ch win1251ukr" define(CHARSETS_AVAILABLE4,latin1 latin2 latin5 latin7 macce macroman)
CHARSETS_DEPRECATED="win1251" define(CHARSETS_AVAILABLE5,sjis swe7 tis620 ucs2 ujis utf8)
CHARSETS_COMPLEX="big5 czech euc_kr gb2312 gbk latin1_de sjis tis620 ucs2 ujis utf8 win1250ch"
DEFAULT_CHARSET=latin1 DEFAULT_CHARSET=latin1
CHARSETS_AVAILABLE="CHARSETS_AVAILABLE1 CHARSETS_AVAILABLE2 CHARSETS_AVAILABLE3 CHARSETS_AVAILABLE4 CHARSETS_AVAILABLE5"
CHARSETS_COMPLEX="big5 cp1250 euckr gb2312 gbk latin1 latin2 sjis tis620 ucs2 ujis utf8"
AC_DIVERT_POP AC_DIVERT_POP
dnl fix this later..
dnl [ --with-charset=CHARSET Use CHARSET by default (one of: $CHARSETS_AVAILABLE; Default is $DEFAULT_CHARSET)],
AC_ARG_WITH(charset, AC_ARG_WITH(charset,
[ --with-charset=CHARSET Use CHARSET by default (Default is latin1)], [ --with-charset=CHARSET
Default character set, use one of:
CHARSETS_AVAILABLE1
CHARSETS_AVAILABLE2
CHARSETS_AVAILABLE3
CHARSETS_AVAILABLE4
CHARSETS_AVAILABLE5],
[default_charset="$withval"], [default_charset="$withval"],
[default_charset="$DEFAULT_CHARSET"]) [default_charset="$DEFAULT_CHARSET"])
AC_ARG_WITH(extra-charsets, AC_ARG_WITH(extra-charsets,
[ --with-extra-charsets=CHARSET[,CHARSET,...] [ --with-extra-charsets=CHARSET[,CHARSET,...]
Use charsets in addition to default (none, complex, Use charsets in addition to default (none, complex,
@@ -2256,73 +2263,77 @@ AC_ARG_WITH(extra-charsets,
[extra_charsets="$withval"], [extra_charsets="$withval"],
[extra_charsets="none"]) [extra_charsets="none"])
AC_MSG_CHECKING("character sets") AC_MSG_CHECKING("character sets")
CHARSETS="$default_charset latin1 utf8"
if test "$extra_charsets" = no; then if test "$extra_charsets" = no; then
CHARSETS="" CHARSETS="$CHARSETS"
elif test "$extra_charsets" = none; then elif test "$extra_charsets" = none; then
CHARSETS="" CHARSETS="$CHARSETS"
elif test "$extra_charsets" = complex; then elif test "$extra_charsets" = complex; then
CHARSETS="$CHARSETS_COMPLEX" CHARSETS="$CHARSETS $CHARSETS_COMPLEX"
elif test "$extra_charsets" = all; then elif test "$extra_charsets" = all; then
CHARSETS="$CHARSETS_AVAILABLE $CHARSETS_DEPRECATED" CHARSETS="$CHARSETS $CHARSETS_AVAILABLE"
else else
CHARSETS=`echo $extra_charsets | sed -e 's/,/ /g'` EXTRA_CHARSETS=`echo $extra_charsets | sed -e 's/,/ /g'`
CHARSETS="$CHARSETS $EXTRA_CHARSETS"
fi fi
CHARSETS="$default_charset $CHARSETS"
use_mb="no"
for cs in $CHARSETS for cs in $CHARSETS
do do
case $cs in case $cs in
armscii8) armscii8)
AC_DEFINE(HAVE_CHARSET_armscii8) AC_DEFINE(HAVE_CHARSET_armscii8)
use_mb="yes" ;;
ascii)
AC_DEFINE(HAVE_CHARSET_ascii)
;; ;;
big5) big5)
AC_DEFINE(HAVE_CHARSET_big5) AC_DEFINE(HAVE_CHARSET_big5)
use_mb="yes" AC_DEFINE(USE_MB)
AC_DEFINE(USE_MB_IDENT)
;;
cp1250)
AC_DEFINE(HAVE_CHARSET_cp1250)
;; ;;
cp1251) cp1251)
AC_DEFINE(HAVE_CHARSET_cp1251) AC_DEFINE(HAVE_CHARSET_cp1251)
;; ;;
cp1256)
AC_DEFINE(HAVE_CHARSET_cp1256)
;;
cp1257) cp1257)
AC_DEFINE(HAVE_CHARSET_cp1257) AC_DEFINE(HAVE_CHARSET_cp1257)
;; ;;
croat) cp850)
AC_DEFINE(HAVE_CHARSET_croat) AC_DEFINE(HAVE_CHARSET_cp850)
;; ;;
czech) cp852)
AC_DEFINE(HAVE_CHARSET_czech) AC_DEFINE(HAVE_CHARSET_cp852)
;; ;;
danish) cp866)
AC_DEFINE(HAVE_CHARSET_danish) AC_DEFINE(HAVE_CHARSET_cp866)
;; ;;
dec8) dec8)
AC_DEFINE(HAVE_CHARSET_dec8) AC_DEFINE(HAVE_CHARSET_dec8)
;; ;;
dos) euckr)
AC_DEFINE(HAVE_CHARSET_dos) AC_DEFINE(HAVE_CHARSET_euckr)
;; AC_DEFINE(USE_MB)
estonia) AC_DEFINE(USE_MB_IDENT)
AC_DEFINE(HAVE_CHARSET_estonia)
;;
euc_kr)
AC_DEFINE(HAVE_CHARSET_euc_kr)
use_mb="yes"
;; ;;
gb2312) gb2312)
AC_DEFINE(HAVE_CHARSET_gb2312) AC_DEFINE(HAVE_CHARSET_gb2312)
use_mb="yes" AC_DEFINE(USE_MB)
AC_DEFINE(USE_MB_IDENT)
;; ;;
gbk) gbk)
AC_DEFINE(HAVE_CHARSET_gbk) AC_DEFINE(HAVE_CHARSET_gbk)
use_mb="yes" AC_DEFINE(USE_MB)
;; AC_DEFINE(USE_MB_IDENT)
german1)
AC_DEFINE(HAVE_CHARSET_german1)
;; ;;
greek) greek)
AC_DEFINE(HAVE_CHARSET_greek) AC_DEFINE(HAVE_CHARSET_greek)
@@ -2333,30 +2344,37 @@ do
hp8) hp8)
AC_DEFINE(HAVE_CHARSET_hp8) AC_DEFINE(HAVE_CHARSET_hp8)
;; ;;
hungarian) keybcs2)
AC_DEFINE(HAVE_CHARSET_hungarian) AC_DEFINE(HAVE_CHARSET_keybcs2)
;; ;;
koi8_ru) koi8r)
AC_DEFINE(HAVE_CHARSET_koi8_ru) AC_DEFINE(HAVE_CHARSET_koi8r)
;; ;;
koi8_ukr) koi8u)
AC_DEFINE(HAVE_CHARSET_koi8_ukr) AC_DEFINE(HAVE_CHARSET_koi8u)
;; ;;
latin1) latin1)
AC_DEFINE(HAVE_CHARSET_latin1) AC_DEFINE(HAVE_CHARSET_latin1)
;; ;;
latin1_de)
AC_DEFINE(HAVE_CHARSET_latin1_de)
;;
latin2) latin2)
AC_DEFINE(HAVE_CHARSET_latin2) AC_DEFINE(HAVE_CHARSET_latin2)
;; ;;
latin5) latin5)
AC_DEFINE(HAVE_CHARSET_latin5) AC_DEFINE(HAVE_CHARSET_latin5)
;; ;;
latin7)
AC_DEFINE(HAVE_CHARSET_latin7)
;;
macce)
AC_DEFINE(HAVE_CHARSET_macce)
;;
macroman)
AC_DEFINE(HAVE_CHARSET_macroman)
;;
sjis) sjis)
AC_DEFINE(HAVE_CHARSET_sjis) AC_DEFINE(HAVE_CHARSET_sjis)
use_mb="yes" AC_DEFINE(USE_MB)
AC_DEFINE(USE_MB_IDENT)
;; ;;
swe7) swe7)
AC_DEFINE(HAVE_CHARSET_swe7) AC_DEFINE(HAVE_CHARSET_swe7)
@@ -2366,49 +2384,25 @@ do
;; ;;
ucs2) ucs2)
AC_DEFINE(HAVE_CHARSET_ucs2) AC_DEFINE(HAVE_CHARSET_ucs2)
use_mb="yes" AC_DEFINE(USE_MB)
AC_DEFINE(USE_MB_IDENT)
;; ;;
ujis) ujis)
AC_DEFINE(HAVE_CHARSET_ujis) AC_DEFINE(HAVE_CHARSET_ujis)
use_mb="yes" AC_DEFINE(USE_MB)
;; AC_DEFINE(USE_MB_IDENT)
usa7)
AC_DEFINE(HAVE_CHARSET_usa7)
;; ;;
utf8) utf8)
AC_DEFINE(HAVE_CHARSET_utf8) AC_DEFINE(HAVE_CHARSET_utf8)
use_mb="yes" AC_DEFINE(USE_MB)
;; AC_DEFINE(USE_MB_IDENT)
win1250)
AC_DEFINE(HAVE_CHARSET_win1250)
;;
win1250ch)
AC_DEFINE(HAVE_CHARSET_win1250ch)
;;
win1251)
AC_DEFINE(HAVE_CHARSET_win1251)
;;
win1251ukr)
AC_DEFINE(HAVE_CHARSET_win1251ukr)
;; ;;
*) *)
AC_MSG_ERROR([Charset $cs not available. (Available $CHARSETS_AVAILABLE). AC_MSG_ERROR([Charset $cs not available. (Available are: $CHARSETS_AVAILABLE).
See the Installation chapter in the Reference Manual.]); See the Installation chapter in the Reference Manual.]);
esac esac
done done
dnl Always compile latin1
AC_DEFINE(HAVE_CHARSET_latin1)
dnl Always compile utf8
AC_DEFINE(HAVE_CHARSET_utf8)
use_mb=yes
if test "$use_mb" = "yes"
then
AC_DEFINE(USE_MB)
AC_DEFINE(USE_MB_IDENT)
fi
AC_SUBST(default_charset) AC_SUBST(default_charset)
AC_DEFINE_UNQUOTED(DEFAULT_CHARSET_NAME,"$default_charset") AC_DEFINE_UNQUOTED(DEFAULT_CHARSET_NAME,"$default_charset")

View File

@@ -83,6 +83,7 @@ typedef struct st_mysql_field {
char *table; /* Table of column if column was a field */ char *table; /* Table of column if column was a field */
char *org_table; /* Org table name, if table was an alias */ char *org_table; /* Org table name, if table was an alias */
char *db; /* Database for table */ char *db; /* Database for table */
char *catalog; /* Catalog for table */
char *def; /* Default value (set by mysql_list_fields) */ char *def; /* Default value (set by mysql_list_fields) */
unsigned long length; /* Width of column */ unsigned long length; /* Width of column */
unsigned long max_length; /* Max width of selected set */ unsigned long max_length; /* Max width of selected set */
@@ -91,6 +92,7 @@ typedef struct st_mysql_field {
unsigned int table_length; unsigned int table_length;
unsigned int org_table_length; unsigned int org_table_length;
unsigned int db_length; unsigned int db_length;
unsigned int catalog_length;
unsigned int def_length; unsigned int def_length;
unsigned int flags; /* Div flags */ unsigned int flags; /* Div flags */
unsigned int decimals; /* Number of decimals in field */ unsigned int decimals; /* Number of decimals in field */
@@ -346,6 +348,7 @@ my_ulonglong STDCALL mysql_affected_rows(MYSQL *mysql);
my_ulonglong STDCALL mysql_insert_id(MYSQL *mysql); my_ulonglong STDCALL mysql_insert_id(MYSQL *mysql);
unsigned int STDCALL mysql_errno(MYSQL *mysql); unsigned int STDCALL mysql_errno(MYSQL *mysql);
const char * STDCALL mysql_error(MYSQL *mysql); const char * STDCALL mysql_error(MYSQL *mysql);
const char *STDCALL mysql_sqlstate(MYSQL *mysql);
unsigned int STDCALL mysql_warning_count(MYSQL *mysql); unsigned int STDCALL mysql_warning_count(MYSQL *mysql);
const char * STDCALL mysql_info(MYSQL *mysql); const char * STDCALL mysql_info(MYSQL *mysql);
unsigned long STDCALL mysql_thread_id(MYSQL *mysql); unsigned long STDCALL mysql_thread_id(MYSQL *mysql);
@@ -543,6 +546,7 @@ typedef struct st_mysql_stmt
unsigned int last_errno; /* error code */ unsigned int last_errno; /* error code */
enum PREP_STMT_STATE state; /* statement state */ enum PREP_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];
my_bool long_alloced; /* flag to indicate long alloced */ my_bool long_alloced; /* flag to indicate long alloced */
my_bool send_types_to_server; /* Types sent to server */ my_bool send_types_to_server; /* Types sent to server */
my_bool param_buffers; /* param bound buffers */ my_bool param_buffers; /* param bound buffers */
@@ -560,6 +564,7 @@ my_bool STDCALL mysql_bind_result(MYSQL_STMT * stmt, MYSQL_BIND * bnd);
my_bool STDCALL mysql_stmt_close(MYSQL_STMT * stmt); my_bool STDCALL mysql_stmt_close(MYSQL_STMT * stmt);
unsigned int STDCALL mysql_stmt_errno(MYSQL_STMT * stmt); unsigned int STDCALL mysql_stmt_errno(MYSQL_STMT * stmt);
const char *STDCALL mysql_stmt_error(MYSQL_STMT * stmt); const char *STDCALL mysql_stmt_error(MYSQL_STMT * stmt);
const char *STDCALL mysql_stmt_sqlstate(MYSQL_STMT * stmt);
my_bool STDCALL mysql_commit(MYSQL * mysql); my_bool STDCALL mysql_commit(MYSQL * mysql);
my_bool STDCALL mysql_rollback(MYSQL * mysql); my_bool STDCALL mysql_rollback(MYSQL * mysql);
my_bool STDCALL mysql_autocommit(MYSQL * mysql, my_bool auto_mode); my_bool STDCALL mysql_autocommit(MYSQL * mysql, my_bool auto_mode);

View File

@@ -25,6 +25,7 @@
#define HOSTNAME_LENGTH 60 #define HOSTNAME_LENGTH 60
#define USERNAME_LENGTH 16 #define USERNAME_LENGTH 16
#define SERVER_VERSION_LENGTH 60 #define SERVER_VERSION_LENGTH 60
#define SQLSTATE_LENGTH 6
#define LOCAL_HOST "localhost" #define LOCAL_HOST "localhost"
#define LOCAL_HOST_NAMEDPIPE "." #define LOCAL_HOST_NAMEDPIPE "."
@@ -100,20 +101,22 @@ enum enum_server_command
#define CLIENT_ODBC 64 /* Odbc client */ #define CLIENT_ODBC 64 /* Odbc client */
#define CLIENT_LOCAL_FILES 128 /* Can use LOAD DATA LOCAL */ #define CLIENT_LOCAL_FILES 128 /* Can use LOAD DATA LOCAL */
#define CLIENT_IGNORE_SPACE 256 /* Ignore spaces before '(' */ #define CLIENT_IGNORE_SPACE 256 /* Ignore spaces before '(' */
#define CLIENT_PROTOCOL_41 512 /* New 4.1 protocol */
#define CLIENT_INTERACTIVE 1024 /* This is an interactive client */ #define CLIENT_INTERACTIVE 1024 /* This is an interactive client */
#define CLIENT_SSL 2048 /* Switch to SSL after handshake */ #define CLIENT_SSL 2048 /* Switch to SSL after handshake */
#define CLIENT_IGNORE_SIGPIPE 4096 /* IGNORE sigpipes */ #define CLIENT_IGNORE_SIGPIPE 4096 /* IGNORE sigpipes */
#define CLIENT_TRANSACTIONS 8192 /* Client knows about transactions */ #define CLIENT_TRANSACTIONS 8192 /* Client knows about transactions */
#define CLIENT_PROTOCOL_41 16384 /* New 4.1 protocol */ #define CLIENT_RESERVED 16384 /* Old flag for 4.1 protocol */
#define CLIENT_SECURE_CONNECTION 32768 /* New 4.1 authentication */ #define CLIENT_SECURE_CONNECTION 32768 /* New 4.1 authentication */
#define CLIENT_MULTI_QUERIES 65536 /* Enable/disable multi query support */ #define CLIENT_MULTI_QUERIES 65536 /* Enable/disable multiquery support */
#define CLIENT_MULTI_RESULTS 131072 /* Enable/disable multi-results */
#define SERVER_STATUS_IN_TRANS 1 /* Transaction has started */ #define SERVER_STATUS_IN_TRANS 1 /* Transaction has started */
#define SERVER_STATUS_AUTOCOMMIT 2 /* Server in auto_commit mode */ #define SERVER_STATUS_AUTOCOMMIT 2 /* Server in auto_commit mode */
#define SERVER_STATUS_MORE_RESULTS 4 /* More results on server */ #define SERVER_STATUS_MORE_RESULTS 4 /* More results on server */
#define SERVER_MORE_RESULTS_EXISTS 8 /* Multi query - next query exists */ #define SERVER_MORE_RESULTS_EXISTS 8 /* Multi query - next query exists */
#define MYSQL_ERRMSG_SIZE 200 #define MYSQL_ERRMSG_SIZE 512
#define NET_READ_TIMEOUT 30 /* Timeout on read */ #define NET_READ_TIMEOUT 30 /* Timeout on read */
#define NET_WRITE_TIMEOUT 60 /* Timeout on write */ #define NET_WRITE_TIMEOUT 60 /* Timeout on write */
#define NET_WAIT_TIMEOUT 8*60*60 /* Wait for new query */ #define NET_WAIT_TIMEOUT 8*60*60 /* Wait for new query */
@@ -149,7 +152,7 @@ typedef struct st_net {
queries in cache that have not stored its results yet queries in cache that have not stored its results yet
*/ */
#endif #endif
char last_error[MYSQL_ERRMSG_SIZE]; char last_error[MYSQL_ERRMSG_SIZE], sqlstate[SQLSTATE_LENGTH+1];
unsigned int last_errno; unsigned int last_errno;
unsigned char error; unsigned char error;
gptr query_cache_query; gptr query_cache_query;

View File

@@ -64,6 +64,7 @@ ulong net_buffer_length=8192;
ulong max_allowed_packet= 1024L*1024L*1024L; ulong max_allowed_packet= 1024L*1024L*1024L;
ulong net_read_timeout= NET_READ_TIMEOUT; ulong net_read_timeout= NET_READ_TIMEOUT;
ulong net_write_timeout= NET_WRITE_TIMEOUT; ulong net_write_timeout= NET_WRITE_TIMEOUT;
const char *unknown_sqlstate= "000000";
#define CLIENT_CAPABILITIES (CLIENT_LONG_PASSWORD | CLIENT_LONG_FLAG \ #define CLIENT_CAPABILITIES (CLIENT_LONG_PASSWORD | CLIENT_LONG_FLAG \
| CLIENT_LOCAL_FILES | CLIENT_TRANSACTIONS \ | CLIENT_LOCAL_FILES | CLIENT_TRANSACTIONS \
@@ -324,6 +325,7 @@ HANDLE create_named_pipe(NET *net, uint connect_timeout, char **arg_host,
if (GetLastError() != ERROR_PIPE_BUSY) if (GetLastError() != ERROR_PIPE_BUSY)
{ {
net->last_errno=CR_NAMEDPIPEOPEN_ERROR; net->last_errno=CR_NAMEDPIPEOPEN_ERROR;
strmov(net->sqlstate, unknown_sqlstate);
sprintf(net->last_error,ER(net->last_errno),host, unix_socket, sprintf(net->last_error,ER(net->last_errno),host, unix_socket,
(ulong) GetLastError()); (ulong) GetLastError());
return INVALID_HANDLE_VALUE; return INVALID_HANDLE_VALUE;
@@ -332,6 +334,7 @@ HANDLE create_named_pipe(NET *net, uint connect_timeout, char **arg_host,
if (! WaitNamedPipe(szPipeName, connect_timeout*1000) ) if (! WaitNamedPipe(szPipeName, connect_timeout*1000) )
{ {
net->last_errno=CR_NAMEDPIPEWAIT_ERROR; net->last_errno=CR_NAMEDPIPEWAIT_ERROR;
strmov(net->sqlstate, unknown_sqlstate);
sprintf(net->last_error,ER(net->last_errno),host, unix_socket, sprintf(net->last_error,ER(net->last_errno),host, unix_socket,
(ulong) GetLastError()); (ulong) GetLastError());
return INVALID_HANDLE_VALUE; return INVALID_HANDLE_VALUE;
@@ -340,6 +343,7 @@ HANDLE create_named_pipe(NET *net, uint connect_timeout, char **arg_host,
if (hPipe == INVALID_HANDLE_VALUE) if (hPipe == INVALID_HANDLE_VALUE)
{ {
net->last_errno=CR_NAMEDPIPEOPEN_ERROR; net->last_errno=CR_NAMEDPIPEOPEN_ERROR;
strmov(net->sqlstate, unknown_sqlstate);
sprintf(net->last_error,ER(net->last_errno),host, unix_socket, sprintf(net->last_error,ER(net->last_errno),host, unix_socket,
(ulong) GetLastError()); (ulong) GetLastError());
return INVALID_HANDLE_VALUE; return INVALID_HANDLE_VALUE;
@@ -349,6 +353,7 @@ HANDLE create_named_pipe(NET *net, uint connect_timeout, char **arg_host,
{ {
CloseHandle( hPipe ); CloseHandle( hPipe );
net->last_errno=CR_NAMEDPIPESETSTATE_ERROR; net->last_errno=CR_NAMEDPIPESETSTATE_ERROR;
strmov(net->sqlstate, unknown_sqlstate);
sprintf(net->last_error,ER(net->last_errno),host, unix_socket, sprintf(net->last_error,ER(net->last_errno),host, unix_socket,
(ulong) GetLastError()); (ulong) GetLastError());
return INVALID_HANDLE_VALUE; return INVALID_HANDLE_VALUE;
@@ -552,6 +557,7 @@ err:
if (error_allow) if (error_allow)
{ {
net->last_errno=error_allow; net->last_errno=error_allow;
strmov(net->sqlstate, unknown_sqlstate);
if (error_allow == CR_SHARED_MEMORY_EVENT_ERROR) if (error_allow == CR_SHARED_MEMORY_EVENT_ERROR)
sprintf(net->last_error,ER(net->last_errno),suffix_pos,error_code); sprintf(net->last_error,ER(net->last_errno),suffix_pos,error_code);
else else
@@ -590,6 +596,7 @@ net_safe_read(MYSQL *mysql)
CR_NET_PACKET_TOO_LARGE: CR_NET_PACKET_TOO_LARGE:
CR_SERVER_LOST); CR_SERVER_LOST);
strmov(net->last_error,ER(net->last_errno)); strmov(net->last_error,ER(net->last_errno));
strmov(net->sqlstate, unknown_sqlstate);
return (packet_error); return (packet_error);
} }
if (net->read_pos[0] == 255) if (net->read_pos[0] == 255)
@@ -600,16 +607,22 @@ net_safe_read(MYSQL *mysql)
net->last_errno=uint2korr(pos); net->last_errno=uint2korr(pos);
pos+=2; pos+=2;
len-=2; len-=2;
if (protocol_41(mysql) && pos[0] == '#')
{
strmake(net->sqlstate, pos+1, SQLSTATE_LENGTH);
pos+= SQLSTATE_LENGTH+1;
}
(void) strmake(net->last_error,(char*) pos, (void) strmake(net->last_error,(char*) pos,
min((uint) len,(uint) sizeof(net->last_error)-1)); min((uint) len,(uint) sizeof(net->last_error)-1));
} }
else else
{ {
net->last_errno=CR_UNKNOWN_ERROR; net->last_errno=CR_UNKNOWN_ERROR;
(void) strmov(net->last_error,ER(net->last_errno)); strmov(net->sqlstate, unknown_sqlstate);
strmov(net->last_error, ER(net->last_errno));
} }
DBUG_PRINT("error",("Got error: %d (%s)", net->last_errno, DBUG_PRINT("error",("Got error: %d/%s (%s)",
net->last_error)); net->last_errno, net->sqlstate, net->last_error));
return(packet_error); return(packet_error);
} }
return len; return len;
@@ -645,11 +658,13 @@ advanced_command(MYSQL *mysql, enum enum_server_command command,
if (mysql->status != MYSQL_STATUS_READY) if (mysql->status != MYSQL_STATUS_READY)
{ {
strmov(net->last_error,ER(mysql->net.last_errno=CR_COMMANDS_OUT_OF_SYNC)); strmov(net->last_error,ER(mysql->net.last_errno=CR_COMMANDS_OUT_OF_SYNC));
strmov(net->sqlstate, unknown_sqlstate);
return 1; return 1;
} }
mysql->net.last_error[0]=0; net->last_error[0]=0;
mysql->net.last_errno=0; net->last_errno=0;
strmov(net->sqlstate, unknown_sqlstate);
mysql->info=0; mysql->info=0;
mysql->affected_rows= ~(my_ulonglong) 0; mysql->affected_rows= ~(my_ulonglong) 0;
net_clear(&mysql->net); /* Clear receive buffer */ net_clear(&mysql->net); /* Clear receive buffer */
@@ -911,8 +926,8 @@ static const char *default_options[]=
"character-sets-dir", "default-character-set", "interactive-timeout", "character-sets-dir", "default-character-set", "interactive-timeout",
"connect-timeout", "local-infile", "disable-local-infile", "connect-timeout", "local-infile", "disable-local-infile",
"replication-probe", "enable-reads-from-master", "repl-parse-query", "replication-probe", "enable-reads-from-master", "repl-parse-query",
"ssl-cipher", "max-allowed-packet", "ssl-cipher", "max-allowed-packet", "protocol", "shared-memory-base-name",
"protocol", "shared-memory-base-name", "multi-results", "multi-queries",
NullS NullS
}; };
@@ -1101,6 +1116,12 @@ static void mysql_read_default_options(struct st_mysql_options *options,
options->shared_memory_base_name=my_strdup(opt_arg,MYF(MY_WME)); options->shared_memory_base_name=my_strdup(opt_arg,MYF(MY_WME));
#endif #endif
break; break;
case 30:
options->client_flag|= CLIENT_MULTI_RESULTS;
break;
case 31:
options->client_flag|= CLIENT_MULTI_QUERIES | CLIENT_MULTI_RESULTS;
break;
default: default:
DBUG_PRINT("warning",("unknown option: %s",option[0])); DBUG_PRINT("warning",("unknown option: %s",option[0]));
} }
@@ -1122,7 +1143,7 @@ unpack_fields(MYSQL_DATA *data,MEM_ROOT *alloc,uint fields,
{ {
MYSQL_ROWS *row; MYSQL_ROWS *row;
MYSQL_FIELD *field,*result; MYSQL_FIELD *field,*result;
ulong lengths[8]; /* Max of fields */ ulong lengths[9]; /* Max of fields */
DBUG_ENTER("unpack_fields"); DBUG_ENTER("unpack_fields");
field=result=(MYSQL_FIELD*) alloc_root(alloc, field=result=(MYSQL_FIELD*) alloc_root(alloc,
@@ -1139,33 +1160,35 @@ unpack_fields(MYSQL_DATA *data,MEM_ROOT *alloc,uint fields,
for (row=data->data; row ; row = row->next,field++) for (row=data->data; row ; row = row->next,field++)
{ {
uchar *pos; uchar *pos;
fetch_lengths(&lengths[0], row->data, default_value ? 7 : 6); fetch_lengths(&lengths[0], row->data, default_value ? 8 : 7);
field->db = strdup_root(alloc,(char*) row->data[0]); field->catalog = strdup_root(alloc,(char*) row->data[0]);
field->table = strdup_root(alloc,(char*) row->data[1]); field->db = strdup_root(alloc,(char*) row->data[1]);
field->org_table= strdup_root(alloc,(char*) row->data[2]); field->table = strdup_root(alloc,(char*) row->data[2]);
field->name = strdup_root(alloc,(char*) row->data[3]); field->org_table= strdup_root(alloc,(char*) row->data[3]);
field->org_name = strdup_root(alloc,(char*) row->data[4]); field->name = strdup_root(alloc,(char*) row->data[4]);
field->org_name = strdup_root(alloc,(char*) row->data[5]);
field->db_length= lengths[0]; field->catalog_length= lengths[0];
field->table_length= lengths[1]; field->db_length= lengths[1];
field->org_table_length= lengths[2]; field->table_length= lengths[2];
field->name_length= lengths[3]; field->org_table_length= lengths[3];
field->org_name_length= lengths[4]; field->name_length= lengths[4];
field->org_name_length= lengths[5];
/* Unpack fixed length parts */ /* Unpack fixed length parts */
pos= (uchar*) row->data[5]; pos= (uchar*) row->data[6];
field->charsetnr= uint2korr(pos); field->charsetnr= uint2korr(pos);
field->length= (uint) uint3korr(pos+2); field->length= (uint) uint4korr(pos+2);
field->type= (enum enum_field_types) pos[5]; field->type= (enum enum_field_types) pos[6];
field->flags= uint2korr(pos+6); field->flags= uint2korr(pos+7);
field->decimals= (uint) pos[8]; field->decimals= (uint) pos[9];
if (INTERNAL_NUM_FIELD(field)) if (INTERNAL_NUM_FIELD(field))
field->flags|= NUM_FLAG; field->flags|= NUM_FLAG;
if (default_value && row->data[6]) if (default_value && row->data[7])
{ {
field->def=strdup_root(alloc,(char*) row->data[6]); field->def=strdup_root(alloc,(char*) row->data[7]);
field->def_length= lengths[6]; field->def_length= lengths[7];
} }
else else
field->def=0; field->def=0;
@@ -1236,6 +1259,7 @@ static MYSQL_DATA *read_rows(MYSQL *mysql,MYSQL_FIELD *mysql_fields,
MYF(MY_WME | MY_ZEROFILL)))) MYF(MY_WME | MY_ZEROFILL))))
{ {
net->last_errno=CR_OUT_OF_MEMORY; net->last_errno=CR_OUT_OF_MEMORY;
strmov(net->sqlstate, unknown_sqlstate);
strmov(net->last_error,ER(net->last_errno)); strmov(net->last_error,ER(net->last_errno));
DBUG_RETURN(0); DBUG_RETURN(0);
} }
@@ -1264,6 +1288,7 @@ static MYSQL_DATA *read_rows(MYSQL *mysql,MYSQL_FIELD *mysql_fields,
{ {
free_rows(result); free_rows(result);
net->last_errno=CR_OUT_OF_MEMORY; net->last_errno=CR_OUT_OF_MEMORY;
strmov(net->sqlstate, unknown_sqlstate);
strmov(net->last_error,ER(net->last_errno)); strmov(net->last_error,ER(net->last_errno));
DBUG_RETURN(0); DBUG_RETURN(0);
} }
@@ -1284,6 +1309,7 @@ static MYSQL_DATA *read_rows(MYSQL *mysql,MYSQL_FIELD *mysql_fields,
{ {
free_rows(result); free_rows(result);
net->last_errno=CR_MALFORMED_PACKET; net->last_errno=CR_MALFORMED_PACKET;
strmov(net->sqlstate, unknown_sqlstate);
strmov(net->last_error,ER(net->last_errno)); strmov(net->last_error,ER(net->last_errno));
DBUG_RETURN(0); DBUG_RETURN(0);
} }
@@ -1328,17 +1354,18 @@ read_one_row(MYSQL *mysql,uint fields,MYSQL_ROW row, ulong *lengths)
ulong pkt_len,len; ulong pkt_len,len;
uchar *pos, *end_pos; uchar *pos, *end_pos;
uchar *prev_pos; uchar *prev_pos;
NET *net= &mysql->net;
if ((pkt_len=net_safe_read(mysql)) == packet_error) if ((pkt_len=net_safe_read(mysql)) == packet_error)
return -1; return -1;
if (pkt_len <= 8 && mysql->net.read_pos[0] == 254) if (pkt_len <= 8 && net->read_pos[0] == 254)
{ {
if (pkt_len > 1) /* MySQL 4.1 protocol */ if (pkt_len > 1) /* MySQL 4.1 protocol */
mysql->warning_count= uint2korr(mysql->net.read_pos+1); mysql->warning_count= uint2korr(net->read_pos+1);
return 1; /* End of data */ return 1; /* End of data */
} }
prev_pos= 0; /* allowed to write at packet[-1] */ prev_pos= 0; /* allowed to write at packet[-1] */
pos=mysql->net.read_pos; pos=net->read_pos;
end_pos=pos+pkt_len; end_pos=pos+pkt_len;
for (field=0 ; field < fields ; field++) for (field=0 ; field < fields ; field++)
{ {
@@ -1351,8 +1378,9 @@ read_one_row(MYSQL *mysql,uint fields,MYSQL_ROW row, ulong *lengths)
{ {
if (len > (ulong) (end_pos - pos)) if (len > (ulong) (end_pos - pos))
{ {
mysql->net.last_errno=CR_UNKNOWN_ERROR; net->last_errno=CR_UNKNOWN_ERROR;
strmov(mysql->net.last_error,ER(mysql->net.last_errno)); strmov(net->last_error,ER(net->last_errno));
strmov(net->sqlstate, unknown_sqlstate);
return -1; return -1;
} }
row[field] = (char*) pos; row[field] = (char*) pos;
@@ -1871,6 +1899,7 @@ static my_bool mysql_autenticate(MYSQL *mysql, const char *passwd)
if (my_net_write(net,buff,SCRAMBLE41_LENGTH) || net_flush(net)) if (my_net_write(net,buff,SCRAMBLE41_LENGTH) || net_flush(net))
{ {
net->last_errno= CR_SERVER_LOST; net->last_errno= CR_SERVER_LOST;
strmov(net->sqlstate, unknown_sqlstate);
strmov(net->last_error,ER(net->last_errno)); strmov(net->last_error,ER(net->last_errno));
goto error; goto error;
} }
@@ -1945,6 +1974,7 @@ mysql_real_connect(MYSQL *mysql,const char *host, const char *user,
/* Don't give sigpipe errors if the client doesn't want them */ /* Don't give sigpipe errors if the client doesn't want them */
set_sigpipe(mysql); set_sigpipe(mysql);
net->vio = 0; /* If something goes wrong */ net->vio = 0; /* If something goes wrong */
mysql->client_flag=0; /* For handshake */
/* use default options */ /* use default options */
if (mysql->options.my_cnf_file || mysql->options.my_cnf_group) if (mysql->options.my_cnf_file || mysql->options.my_cnf_group)
{ {
@@ -2025,6 +2055,7 @@ mysql_real_connect(MYSQL *mysql,const char *host, const char *user,
if ((sock = socket(AF_UNIX,SOCK_STREAM,0)) == SOCKET_ERROR) if ((sock = socket(AF_UNIX,SOCK_STREAM,0)) == SOCKET_ERROR)
{ {
net->last_errno=CR_SOCKET_CREATE_ERROR; net->last_errno=CR_SOCKET_CREATE_ERROR;
strmov(net->sqlstate, unknown_sqlstate);
sprintf(net->last_error,ER(net->last_errno),socket_errno); sprintf(net->last_error,ER(net->last_errno),socket_errno);
goto error; goto error;
} }
@@ -2038,6 +2069,7 @@ mysql_real_connect(MYSQL *mysql,const char *host, const char *user,
DBUG_PRINT("error",("Got error %d on connect to local server", DBUG_PRINT("error",("Got error %d on connect to local server",
socket_errno)); socket_errno));
net->last_errno=CR_CONNECTION_ERROR; net->last_errno=CR_CONNECTION_ERROR;
strmov(net->sqlstate, unknown_sqlstate);
sprintf(net->last_error,ER(net->last_errno),unix_socket,socket_errno); sprintf(net->last_error,ER(net->last_errno),unix_socket,socket_errno);
goto error; goto error;
} }
@@ -2092,6 +2124,7 @@ mysql_real_connect(MYSQL *mysql,const char *host, const char *user,
if ((sock = (my_socket) socket(AF_INET,SOCK_STREAM,0)) == SOCKET_ERROR) if ((sock = (my_socket) socket(AF_INET,SOCK_STREAM,0)) == SOCKET_ERROR)
{ {
net->last_errno=CR_IPSOCK_ERROR; net->last_errno=CR_IPSOCK_ERROR;
strmov(net->sqlstate, unknown_sqlstate);
sprintf(net->last_error,ER(net->last_errno),socket_errno); sprintf(net->last_error,ER(net->last_errno),socket_errno);
goto error; goto error;
} }
@@ -2118,6 +2151,7 @@ mysql_real_connect(MYSQL *mysql,const char *host, const char *user,
{ {
my_gethostbyname_r_free(); my_gethostbyname_r_free();
net->last_errno=CR_UNKNOWN_HOST; net->last_errno=CR_UNKNOWN_HOST;
strmov(net->sqlstate, unknown_sqlstate);
sprintf(net->last_error, ER(CR_UNKNOWN_HOST), host, tmp_errno); sprintf(net->last_error, ER(CR_UNKNOWN_HOST), host, tmp_errno);
goto error; goto error;
} }
@@ -2131,6 +2165,7 @@ mysql_real_connect(MYSQL *mysql,const char *host, const char *user,
DBUG_PRINT("error",("Got error %d on connect to '%s'",socket_errno, DBUG_PRINT("error",("Got error %d on connect to '%s'",socket_errno,
host)); host));
net->last_errno= CR_CONN_HOST_ERROR; net->last_errno= CR_CONN_HOST_ERROR;
strmov(net->sqlstate, unknown_sqlstate);
sprintf(net->last_error ,ER(CR_CONN_HOST_ERROR), host, socket_errno); sprintf(net->last_error ,ER(CR_CONN_HOST_ERROR), host, socket_errno);
goto error; goto error;
} }
@@ -2139,6 +2174,7 @@ mysql_real_connect(MYSQL *mysql,const char *host, const char *user,
{ {
DBUG_PRINT("error",("Unknow protocol %d ",mysql->options.protocol)); DBUG_PRINT("error",("Unknow protocol %d ",mysql->options.protocol));
net->last_errno= CR_CONN_UNKNOW_PROTOCOL; net->last_errno= CR_CONN_UNKNOW_PROTOCOL;
strmov(net->sqlstate, unknown_sqlstate);
sprintf(net->last_error ,ER(CR_CONN_UNKNOW_PROTOCOL)); sprintf(net->last_error ,ER(CR_CONN_UNKNOW_PROTOCOL));
goto error; goto error;
} }
@@ -2148,6 +2184,7 @@ mysql_real_connect(MYSQL *mysql,const char *host, const char *user,
vio_delete(net->vio); vio_delete(net->vio);
net->vio = 0; net->vio = 0;
net->last_errno=CR_OUT_OF_MEMORY; net->last_errno=CR_OUT_OF_MEMORY;
strmov(net->sqlstate, unknown_sqlstate);
strmov(net->last_error,ER(net->last_errno)); strmov(net->last_error,ER(net->last_errno));
goto error; goto error;
} }
@@ -2159,6 +2196,7 @@ mysql_real_connect(MYSQL *mysql,const char *host, const char *user,
vio_poll_read(net->vio, mysql->options.connect_timeout)) vio_poll_read(net->vio, mysql->options.connect_timeout))
{ {
net->last_errno= CR_SERVER_LOST; net->last_errno= CR_SERVER_LOST;
strmov(net->sqlstate, unknown_sqlstate);
strmov(net->last_error,ER(net->last_errno)); strmov(net->last_error,ER(net->last_errno));
goto error; goto error;
} }
@@ -2174,6 +2212,7 @@ mysql_real_connect(MYSQL *mysql,const char *host, const char *user,
if (mysql->protocol_version != PROTOCOL_VERSION) if (mysql->protocol_version != PROTOCOL_VERSION)
{ {
net->last_errno= CR_VERSION_ERROR; net->last_errno= CR_VERSION_ERROR;
strmov(net->sqlstate, unknown_sqlstate);
sprintf(net->last_error, ER(CR_VERSION_ERROR), mysql->protocol_version, sprintf(net->last_error, ER(CR_VERSION_ERROR), mysql->protocol_version,
PROTOCOL_VERSION); PROTOCOL_VERSION);
goto error; goto error;
@@ -2216,6 +2255,7 @@ mysql_real_connect(MYSQL *mysql,const char *host, const char *user,
if (!mysql->charset) if (!mysql->charset)
{ {
net->last_errno=CR_CANT_READ_CHARSET; net->last_errno=CR_CANT_READ_CHARSET;
strmov(net->sqlstate, unknown_sqlstate);
if (mysql->options.charset_dir) if (mysql->options.charset_dir)
sprintf(net->last_error,ER(net->last_errno), sprintf(net->last_error,ER(net->last_errno),
charset_name ? charset_name : "unknown", charset_name ? charset_name : "unknown",
@@ -2245,6 +2285,7 @@ mysql_real_connect(MYSQL *mysql,const char *host, const char *user,
!(mysql->user=my_strdup(user,MYF(0))) || !(mysql->user=my_strdup(user,MYF(0))) ||
!(mysql->passwd=my_strdup(passwd,MYF(0)))) !(mysql->passwd=my_strdup(passwd,MYF(0))))
{ {
strmov(net->sqlstate, unknown_sqlstate);
strmov(net->last_error, ER(net->last_errno=CR_OUT_OF_MEMORY)); strmov(net->last_error, ER(net->last_errno=CR_OUT_OF_MEMORY));
goto error; goto error;
} }
@@ -2260,6 +2301,8 @@ mysql_real_connect(MYSQL *mysql,const char *host, const char *user,
/* Send client information for access check */ /* Send client information for access check */
client_flag|=CLIENT_CAPABILITIES; client_flag|=CLIENT_CAPABILITIES;
if (client_flag & CLIENT_MULTI_QUERIES)
client_flag|= CLIENT_MULTI_RESULTS;
#ifdef HAVE_OPENSSL #ifdef HAVE_OPENSSL
if (mysql->options.ssl_key || mysql->options.ssl_cert || if (mysql->options.ssl_key || mysql->options.ssl_cert ||
@@ -2282,10 +2325,12 @@ mysql_real_connect(MYSQL *mysql,const char *host, const char *user,
if (client_flag & CLIENT_PROTOCOL_41) if (client_flag & CLIENT_PROTOCOL_41)
{ {
/* 4.1 server and 4.1 client has a 4 byte option flag */ /* 4.1 server and 4.1 client has a 32 byte option flag */
int4store(buff,client_flag); int4store(buff,client_flag);
int4store(buff+4,max_allowed_packet); int4store(buff+4,max_allowed_packet);
end= buff+8; buff[8]= mysql->charset->number;
bzero(buff+9, 32-9);
end= buff+32;
} }
else else
{ {
@@ -2305,6 +2350,7 @@ mysql_real_connect(MYSQL *mysql,const char *host, const char *user,
struct st_mysql_options *options= &mysql->options; struct st_mysql_options *options= &mysql->options;
if (my_net_write(net,buff,(uint) (end-buff)) || net_flush(net)) if (my_net_write(net,buff,(uint) (end-buff)) || net_flush(net))
{ {
strmov(net->sqlstate, unknown_sqlstate);
net->last_errno= CR_SERVER_LOST; net->last_errno= CR_SERVER_LOST;
strmov(net->last_error,ER(net->last_errno)); strmov(net->last_error,ER(net->last_errno));
goto error; goto error;
@@ -2317,6 +2363,7 @@ mysql_real_connect(MYSQL *mysql,const char *host, const char *user,
options->ssl_capath, options->ssl_capath,
options->ssl_cipher))) options->ssl_cipher)))
{ {
strmov(net->sqlstate, unknown_sqlstate);
net->last_errno= CR_SSL_CONNECTION_ERROR; net->last_errno= CR_SSL_CONNECTION_ERROR;
strmov(net->last_error,ER(net->last_errno)); strmov(net->last_error,ER(net->last_errno));
goto error; goto error;
@@ -2325,6 +2372,7 @@ mysql_real_connect(MYSQL *mysql,const char *host, const char *user,
if (sslconnect((struct st_VioSSLConnectorFd*)(mysql->connector_fd), if (sslconnect((struct st_VioSSLConnectorFd*)(mysql->connector_fd),
mysql->net.vio, (long) (mysql->options.connect_timeout))) mysql->net.vio, (long) (mysql->options.connect_timeout)))
{ {
strmov(net->sqlstate, unknown_sqlstate);
net->last_errno= CR_SSL_CONNECTION_ERROR; net->last_errno= CR_SSL_CONNECTION_ERROR;
strmov(net->last_error,ER(net->last_errno)); strmov(net->last_error,ER(net->last_errno));
goto error; goto error;
@@ -2385,6 +2433,7 @@ mysql_real_connect(MYSQL *mysql,const char *host, const char *user,
/* Write authentication package */ /* Write authentication package */
if (my_net_write(net,buff,(ulong) (end-buff)) || net_flush(net)) if (my_net_write(net,buff,(ulong) (end-buff)) || net_flush(net))
{ {
strmov(net->sqlstate, unknown_sqlstate);
net->last_errno= CR_SERVER_LOST; net->last_errno= CR_SERVER_LOST;
strmov(net->last_error,ER(net->last_errno)); strmov(net->last_error,ER(net->last_errno));
goto error; goto error;
@@ -2434,7 +2483,8 @@ mysql_real_connect(MYSQL *mysql,const char *host, const char *user,
error: error:
reset_sigpipe(mysql); reset_sigpipe(mysql);
DBUG_PRINT("error",("message: %u (%s)",net->last_errno,net->last_error)); DBUG_PRINT("error",("message: %u/%s (%s)",
net->last_errno, net->sqlstate, net->last_error));
{ {
/* Free alloced memory */ /* Free alloced memory */
my_bool free_me=mysql->free_me; my_bool free_me=mysql->free_me;
@@ -2477,6 +2527,7 @@ static my_bool mysql_reconnect(MYSQL *mysql)
{ {
/* Allow reconnect next time */ /* Allow reconnect next time */
mysql->server_status&= ~SERVER_STATUS_IN_TRANS; mysql->server_status&= ~SERVER_STATUS_IN_TRANS;
strmov(mysql->net.sqlstate, unknown_sqlstate);
mysql->net.last_errno=CR_SERVER_GONE_ERROR; mysql->net.last_errno=CR_SERVER_GONE_ERROR;
strmov(mysql->net.last_error,ER(mysql->net.last_errno)); strmov(mysql->net.last_error,ER(mysql->net.last_errno));
DBUG_RETURN(1); DBUG_RETURN(1);
@@ -2491,6 +2542,7 @@ static my_bool mysql_reconnect(MYSQL *mysql)
{ {
mysql->net.last_errno= tmp_mysql.net.last_errno; mysql->net.last_errno= tmp_mysql.net.last_errno;
strmov(mysql->net.last_error, tmp_mysql.net.last_error); strmov(mysql->net.last_error, tmp_mysql.net.last_error);
strmov(mysql->net.sqlstate, tmp_mysql.net.sqlstate);
DBUG_RETURN(1); DBUG_RETURN(1);
} }
tmp_mysql.free_me=mysql->free_me; tmp_mysql.free_me=mysql->free_me;
@@ -2864,46 +2916,52 @@ send_file_to_server(MYSQL *mysql, const char *filename)
my_bool result= 1; my_bool result= 1;
uint packet_length=MY_ALIGN(mysql->net.max_packet-16,IO_SIZE); uint packet_length=MY_ALIGN(mysql->net.max_packet-16,IO_SIZE);
char *buf, tmp_name[FN_REFLEN]; char *buf, tmp_name[FN_REFLEN];
NET *net= &mysql->net;
DBUG_ENTER("send_file_to_server"); DBUG_ENTER("send_file_to_server");
if (!(buf=my_malloc(packet_length,MYF(0)))) if (!(buf=my_malloc(packet_length,MYF(0))))
{ {
strmov(mysql->net.last_error, ER(mysql->net.last_errno=CR_OUT_OF_MEMORY)); strmov(net->sqlstate, unknown_sqlstate);
strmov(net->last_error, ER(net->last_errno=CR_OUT_OF_MEMORY));
DBUG_RETURN(1); DBUG_RETURN(1);
} }
fn_format(tmp_name,filename,"","",4); /* Convert to client format */ fn_format(tmp_name,filename,"","",4); /* Convert to client format */
if ((fd = my_open(tmp_name,O_RDONLY, MYF(0))) < 0) if ((fd = my_open(tmp_name,O_RDONLY, MYF(0))) < 0)
{ {
my_net_write(&mysql->net,"",0); /* Server needs one packet */ my_net_write(net,"",0); /* Server needs one packet */
net_flush(&mysql->net); net_flush(net);
mysql->net.last_errno=EE_FILENOTFOUND; strmov(net->sqlstate, unknown_sqlstate);
my_snprintf(mysql->net.last_error,sizeof(mysql->net.last_error)-1, net->last_errno=EE_FILENOTFOUND;
EE(mysql->net.last_errno),tmp_name, errno); my_snprintf(net->last_error,sizeof(net->last_error)-1,
EE(net->last_errno),tmp_name, errno);
goto err; goto err;
} }
while ((readcount = (int) my_read(fd,(byte*) buf,packet_length,MYF(0))) > 0) while ((readcount = (int) my_read(fd,(byte*) buf,packet_length,MYF(0))) > 0)
{ {
if (my_net_write(&mysql->net,buf,readcount)) if (my_net_write(net,buf,readcount))
{ {
DBUG_PRINT("error",("Lost connection to MySQL server during LOAD DATA of local file")); DBUG_PRINT("error",("Lost connection to MySQL server during LOAD DATA of local file"));
mysql->net.last_errno=CR_SERVER_LOST; strmov(net->sqlstate, unknown_sqlstate);
strmov(mysql->net.last_error,ER(mysql->net.last_errno)); net->last_errno=CR_SERVER_LOST;
strmov(net->last_error,ER(net->last_errno));
goto err; goto err;
} }
} }
/* Send empty packet to mark end of file */ /* Send empty packet to mark end of file */
if (my_net_write(&mysql->net,"",0) || net_flush(&mysql->net)) if (my_net_write(net,"",0) || net_flush(net))
{ {
mysql->net.last_errno=CR_SERVER_LOST; strmov(net->sqlstate, unknown_sqlstate);
sprintf(mysql->net.last_error,ER(mysql->net.last_errno),errno); net->last_errno=CR_SERVER_LOST;
sprintf(net->last_error,ER(net->last_errno),errno);
goto err; goto err;
} }
if (readcount < 0) if (readcount < 0)
{ {
mysql->net.last_errno=EE_READ; /* the errmsg for not entire file read */ strmov(net->sqlstate, unknown_sqlstate);
my_snprintf(mysql->net.last_error,sizeof(mysql->net.last_error)-1, net->last_errno=EE_READ; /* the errmsg for not entire file read */
my_snprintf(net->last_error,sizeof(net->last_error)-1,
tmp_name,errno); tmp_name,errno);
goto err; goto err;
} }
@@ -2935,6 +2993,7 @@ mysql_store_result(MYSQL *mysql)
DBUG_RETURN(0); DBUG_RETURN(0);
if (mysql->status != MYSQL_STATUS_GET_RESULT) if (mysql->status != MYSQL_STATUS_GET_RESULT)
{ {
strmov(mysql->net.sqlstate, unknown_sqlstate);
strmov(mysql->net.last_error, strmov(mysql->net.last_error,
ER(mysql->net.last_errno=CR_COMMANDS_OUT_OF_SYNC)); ER(mysql->net.last_errno=CR_COMMANDS_OUT_OF_SYNC));
DBUG_RETURN(0); DBUG_RETURN(0);
@@ -2945,6 +3004,7 @@ mysql_store_result(MYSQL *mysql)
mysql->field_count), mysql->field_count),
MYF(MY_WME | MY_ZEROFILL)))) MYF(MY_WME | MY_ZEROFILL))))
{ {
strmov(mysql->net.sqlstate, unknown_sqlstate);
mysql->net.last_errno=CR_OUT_OF_MEMORY; mysql->net.last_errno=CR_OUT_OF_MEMORY;
strmov(mysql->net.last_error, ER(mysql->net.last_errno)); strmov(mysql->net.last_error, ER(mysql->net.last_errno));
DBUG_RETURN(0); DBUG_RETURN(0);
@@ -2990,6 +3050,7 @@ mysql_use_result(MYSQL *mysql)
DBUG_RETURN(0); DBUG_RETURN(0);
if (mysql->status != MYSQL_STATUS_GET_RESULT) if (mysql->status != MYSQL_STATUS_GET_RESULT)
{ {
strmov(mysql->net.sqlstate, unknown_sqlstate);
strmov(mysql->net.last_error, strmov(mysql->net.last_error,
ER(mysql->net.last_errno=CR_COMMANDS_OUT_OF_SYNC)); ER(mysql->net.last_errno=CR_COMMANDS_OUT_OF_SYNC));
DBUG_RETURN(0); DBUG_RETURN(0);
@@ -3319,6 +3380,7 @@ mysql_stat(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 */
if (!mysql->net.read_pos[0]) if (!mysql->net.read_pos[0])
{ {
strmov(mysql->net.sqlstate, unknown_sqlstate);
mysql->net.last_errno=CR_WRONG_HOST_INFO; mysql->net.last_errno=CR_WRONG_HOST_INFO;
strmov(mysql->net.last_error, ER(mysql->net.last_errno)); strmov(mysql->net.last_error, ER(mysql->net.last_errno));
return mysql->net.last_error; return mysql->net.last_error;
@@ -3511,6 +3573,11 @@ uint STDCALL mysql_errno(MYSQL *mysql)
return mysql->net.last_errno; return mysql->net.last_errno;
} }
const char *STDCALL mysql_sqlstate(MYSQL *mysql)
{
return mysql->net.sqlstate;
}
const char * STDCALL mysql_error(MYSQL *mysql) const char * STDCALL mysql_error(MYSQL *mysql)
{ {
return mysql->net.last_error; return mysql->net.last_error;
@@ -3761,7 +3828,8 @@ myodbc_remove_escape(MYSQL *mysql,char *name)
Set the internal stmt error messages Set the internal stmt error messages
*/ */
static void set_stmt_error(MYSQL_STMT * stmt, int errcode) static void set_stmt_error(MYSQL_STMT * stmt, int errcode,
const char *sqlstate)
{ {
DBUG_ENTER("set_stmt_error"); DBUG_ENTER("set_stmt_error");
DBUG_PRINT("enter", ("error: %d '%s'", errcode, ER(errcode))); DBUG_PRINT("enter", ("error: %d '%s'", errcode, ER(errcode)));
@@ -3769,6 +3837,7 @@ static void set_stmt_error(MYSQL_STMT * stmt, int errcode)
stmt->last_errno= errcode; stmt->last_errno= errcode;
strmov(stmt->last_error, ER(errcode)); strmov(stmt->last_error, ER(errcode));
strmov(stmt->sqlstate, sqlstate);
DBUG_VOID_RETURN; DBUG_VOID_RETURN;
} }
@@ -3778,15 +3847,17 @@ static void set_stmt_error(MYSQL_STMT * stmt, int errcode)
Copy error message to statement handler Copy error message to statement handler
*/ */
static void set_stmt_errmsg(MYSQL_STMT * stmt, char *err, int errcode) static void set_stmt_errmsg(MYSQL_STMT * stmt, const char *err, int errcode,
const char *sqlstate)
{ {
DBUG_ENTER("set_stmt_error_msg"); DBUG_ENTER("set_stmt_error_msg");
DBUG_PRINT("enter", ("error: %d '%s'", errcode, err)); DBUG_PRINT("enter", ("error: %d/%s '%s'", errcode, sqlstate, err));
DBUG_ASSERT(stmt != 0); DBUG_ASSERT(stmt != 0);
stmt->last_errno= errcode; stmt->last_errno= errcode;
if (err && err[0]) if (err && err[0])
strmov(stmt->last_error, err); strmov(stmt->last_error, err);
strmov(stmt->sqlstate, sqlstate);
DBUG_VOID_RETURN; DBUG_VOID_RETURN;
} }
@@ -3796,7 +3867,7 @@ static void set_stmt_errmsg(MYSQL_STMT * stmt, char *err, int errcode)
Set the internal error message to mysql handler Set the internal error message to mysql handler
*/ */
static void set_mysql_error(MYSQL * mysql, int errcode) static void set_mysql_error(MYSQL * mysql, int errcode, const char *sqlstate)
{ {
DBUG_ENTER("set_mysql_error"); DBUG_ENTER("set_mysql_error");
DBUG_PRINT("enter", ("error :%d '%s'", errcode, ER(errcode))); DBUG_PRINT("enter", ("error :%d '%s'", errcode, ER(errcode)));
@@ -3804,6 +3875,7 @@ static void set_mysql_error(MYSQL * mysql, int errcode)
mysql->net.last_errno= errcode; mysql->net.last_errno= errcode;
strmov(mysql->net.last_error, ER(errcode)); strmov(mysql->net.last_error, ER(errcode));
strmov(mysql->net.sqlstate, sqlstate);
} }
@@ -3873,7 +3945,7 @@ static my_bool read_prepare_result(MYSQL *mysql, MYSQL_STMT *stmt)
mysql->server_status|= SERVER_STATUS_IN_TRANS; mysql->server_status|= SERVER_STATUS_IN_TRANS;
mysql->extra_info= net_field_length_ll(&pos); mysql->extra_info= net_field_length_ll(&pos);
if (!(fields_data= read_rows(mysql, (MYSQL_FIELD*) 0, 8))) if (!(fields_data= read_rows(mysql, (MYSQL_FIELD*) 0, 9)))
DBUG_RETURN(1); DBUG_RETURN(1);
if (!(stmt->fields= unpack_fields(fields_data,&stmt->mem_root, if (!(stmt->fields= unpack_fields(fields_data,&stmt->mem_root,
field_count,0, field_count,0,
@@ -3885,7 +3957,7 @@ static my_bool read_prepare_result(MYSQL *mysql, MYSQL_STMT *stmt)
(param_count + (param_count +
field_count)))) field_count))))
{ {
set_stmt_error(stmt, CR_OUT_OF_MEMORY); set_stmt_error(stmt, CR_OUT_OF_MEMORY, unknown_sqlstate);
DBUG_RETURN(0); DBUG_RETURN(0);
} }
stmt->bind= (stmt->params + param_count); stmt->bind= (stmt->params + param_count);
@@ -3915,7 +3987,7 @@ mysql_prepare(MYSQL *mysql, const char *query, ulong length)
#ifdef CHECK_EXTRA_ARGUMENTS #ifdef CHECK_EXTRA_ARGUMENTS
if (!query) if (!query)
{ {
set_mysql_error(mysql, CR_NULL_POINTER); set_mysql_error(mysql, CR_NULL_POINTER, unknown_sqlstate);
DBUG_RETURN(0); DBUG_RETURN(0);
} }
#endif #endif
@@ -3925,7 +3997,7 @@ mysql_prepare(MYSQL *mysql, const char *query, ulong length)
!(stmt->query= my_strdup_with_length((byte *) query, length, MYF(0)))) !(stmt->query= my_strdup_with_length((byte *) query, length, MYF(0))))
{ {
my_free((gptr) stmt, MYF(MY_ALLOW_ZERO_PTR)); my_free((gptr) stmt, MYF(MY_ALLOW_ZERO_PTR));
set_mysql_error(mysql, CR_OUT_OF_MEMORY); set_mysql_error(mysql, CR_OUT_OF_MEMORY, unknown_sqlstate);
DBUG_RETURN(0); DBUG_RETURN(0);
} }
if (simple_command(mysql, COM_PREPARE, query, length, 1)) if (simple_command(mysql, COM_PREPARE, query, length, 1))
@@ -4266,7 +4338,7 @@ static my_bool store_param(MYSQL_STMT *stmt, MYSQL_BIND *param)
*/ */
if ((my_realloc_str(net, 9 + *param->length))) if ((my_realloc_str(net, 9 + *param->length)))
{ {
set_stmt_error(stmt, CR_OUT_OF_MEMORY); set_stmt_error(stmt, CR_OUT_OF_MEMORY, unknown_sqlstate);
DBUG_RETURN(1); DBUG_RETURN(1);
} }
(*param->store_param_func)(net, param); (*param->store_param_func)(net, param);
@@ -4293,7 +4365,7 @@ static my_bool execute(MYSQL_STMT * stmt, char *packet, ulong length)
length, 1) || length, 1) ||
mysql_read_query_result(mysql)) mysql_read_query_result(mysql))
{ {
set_stmt_errmsg(stmt, net->last_error, net->last_errno); set_stmt_errmsg(stmt, net->last_error, net->last_errno, net->sqlstate);
DBUG_RETURN(1); DBUG_RETURN(1);
} }
stmt->state= MY_ST_EXECUTE; stmt->state= MY_ST_EXECUTE;
@@ -4315,7 +4387,7 @@ int STDCALL mysql_execute(MYSQL_STMT *stmt)
if (stmt->state == MY_ST_UNKNOWN) if (stmt->state == MY_ST_UNKNOWN)
{ {
set_stmt_error(stmt, CR_NO_PREPARE_STMT); set_stmt_error(stmt, CR_NO_PREPARE_STMT, unknown_sqlstate);
DBUG_RETURN(1); DBUG_RETURN(1);
} }
if (stmt->param_count) if (stmt->param_count)
@@ -4331,7 +4403,7 @@ int STDCALL mysql_execute(MYSQL_STMT *stmt)
if (!stmt->param_buffers) if (!stmt->param_buffers)
{ {
/* Parameters exists, but no bound buffers */ /* Parameters exists, but no bound buffers */
set_stmt_error(stmt, CR_NOT_ALL_PARAMS_BOUND); set_stmt_error(stmt, CR_NOT_ALL_PARAMS_BOUND, unknown_sqlstate);
DBUG_RETURN(1); DBUG_RETURN(1);
} }
#endif #endif
@@ -4366,7 +4438,7 @@ int STDCALL mysql_execute(MYSQL_STMT *stmt)
/* TODO: Look into avoding the following memdup */ /* TODO: Look into avoding the following memdup */
if (!(param_data= my_memdup((const char*) net->buff, length, MYF(0)))) if (!(param_data= my_memdup((const char*) net->buff, length, MYF(0))))
{ {
set_stmt_error(stmt, CR_OUT_OF_MEMORY); 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() */ net->write_pos= net->buff; /* Reset for net_write() */
@@ -4417,12 +4489,12 @@ my_bool STDCALL mysql_bind_param(MYSQL_STMT *stmt, MYSQL_BIND * bind)
#ifdef CHECK_EXTRA_ARGUMENTS #ifdef CHECK_EXTRA_ARGUMENTS
if (stmt->state == MY_ST_UNKNOWN) if (stmt->state == MY_ST_UNKNOWN)
{ {
set_stmt_error(stmt, CR_NO_PREPARE_STMT); set_stmt_error(stmt, CR_NO_PREPARE_STMT, unknown_sqlstate);
DBUG_RETURN(1); DBUG_RETURN(1);
} }
if (!stmt->param_count) if (!stmt->param_count)
{ {
set_stmt_error(stmt, CR_NO_PARAMETERS_EXISTS); set_stmt_error(stmt, CR_NO_PARAMETERS_EXISTS, unknown_sqlstate);
DBUG_RETURN(1); DBUG_RETURN(1);
} }
#endif #endif
@@ -4505,6 +4577,7 @@ my_bool STDCALL mysql_bind_param(MYSQL_STMT *stmt, MYSQL_BIND * bind)
param->store_param_func= store_param_str; param->store_param_func= store_param_str;
break; break;
default: default:
strmov(stmt->sqlstate, unknown_sqlstate);
sprintf(stmt->last_error, sprintf(stmt->last_error,
ER(stmt->last_errno= CR_UNSUPPORTED_PARAM_TYPE), ER(stmt->last_errno= CR_UNSUPPORTED_PARAM_TYPE),
param->buffer_type, count); param->buffer_type, count);
@@ -4550,7 +4623,7 @@ mysql_send_long_data(MYSQL_STMT *stmt, uint param_number,
if (param_number >= stmt->param_count) if (param_number >= stmt->param_count)
{ {
set_stmt_error(stmt, CR_INVALID_PARAMETER_NO); set_stmt_error(stmt, CR_INVALID_PARAMETER_NO, unknown_sqlstate);
DBUG_RETURN(1); DBUG_RETURN(1);
} }
param= stmt->params+param_number; param= stmt->params+param_number;
@@ -4561,6 +4634,7 @@ mysql_send_long_data(MYSQL_STMT *stmt, uint param_number,
Long data handling should be used only for string/binary Long data handling should be used only for string/binary
types only types only
*/ */
strmov(stmt->sqlstate, unknown_sqlstate);
sprintf(stmt->last_error, ER(stmt->last_errno= CR_INVALID_BUFFER_USE), sprintf(stmt->last_error, ER(stmt->last_errno= CR_INVALID_BUFFER_USE),
param->param_number); param->param_number);
DBUG_RETURN(1); DBUG_RETURN(1);
@@ -4583,8 +4657,8 @@ mysql_send_long_data(MYSQL_STMT *stmt, uint param_number,
if (advanced_command(mysql, COM_LONG_DATA, extra_data, if (advanced_command(mysql, COM_LONG_DATA, extra_data,
MYSQL_LONG_DATA_HEADER, data, length, 1)) MYSQL_LONG_DATA_HEADER, data, length, 1))
{ {
set_stmt_errmsg(stmt,(char *) mysql->net.last_error, set_stmt_errmsg(stmt, mysql->net.last_error,
mysql->net.last_errno); mysql->net.last_errno, mysql->net.sqlstate);
DBUG_RETURN(1); DBUG_RETURN(1);
} }
} }
@@ -5123,12 +5197,12 @@ my_bool STDCALL mysql_bind_result(MYSQL_STMT *stmt, MYSQL_BIND *bind)
#ifdef CHECK_EXTRA_ARGUMENTS #ifdef CHECK_EXTRA_ARGUMENTS
if (stmt->state == MY_ST_UNKNOWN) if (stmt->state == MY_ST_UNKNOWN)
{ {
set_stmt_error(stmt, CR_NO_PREPARE_STMT); set_stmt_error(stmt, CR_NO_PREPARE_STMT, unknown_sqlstate);
DBUG_RETURN(1); DBUG_RETURN(1);
} }
if (!bind) if (!bind)
{ {
set_stmt_error(stmt, CR_NULL_POINTER); set_stmt_error(stmt, CR_NULL_POINTER, unknown_sqlstate);
DBUG_RETURN(1); DBUG_RETURN(1);
} }
#endif #endif
@@ -5208,6 +5282,7 @@ my_bool STDCALL mysql_bind_result(MYSQL_STMT *stmt, MYSQL_BIND *bind)
param->fetch_result= fetch_result_str; param->fetch_result= fetch_result_str;
break; break;
default: default:
strmov(stmt->sqlstate, unknown_sqlstate);
sprintf(stmt->last_error, sprintf(stmt->last_error,
ER(stmt->last_errno= CR_UNSUPPORTED_PARAM_TYPE), ER(stmt->last_errno= CR_UNSUPPORTED_PARAM_TYPE),
param->buffer_type, param_count); param->buffer_type, param_count);
@@ -5296,8 +5371,8 @@ int STDCALL mysql_fetch(MYSQL_STMT *stmt)
{ {
if (packet_error == net_safe_read(mysql)) if (packet_error == net_safe_read(mysql))
{ {
set_stmt_errmsg(stmt,(char *)mysql->net.last_error, set_stmt_errmsg(stmt, mysql->net.last_error, mysql->net.last_errno,
mysql->net.last_errno); mysql->net.sqlstate);
DBUG_RETURN(1); DBUG_RETURN(1);
} }
if (mysql->net.read_pos[0] == 254) if (mysql->net.read_pos[0] == 254)
@@ -5447,8 +5522,9 @@ static MYSQL_DATA *read_binary_rows(MYSQL_STMT *stmt)
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)
{ {
set_stmt_errmsg(stmt,(char *)mysql->net.last_error, set_stmt_errmsg(stmt, mysql->net.last_error, mysql->net.last_errno,
mysql->net.last_errno); mysql->net.sqlstate);
DBUG_RETURN(0); DBUG_RETURN(0);
} }
if (mysql->net.read_pos[0] == 254) /* end of data */ if (mysql->net.read_pos[0] == 254) /* end of data */
@@ -5457,8 +5533,8 @@ static MYSQL_DATA *read_binary_rows(MYSQL_STMT *stmt)
if (!(result=(MYSQL_DATA*) my_malloc(sizeof(MYSQL_DATA), if (!(result=(MYSQL_DATA*) my_malloc(sizeof(MYSQL_DATA),
MYF(MY_WME | MY_ZEROFILL)))) MYF(MY_WME | MY_ZEROFILL))))
{ {
net->last_errno=CR_OUT_OF_MEMORY; set_stmt_errmsg(stmt, ER(CR_OUT_OF_MEMORY), CR_OUT_OF_MEMORY,
strmov(net->last_error,ER(net->last_errno)); unknown_sqlstate);
DBUG_RETURN(0); DBUG_RETURN(0);
} }
init_alloc_root(&result->alloc,8192,0); /* Assume rowlength < 8192 */ init_alloc_root(&result->alloc,8192,0); /* Assume rowlength < 8192 */
@@ -5474,8 +5550,8 @@ static MYSQL_DATA *read_binary_rows(MYSQL_STMT *stmt)
!(cur->data= ((MYSQL_ROW) alloc_root(&result->alloc, pkt_len)))) !(cur->data= ((MYSQL_ROW) alloc_root(&result->alloc, pkt_len))))
{ {
free_rows(result); free_rows(result);
net->last_errno=CR_OUT_OF_MEMORY; set_stmt_errmsg(stmt, ER(CR_OUT_OF_MEMORY), CR_OUT_OF_MEMORY,
strmov(net->last_error,ER(net->last_errno)); unknown_sqlstate);
DBUG_RETURN(0); DBUG_RETURN(0);
} }
*prev_ptr= cur; *prev_ptr= cur;
@@ -5514,7 +5590,7 @@ int STDCALL mysql_stmt_store_result(MYSQL_STMT *stmt)
DBUG_RETURN(0); DBUG_RETURN(0);
if (mysql->status != MYSQL_STATUS_GET_RESULT) if (mysql->status != MYSQL_STATUS_GET_RESULT)
{ {
set_stmt_error(stmt, CR_COMMANDS_OUT_OF_SYNC); 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 */ mysql->status= MYSQL_STATUS_READY; /* server is ready */
@@ -5523,7 +5599,7 @@ int STDCALL mysql_stmt_store_result(MYSQL_STMT *stmt)
stmt->field_count), stmt->field_count),
MYF(MY_WME | MY_ZEROFILL)))) MYF(MY_WME | MY_ZEROFILL))))
{ {
set_stmt_error(stmt, CR_OUT_OF_MEMORY); set_stmt_error(stmt, CR_OUT_OF_MEMORY, unknown_sqlstate);
DBUG_RETURN(1); DBUG_RETURN(1);
} }
stmt->result_buffered= 1; stmt->result_buffered= 1;
@@ -5663,7 +5739,8 @@ static my_bool stmt_close(MYSQL_STMT *stmt, my_bool skip_list)
int4store(buff, stmt->stmt_id); int4store(buff, stmt->stmt_id);
if (simple_command(mysql, COM_CLOSE_STMT, buff, 4, 1)) if (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);
stmt->mysql= NULL; /* connection isn't valid anymore */ stmt->mysql= NULL; /* connection isn't valid anymore */
DBUG_RETURN(1); DBUG_RETURN(1);
} }
@@ -5694,6 +5771,12 @@ uint STDCALL mysql_stmt_errno(MYSQL_STMT * stmt)
DBUG_RETURN(stmt->last_errno); DBUG_RETURN(stmt->last_errno);
} }
const char *STDCALL mysql_stmt_sqlstate(MYSQL_STMT * stmt)
{
DBUG_ENTER("mysql_stmt_sqlstate");
DBUG_RETURN(stmt->sqlstate);
}
/* /*
Return statement error message Return statement error message
*/ */
@@ -5775,6 +5858,7 @@ my_bool STDCALL mysql_next_result(MYSQL *mysql)
mysql->net.last_error[0]= 0; mysql->net.last_error[0]= 0;
mysql->net.last_errno= 0; mysql->net.last_errno= 0;
strmov(mysql->net.sqlstate, unknown_sqlstate);
mysql->affected_rows= ~(my_ulonglong) 0; mysql->affected_rows= ~(my_ulonglong) 0;
if (mysql->last_used_con->server_status & SERVER_MORE_RESULTS_EXISTS) if (mysql->last_used_con->server_status & SERVER_MORE_RESULTS_EXISTS)

View File

@@ -1,5 +1,5 @@
drop table if exists t1; drop table if exists t1;
create table t1 (c text); create table t1 (c text character set ujis);
insert into t1 values (0xa4a2),(0xa4a3); insert into t1 values (0xa4a2),(0xa4a3);
select hex(left(c,1)) from t1 group by c; select hex(left(c,1)) from t1 group by c;
hex(left(c,1)) hex(left(c,1))

View File

@@ -1,2 +1,2 @@
Collation Charset Id D C Sortlen Collation Charset Id D C Sortlen
ucs2_general_ci ucs2 35 Y 0 ucs2_general_ci ucs2 35 Y Y 1

View File

@@ -1,2 +1,2 @@
Collation Charset Id D C Sortlen Collation Charset Id D C Sortlen
ujis_japanese_ci ujis 12 Y 0 ujis_japanese_ci ujis 12 Y Y 0

View File

@@ -407,11 +407,15 @@ static my_bool init_compiled_charsets(myf flags __attribute__((unused)))
MY_ADD_CHARSET(&my_charset_big5_bin); MY_ADD_CHARSET(&my_charset_big5_bin);
#endif #endif
#ifdef HAVE_CHARSET_czech #ifdef HAVE_CHARSET_cp1250
MY_ADD_CHARSET(&my_charset_cp1250_czech_ci);
#endif
#ifdef HAVE_CHARSET_latin2
MY_ADD_CHARSET(&my_charset_latin2_czech_ci); MY_ADD_CHARSET(&my_charset_latin2_czech_ci);
#endif #endif
#ifdef HAVE_CHARSET_euc_kr #ifdef HAVE_CHARSET_euckr
MY_ADD_CHARSET(&my_charset_euckr_korean_ci); MY_ADD_CHARSET(&my_charset_euckr_korean_ci);
MY_ADD_CHARSET(&my_charset_euckr_bin); MY_ADD_CHARSET(&my_charset_euckr_bin);
#endif #endif
@@ -451,10 +455,6 @@ static my_bool init_compiled_charsets(myf flags __attribute__((unused)))
MY_ADD_CHARSET(&my_charset_utf8_bin); MY_ADD_CHARSET(&my_charset_utf8_bin);
#endif #endif
#ifdef HAVE_CHARSET_win1250ch
MY_ADD_CHARSET(&my_charset_cp1250_czech_ci);
#endif
/* Copy compiled charsets */ /* Copy compiled charsets */
for (cs=compiled_charsets; cs->name; cs++) for (cs=compiled_charsets; cs->name; cs++)
{ {

View File

@@ -5493,6 +5493,6 @@ void Field::set_warning(const uint level, const uint code)
{ {
THD *thd= current_thd; THD *thd= current_thd;
thd->cuted_fields++; thd->cuted_fields++;
push_warning_printf(thd, (MYSQL_ERROR::enum_warning_level)level, push_warning_printf(thd, (MYSQL_ERROR::enum_warning_level) level,
code, ER(code), field_name, thd->row_count); code, ER(code), field_name, thd->row_count);
} }

View File

@@ -213,8 +213,7 @@ public:
virtual CHARSET_INFO *charset(void) const { return &my_charset_bin; } virtual CHARSET_INFO *charset(void) const { return &my_charset_bin; }
virtual bool has_charset(void) const { return FALSE; } virtual bool has_charset(void) const { return FALSE; }
virtual void set_charset(CHARSET_INFO *charset) { } virtual void set_charset(CHARSET_INFO *charset) { }
virtual void set_warning(const unsigned int level, void set_warning(const unsigned int level, const unsigned int code);
const unsigned int code);
friend bool reopen_table(THD *,struct st_table *,bool); friend bool reopen_table(THD *,struct st_table *,bool);
friend int cre_myisam(my_string name, register TABLE *form, uint options, friend int cre_myisam(my_string name, register TABLE *form, uint options,
ulonglong auto_increment_value); ulonglong auto_increment_value);

View File

@@ -560,12 +560,12 @@ innobase_query_caching_of_table_permitted(
#endif #endif
if (row_search_check_if_query_cache_permitted(trx, norm_name)) { if (row_search_check_if_query_cache_permitted(trx, norm_name)) {
printf("Query cache for %s permitted\n", norm_name); /* printf("Query cache for %s permitted\n", norm_name); */
return((my_bool)TRUE); return((my_bool)TRUE);
} }
printf("Query cache for %s NOT permitted\n", norm_name); /* printf("Query cache for %s NOT permitted\n", norm_name); */
return((my_bool)FALSE); return((my_bool)FALSE);
} }

View File

@@ -384,7 +384,7 @@ void table_cache_init(void);
void table_cache_free(void); void table_cache_free(void);
uint cached_tables(void); uint cached_tables(void);
void kill_mysql(void); void kill_mysql(void);
void close_connection(NET *net,uint errcode=0,bool lock=1); void close_connection(THD *thd, uint errcode, bool lock);
bool check_access(THD *thd, ulong access, const char *db=0, ulong *save_priv=0, bool check_access(THD *thd, ulong access, const char *db=0, ulong *save_priv=0,
bool no_grant=0, bool no_errors=0); bool no_grant=0, bool no_errors=0);
bool check_table_access(THD *thd, ulong want_access, TABLE_LIST *tables, bool check_table_access(THD *thd, ulong want_access, TABLE_LIST *tables,

View File

@@ -597,7 +597,6 @@ static void close_connections(void)
/* Force remaining threads to die by closing the connection to the client */ /* Force remaining threads to die by closing the connection to the client */
(void) my_net_init(&net, (st_vio*) 0);
for (;;) for (;;)
{ {
DBUG_PRINT("quit",("Locking LOCK_thread_count")); DBUG_PRINT("quit",("Locking LOCK_thread_count"));
@@ -609,17 +608,16 @@ static void close_connections(void)
break; break;
} }
#ifndef __bsdi__ // Bug in BSDI kernel #ifndef __bsdi__ // Bug in BSDI kernel
if ((net.vio=tmp->net.vio) != 0) if (tmp->net.vio)
{ {
sql_print_error(ER(ER_FORCING_CLOSE),my_progname, sql_print_error(ER(ER_FORCING_CLOSE),my_progname,
tmp->thread_id,tmp->user ? tmp->user : ""); tmp->thread_id,tmp->user ? tmp->user : "");
close_connection(&net,0,0); close_connection(tmp,0,0);
} }
#endif #endif
DBUG_PRINT("quit",("Unlocking LOCK_thread_count")); DBUG_PRINT("quit",("Unlocking LOCK_thread_count"));
(void) pthread_mutex_unlock(&LOCK_thread_count); (void) pthread_mutex_unlock(&LOCK_thread_count);
} }
net_end(&net);
/* All threads has now been aborted */ /* All threads has now been aborted */
DBUG_PRINT("quit",("Waiting for threads to die (count=%u)",thread_count)); DBUG_PRINT("quit",("Waiting for threads to die (count=%u)",thread_count));
(void) pthread_mutex_lock(&LOCK_thread_count); (void) pthread_mutex_lock(&LOCK_thread_count);
@@ -1215,19 +1213,20 @@ void yyerror(const char *s)
#ifndef EMBEDDED_LIBRARY #ifndef EMBEDDED_LIBRARY
void close_connection(NET *net,uint errcode,bool lock) void close_connection(THD *thd, uint errcode, bool lock)
{ {
st_vio* vio; st_vio *vio;
DBUG_ENTER("close_connection"); DBUG_ENTER("close_connection");
DBUG_PRINT("enter",("fd: %s error: '%s'", DBUG_PRINT("enter",("fd: %s error: '%s'",
net->vio? vio_description(net->vio):"(not connected)", thd->net.vio ? vio_description(thd->net.vio) :
"(not connected)",
errcode ? ER(errcode) : "")); errcode ? ER(errcode) : ""));
if (lock) if (lock)
(void) pthread_mutex_lock(&LOCK_thread_count); (void) pthread_mutex_lock(&LOCK_thread_count);
if ((vio=net->vio) != 0) if ((vio=thd->net.vio) != 0)
{ {
if (errcode) if (errcode)
net_send_error(net,errcode,ER(errcode)); /* purecov: inspected */ send_error(thd, errcode, ER(errcode)); /* purecov: inspected */
vio_close(vio); /* vio is freed in delete thd */ vio_close(vio); /* vio is freed in delete thd */
} }
if (lock) if (lock)
@@ -2717,7 +2716,7 @@ static void create_new_thread(THD *thd)
if (thread_count - delayed_insert_threads >= max_connections+1 || abort_loop) if (thread_count - delayed_insert_threads >= max_connections+1 || abort_loop)
{ {
DBUG_PRINT("error",("Too many connections")); DBUG_PRINT("error",("Too many connections"));
close_connection(net,ER_CON_COUNT_ERROR); close_connection(thd, ER_CON_COUNT_ERROR, 1);
delete thd; delete thd;
DBUG_VOID_RETURN; DBUG_VOID_RETURN;
} }
@@ -2772,7 +2771,7 @@ static void create_new_thread(THD *thd)
(void) pthread_mutex_unlock(&LOCK_thread_count); (void) pthread_mutex_unlock(&LOCK_thread_count);
net_printf(thd,ER_CANT_CREATE_THREAD,error); net_printf(thd,ER_CANT_CREATE_THREAD,error);
(void) pthread_mutex_lock(&LOCK_thread_count); (void) pthread_mutex_lock(&LOCK_thread_count);
close_connection(net,0,0); close_connection(thd,0,0);
delete thd; delete thd;
(void) pthread_mutex_unlock(&LOCK_thread_count); (void) pthread_mutex_unlock(&LOCK_thread_count);
DBUG_VOID_RETURN; DBUG_VOID_RETURN;
@@ -3093,7 +3092,7 @@ extern "C" pthread_handler_decl(handle_connections_namedpipes,arg)
if (!(thd->net.vio = vio_new_win32pipe(hConnectedPipe)) || if (!(thd->net.vio = vio_new_win32pipe(hConnectedPipe)) ||
my_net_init(&thd->net, thd->net.vio)) my_net_init(&thd->net, thd->net.vio))
{ {
close_connection(&thd->net,ER_OUT_OF_RESOURCES); close_connection(thd, ER_OUT_OF_RESOURCES, 1);
delete thd; delete thd;
continue; continue;
} }
@@ -3294,7 +3293,7 @@ Send number of connection to client
event_client_read,event_server_wrote,event_server_read)) || event_client_read,event_server_wrote,event_server_read)) ||
my_net_init(&thd->net, thd->net.vio)) my_net_init(&thd->net, thd->net.vio))
{ {
close_connection(&thd->net,ER_OUT_OF_RESOURCES); close_connection(thd, ER_OUT_OF_RESOURCES, 1);
delete thd; delete thd;
error_allow = TRUE; error_allow = TRUE;
} }
@@ -5290,6 +5289,11 @@ static void get_options(int argc,char **argv)
if ((ho_error=handle_options(&argc, &argv, my_long_options, get_one_option))) if ((ho_error=handle_options(&argc, &argv, my_long_options, get_one_option)))
exit(ho_error); exit(ho_error);
if (argc > 0)
{
fprintf(stderr, "%s: Too many arguments.\nUse --help to get a list of available options\n", my_progname);
exit(ho_error);
}
#if defined(HAVE_BROKEN_REALPATH) #if defined(HAVE_BROKEN_REALPATH)
my_use_symdir=0; my_use_symdir=0;

View File

@@ -52,7 +52,7 @@ void send_error(THD *thd, uint sql_errno, const char *err)
{ {
#ifndef EMBEDDED_LIBRARY #ifndef EMBEDDED_LIBRARY
uint length; uint length;
char buff[MYSQL_ERRMSG_SIZE+2]; char buff[MYSQL_ERRMSG_SIZE+2], *pos;
#endif #endif
NET *net= &thd->net; NET *net= &thd->net;
DBUG_ENTER("send_error"); DBUG_ENTER("send_error");
@@ -98,7 +98,14 @@ void send_error(THD *thd, uint sql_errno, const char *err)
if (net->return_errno) if (net->return_errno)
{ // new client code; Add errno before message { // new client code; Add errno before message
int2store(buff,sql_errno); int2store(buff,sql_errno);
length= (uint) (strmake(buff+2,err,MYSQL_ERRMSG_SIZE-1) - buff); pos= buff+2;
if (thd->client_capabilities & CLIENT_PROTOCOL_41)
{
/* The first # is to make the protocol backward compatible */
strmov(buff+2, "#000000");
pos= buff + 2 + SQLSTATE_LENGTH +1;
}
length= (uint) (strmake(pos, err, MYSQL_ERRMSG_SIZE-1) - buff);
err=buff; err=buff;
} }
else else
@@ -113,26 +120,6 @@ void send_error(THD *thd, uint sql_errno, const char *err)
DBUG_VOID_RETURN; DBUG_VOID_RETURN;
} }
/*
Send an error to the client when a connection is forced close
This is used by mysqld.cc, which doesn't have a THD
*/
#ifndef EMBEDDED_LIBRARY
void net_send_error(NET *net, uint sql_errno, const char *err)
{
char buff[2];
uint length;
DBUG_ENTER("send_net_error");
int2store(buff,sql_errno);
length=(uint) strlen(err);
set_if_smaller(length,MYSQL_ERRMSG_SIZE-1);
net_write_command(net,(uchar) 255, buff, 2, err, length);
DBUG_VOID_RETURN;
}
#endif
/* /*
Send a warning to the end user Send a warning to the end user
@@ -173,7 +160,7 @@ net_printf(THD *thd, uint errcode, ...)
#ifndef EMBEDDED_LIBRARY #ifndef EMBEDDED_LIBRARY
const char *text_pos; const char *text_pos;
#else #else
char text_pos[500]; char text_pos[1024];
#endif #endif
int head_length= NET_HEADER_SIZE; int head_length= NET_HEADER_SIZE;
NET *net= &thd->net; NET *net= &thd->net;
@@ -199,9 +186,11 @@ net_printf(THD *thd, uint errcode, ...)
format=va_arg(args,char*); format=va_arg(args,char*);
errcode= ER_UNKNOWN_ERROR; errcode= ER_UNKNOWN_ERROR;
} }
offset= net->return_errno ? 2 : 0; offset= (net->return_errno ?
((thd->client_capabilities & CLIENT_PROTOCOL_41) ?
2+SQLSTATE_LENGTH+1 : 2) : 0);
#ifndef EMBEDDED_LIBRARY #ifndef EMBEDDED_LIBRARY
text_pos=(char*) net->buff+head_length+offset+1; text_pos=(char*) net->buff + head_length + offset + 1;
#endif #endif
(void) vsprintf(my_const_cast(char*) (text_pos),format,args); (void) vsprintf(my_const_cast(char*) (text_pos),format,args);
length=(uint) strlen((char*) text_pos); length=(uint) strlen((char*) text_pos);
@@ -228,7 +217,15 @@ net_printf(THD *thd, uint errcode, ...)
net->buff[3]= (net->compress) ? 0 : (uchar) (net->pkt_nr++); net->buff[3]= (net->compress) ? 0 : (uchar) (net->pkt_nr++);
net->buff[head_length]=(uchar) 255; // Error package net->buff[head_length]=(uchar) 255; // Error package
if (offset) if (offset)
int2store(text_pos-2, errcode); {
uchar *pos= net->buff+head_length+1;
int2store(pos, errcode);
if (thd->client_capabilities & CLIENT_PROTOCOL_41)
{
/* The first # is to make the protocol backward compatible */
memcpy(pos+2, "#000000", SQLSTATE_LENGTH +1);
}
}
VOID(net_real_write(net,(char*) net->buff,length+head_length+1+offset)); VOID(net_real_write(net,(char*) net->buff,length+head_length+1+offset));
#else #else
net->last_errno= errcode; net->last_errno= errcode;
@@ -502,6 +499,7 @@ bool Protocol::send_fields(List<Item> *list, uint flag)
String tmp((char*) buff,sizeof(buff),&my_charset_bin); String tmp((char*) buff,sizeof(buff),&my_charset_bin);
Protocol_simple prot(thd); Protocol_simple prot(thd);
String *packet= prot.storage_packet(); String *packet= prot.storage_packet();
CHARSET_INFO *thd_charset= thd->charset();
DBUG_ENTER("send_fields"); DBUG_ENTER("send_fields");
if (flag & 1) if (flag & 1)
@@ -526,36 +524,37 @@ bool Protocol::send_fields(List<Item> *list, uint flag)
if (thd->client_capabilities & CLIENT_PROTOCOL_41) if (thd->client_capabilities & CLIENT_PROTOCOL_41)
{ {
if (prot.store(field.db_name, (uint) strlen(field.db_name), if (prot.store("std", 3, cs, thd_charset) ||
cs, thd->charset()) || prot.store(field.db_name, (uint) strlen(field.db_name),
cs, thd_charset) ||
prot.store(field.table_name, (uint) strlen(field.table_name), prot.store(field.table_name, (uint) strlen(field.table_name),
cs, thd->charset()) || cs, thd_charset) ||
prot.store(field.org_table_name, (uint) strlen(field.org_table_name), prot.store(field.org_table_name, (uint) strlen(field.org_table_name),
cs, thd->charset()) || cs, thd_charset) ||
prot.store(field.col_name, (uint) strlen(field.col_name), prot.store(field.col_name, (uint) strlen(field.col_name),
cs, thd->charset()) || cs, thd_charset) ||
prot.store(field.org_col_name, (uint) strlen(field.org_col_name), prot.store(field.org_col_name, (uint) strlen(field.org_col_name),
cs, thd->charset()) || cs, thd_charset) ||
packet->realloc(packet->length()+12)) packet->realloc(packet->length()+12))
goto err; goto err;
/* Store fixed length fields */ /* Store fixed length fields */
pos= (char*) packet->ptr()+packet->length(); pos= (char*) packet->ptr()+packet->length();
*pos++= 11; // Length of packed fields *pos++= 12; // Length of packed fields
int2store(pos, field.charsetnr); int2store(pos, field.charsetnr);
int3store(pos+2, field.length); int4store(pos+2, field.length);
pos[5]= field.type; pos[6]= field.type;
int2store(pos+6,field.flags); int2store(pos+7,field.flags);
pos[8]= (char) field.decimals; pos[9]= (char) field.decimals;
pos[9]= 0; // For the future
pos[10]= 0; // For the future pos[10]= 0; // For the future
pos+= 11; pos[11]= 0; // For the future
pos+= 12;
} }
else else
{ {
if (prot.store(field.table_name, (uint) strlen(field.table_name), if (prot.store(field.table_name, (uint) strlen(field.table_name),
cs, thd->charset()) || cs, thd_charset) ||
prot.store(field.col_name, (uint) strlen(field.col_name), prot.store(field.col_name, (uint) strlen(field.col_name),
cs, thd->charset()) || cs, thd_charset) ||
packet->realloc(packet->length()+10)) packet->realloc(packet->length()+10))
goto err; goto err;
pos= (char*) packet->ptr()+packet->length(); pos= (char*) packet->ptr()+packet->length();
@@ -893,9 +892,10 @@ bool Protocol_simple::store_time(TIME *tm)
#endif #endif
char buff[40]; char buff[40];
uint length; uint length;
uint day= (tm->year || tm->month) ? 0 : tm->day;
length= my_sprintf(buff,(buff, "%s%02ld:%02d:%02d", length= my_sprintf(buff,(buff, "%s%02ld:%02d:%02d",
tm->neg ? "-" : "", tm->neg ? "-" : "",
(long) tm->day*3600L+(long) tm->hour, (long) day*24L+(long) tm->hour,
(int) tm->minute, (int) tm->minute,
(int) tm->second)); (int) tm->second));
return net_store_data((char*) buff, length); return net_store_data((char*) buff, length);

View File

@@ -162,7 +162,6 @@ void net_printf(THD *thd,uint sql_errno, ...);
void send_ok(THD *thd, ha_rows affected_rows=0L, ulonglong id=0L, void send_ok(THD *thd, ha_rows affected_rows=0L, ulonglong id=0L,
const char *info=0); const char *info=0);
void send_eof(THD *thd, bool no_flush=0); void send_eof(THD *thd, bool no_flush=0);
void net_send_error(NET *net, uint sql_errno, const char *err);
char *net_store_length(char *packet,ulonglong length); char *net_store_length(char *packet,ulonglong length);
char *net_store_length(char *packet,uint length); char *net_store_length(char *packet,uint length);
char *net_store_data(char *to,const char *from, uint length); char *net_store_data(char *to,const char *from, uint length);

View File

@@ -72,7 +72,7 @@ static int init_failsafe_rpl_thread(THD* thd)
if (init_thr_lock() || thd->store_globals()) if (init_thr_lock() || thd->store_globals())
{ {
close_connection(&thd->net,ER_OUT_OF_RESOURCES); // is this needed? close_connection(thd, ER_OUT_OF_RESOURCES, 1); // is this needed?
end_thread(thd,0); end_thread(thd,0);
DBUG_RETURN(-1); DBUG_RETURN(-1);
} }

View File

@@ -348,7 +348,9 @@ To make maintaining easier please:
<order>Slovenian</order> <order>Slovenian</order>
<order>Sorbian</order> <order>Sorbian</order>
</collation> </collation>
<collation name="cp1250_czech_ci" id="34" order="Czech"/> <collation name="cp1250_czech_ci" id="34" order="Czech">
<flag>compiled</flag>
</collation>
<collation name="cp1250_bin" id="66" order="Binary" flag="binary"/> <collation name="cp1250_bin" id="66" order="Binary" flag="binary"/>
</charset> </charset>

View File

@@ -178,6 +178,15 @@ int mysql_delete(THD *thd, TABLE_LIST *table_list, COND *conds, ORDER *order,
(void) table->file->extra(HA_EXTRA_NORMAL); (void) table->file->extra(HA_EXTRA_NORMAL);
cleanup: cleanup:
/*
Invalidate the table in the query cache if something changed. This must
be before binlog writing and ha_autocommit_...
*/
if (deleted)
{
query_cache_invalidate3(thd, table_list, 1);
}
transactional_table= table->file->has_transactions(); transactional_table= table->file->has_transactions();
log_delayed= (transactional_table || table->tmp_table); log_delayed= (transactional_table || table->tmp_table);
if (deleted && (error <= 0 || !transactional_table)) if (deleted && (error <= 0 || !transactional_table))
@@ -199,14 +208,6 @@ cleanup:
error=1; error=1;
} }
/*
Store table for future invalidation or invalidate it in
the query cache if something changed
*/
if (deleted)
{
query_cache_invalidate3(thd, table_list, 1);
}
if (thd->lock) if (thd->lock)
{ {
mysql_unlock_tables(thd, thd->lock); mysql_unlock_tables(thd, thd->lock);
@@ -480,6 +481,12 @@ bool multi_delete::send_eof()
/* reset used flags */ /* reset used flags */
thd->proc_info="end"; thd->proc_info="end";
/*
We must invalidate the query cache before binlog writing and
ha_autocommit_...
*/
if (deleted)
query_cache_invalidate3(thd, delete_tables, 1);
/* /*
Write the SQL statement to the binlog if we deleted Write the SQL statement to the binlog if we deleted
@@ -505,9 +512,6 @@ bool multi_delete::send_eof()
if (ha_autocommit_or_rollback(thd,local_error > 0)) if (ha_autocommit_or_rollback(thd,local_error > 0))
local_error=1; local_error=1;
if (deleted)
query_cache_invalidate3(thd, delete_tables, 1);
if (local_error) if (local_error)
::send_error(thd); ::send_error(thd);
else else

View File

@@ -344,7 +344,16 @@ int mysql_insert(THD *thd,TABLE_LIST *table_list,
else if (table->next_number_field) else if (table->next_number_field)
id=table->next_number_field->val_int(); // Return auto_increment value id=table->next_number_field->val_int(); // Return auto_increment value
/*
Invalidate the table in the query cache if something changed.
For the transactional algorithm to work the invalidation must be
before binlog writing and ha_autocommit_...
*/
if (info.copied || info.deleted)
query_cache_invalidate3(thd, table_list, 1);
transactional_table= table->file->has_transactions(); transactional_table= table->file->has_transactions();
log_delayed= (transactional_table || table->tmp_table); log_delayed= (transactional_table || table->tmp_table);
if ((info.copied || info.deleted) && (error <= 0 || !transactional_table)) if ((info.copied || info.deleted) && (error <= 0 || !transactional_table))
{ {
@@ -362,14 +371,6 @@ int mysql_insert(THD *thd,TABLE_LIST *table_list,
if (transactional_table) if (transactional_table)
error=ha_autocommit_or_rollback(thd,error); error=ha_autocommit_or_rollback(thd,error);
/*
Store table for future invalidation or invalidate it in
the query cache if something changed
*/
if (info.copied || info.deleted)
{
query_cache_invalidate3(thd, table_list, 1);
}
if (thd->lock) if (thd->lock)
{ {
mysql_unlock_tables(thd, thd->lock); mysql_unlock_tables(thd, thd->lock);
@@ -1420,11 +1421,9 @@ void select_insert::send_error(uint errcode,const char *err)
::send_error(thd,errcode,err); ::send_error(thd,errcode,err);
table->file->extra(HA_EXTRA_NO_CACHE); table->file->extra(HA_EXTRA_NO_CACHE);
table->file->activate_all_index(thd); table->file->activate_all_index(thd);
ha_rollback_stmt(thd);
if (info.copied || info.deleted) if (info.copied || info.deleted)
{
query_cache_invalidate3(thd, table, 1); query_cache_invalidate3(thd, table, 1);
} ha_rollback_stmt(thd);
} }
@@ -1435,6 +1434,14 @@ bool select_insert::send_eof()
error=table->file->activate_all_index(thd); error=table->file->activate_all_index(thd);
table->file->extra(HA_EXTRA_NO_IGNORE_DUP_KEY); table->file->extra(HA_EXTRA_NO_IGNORE_DUP_KEY);
/*
We must invalidate the table in the query cache before binlog writing
and ha_autocommit_...
*/
if (info.copied || info.deleted)
query_cache_invalidate3(thd, table, 1);
/* Write to binlog before commiting transaction */ /* Write to binlog before commiting transaction */
if (mysql_bin_log.is_open()) if (mysql_bin_log.is_open())
{ {
@@ -1444,10 +1451,6 @@ bool select_insert::send_eof()
} }
if ((error2=ha_autocommit_or_rollback(thd,error)) && ! error) if ((error2=ha_autocommit_or_rollback(thd,error)) && ! error)
error=error2; error=error2;
if (info.copied || info.deleted)
{
query_cache_invalidate3(thd, table, 1);
}
if (error) if (error)
{ {
table->file->print_error(error,MYF(0)); table->file->print_error(error,MYF(0));

View File

@@ -283,6 +283,12 @@ int mysql_load(THD *thd,sql_exchange *ex,TABLE_LIST *table_list,
table->copy_blobs=0; table->copy_blobs=0;
thd->count_cuted_fields=0; /* Don`t calc cuted fields */ thd->count_cuted_fields=0; /* Don`t calc cuted fields */
/*
We must invalidate the table in query cache before binlog writing and
ha_autocommit_...
*/
query_cache_invalidate3(thd, table_list, 0);
if (error) if (error)
{ {
if (transactional_table) if (transactional_table)
@@ -344,8 +350,6 @@ int mysql_load(THD *thd,sql_exchange *ex,TABLE_LIST *table_list,
} }
if (transactional_table) if (transactional_table)
error=ha_autocommit_or_rollback(thd,error); error=ha_autocommit_or_rollback(thd,error);
query_cache_invalidate3(thd, table_list, 0);
err: err:
if (thd->lock) if (thd->lock)
{ {

View File

@@ -601,7 +601,7 @@ check_connections(THD *thd)
{ {
/* buff[] needs to big enough to hold the server_version variable */ /* buff[] needs to big enough to hold the server_version variable */
char buff[SERVER_VERSION_LENGTH + SCRAMBLE_LENGTH+64]; char buff[SERVER_VERSION_LENGTH + SCRAMBLE_LENGTH+64];
int client_flags = (CLIENT_LONG_FLAG | CLIENT_CONNECT_WITH_DB | ulong client_flags = (CLIENT_LONG_FLAG | CLIENT_CONNECT_WITH_DB |
CLIENT_PROTOCOL_41 | CLIENT_SECURE_CONNECTION); CLIENT_PROTOCOL_41 | CLIENT_SECURE_CONNECTION);
if (opt_using_transactions) if (opt_using_transactions)
@@ -644,11 +644,26 @@ check_connections(THD *thd)
return(ER_OUT_OF_RESOURCES); return(ER_OUT_OF_RESOURCES);
thd->client_capabilities=uint2korr(net->read_pos); thd->client_capabilities=uint2korr(net->read_pos);
#ifdef TO_BE_REMOVED_IN_4_1_RELEASE
/*
This is just a safety check against any client that would use the old
CLIENT_CHANGE_USER flag
*/
if ((thd->client_capabilities & CLIENT_PROTOCOL_41) &&
!(thd->client_capabilities & (CLIENT_RESERVED |
CLIENT_SECURE_CONNECTION |
CLIENT_MULTI_RESULTS)))
thd->client_capabilities&= ~CLIENT_PROTOCOL_41;
#endif
if (thd->client_capabilities & CLIENT_PROTOCOL_41) if (thd->client_capabilities & CLIENT_PROTOCOL_41)
{ {
thd->client_capabilities|= ((ulong) uint2korr(net->read_pos+2)) << 16; thd->client_capabilities|= ((ulong) uint2korr(net->read_pos+2)) << 16;
thd->max_client_packet_length= uint4korr(net->read_pos+4); thd->max_client_packet_length= uint4korr(net->read_pos+4);
end= (char*) net->read_pos+8; if (!(thd->variables.character_set_client=
get_charset((uint) net->read_pos[8], MYF(0))))
thd->variables.character_set_client=
global_system_variables.character_set_client;
end= (char*) net->read_pos+32;
} }
else else
{ {
@@ -778,7 +793,7 @@ pthread_handler_decl(handle_one_connection,arg)
// The following calls needs to be done before we call DBUG_ macros // The following calls needs to be done before we call DBUG_ macros
if (!(test_flags & TEST_NO_THREADS) & my_thread_init()) if (!(test_flags & TEST_NO_THREADS) & my_thread_init())
{ {
close_connection(&thd->net,ER_OUT_OF_RESOURCES); close_connection(thd, ER_OUT_OF_RESOURCES, 1);
statistic_increment(aborted_connects,&LOCK_status); statistic_increment(aborted_connects,&LOCK_status);
end_thread(thd,0); end_thread(thd,0);
return 0; return 0;
@@ -805,7 +820,7 @@ pthread_handler_decl(handle_one_connection,arg)
#endif #endif
if (thd->store_globals()) if (thd->store_globals())
{ {
close_connection(&thd->net,ER_OUT_OF_RESOURCES); close_connection(thd, ER_OUT_OF_RESOURCES, 1);
statistic_increment(aborted_connects,&LOCK_status); statistic_increment(aborted_connects,&LOCK_status);
end_thread(thd,0); end_thread(thd,0);
return 0; return 0;
@@ -863,7 +878,7 @@ pthread_handler_decl(handle_one_connection,arg)
} }
end_thread: end_thread:
close_connection(net); close_connection(thd, 0, 1);
end_thread(thd,1); end_thread(thd,1);
/* /*
If end_thread returns, we are either running with --one-thread If end_thread returns, we are either running with --one-thread
@@ -889,7 +904,7 @@ extern "C" pthread_handler_decl(handle_bootstrap,arg)
/* The following must be called before DBUG_ENTER */ /* The following must be called before DBUG_ENTER */
if (my_thread_init() || thd->store_globals()) if (my_thread_init() || thd->store_globals())
{ {
close_connection(&thd->net,ER_OUT_OF_RESOURCES); close_connection(thd, ER_OUT_OF_RESOURCES, 1);
thd->fatal_error(); thd->fatal_error();
goto end; goto end;
} }
@@ -1419,7 +1434,7 @@ restore_user:
#ifndef OS2 #ifndef OS2
send_eof(thd); // This is for 'quit request' send_eof(thd); // This is for 'quit request'
#endif #endif
close_connection(net); close_connection(thd, 0, 1);
close_thread_tables(thd); // Free before kill close_thread_tables(thd); // Free before kill
free_root(&thd->mem_root,MYF(0)); free_root(&thd->mem_root,MYF(0));
free_root(&thd->transaction.mem_root,MYF(0)); free_root(&thd->transaction.mem_root,MYF(0));

View File

@@ -332,6 +332,14 @@ int mysql_update(THD *thd,
free_io_cache(table); // If ORDER BY free_io_cache(table); // If ORDER BY
thd->proc_info="end"; thd->proc_info="end";
VOID(table->file->extra(HA_EXTRA_NO_IGNORE_DUP_KEY)); VOID(table->file->extra(HA_EXTRA_NO_IGNORE_DUP_KEY));
/*
Invalidate the table in the query cache if something changed.
This must be before binlog writing and ha_autocommit_...
*/
if (updated)
query_cache_invalidate3(thd, table_list, 1);
transactional_table= table->file->has_transactions(); transactional_table= table->file->has_transactions();
log_delayed= (transactional_table || table->tmp_table); log_delayed= (transactional_table || table->tmp_table);
if (updated && (error <= 0 || !transactional_table)) if (updated && (error <= 0 || !transactional_table))
@@ -353,14 +361,6 @@ int mysql_update(THD *thd,
error=1; error=1;
} }
/*
Store table for future invalidation or invalidate it in
the query cache if something changed
*/
if (updated)
{
query_cache_invalidate3(thd, table_list, 1);
}
if (thd->lock) if (thd->lock)
{ {
mysql_unlock_tables(thd, thd->lock); mysql_unlock_tables(thd, thd->lock);
@@ -950,6 +950,14 @@ bool multi_update::send_eof()
int local_error = (table_count) ? do_updates(0) : 0; int local_error = (table_count) ? do_updates(0) : 0;
thd->proc_info= "end"; thd->proc_info= "end";
/* We must invalidate the query cache before binlog writing and
ha_autocommit_... */
if (updated)
{
query_cache_invalidate3(thd, update_tables, 1);
}
/* /*
Write the SQL statement to the binlog if we updated Write the SQL statement to the binlog if we updated
rows and we succeeded or if we updated some non rows and we succeeded or if we updated some non
@@ -988,10 +996,6 @@ bool multi_update::send_eof()
sprintf(buff,ER(ER_UPDATE_INFO), (long) found, (long) updated, sprintf(buff,ER(ER_UPDATE_INFO), (long) found, (long) updated,
(long) thd->cuted_fields); (long) thd->cuted_fields);
if (updated)
{
query_cache_invalidate3(thd, update_tables, 1);
}
::send_ok(thd, ::send_ok(thd,
(thd->client_capabilities & CLIENT_FOUND_ROWS) ? found : updated, (thd->client_capabilities & CLIENT_FOUND_ROWS) ? found : updated,
thd->insert_id_used ? thd->insert_id() : 0L,buff); thd->insert_id_used ? thd->insert_id() : 0L,buff);

View File

@@ -77,7 +77,7 @@
#endif #endif
#ifdef HAVE_CHARSET_czech #ifdef HAVE_CHARSET_latin2
/* /*
These are four tables for four passes of the algorithm. Please see These are four tables for four passes of the algorithm. Please see

View File

@@ -30,7 +30,7 @@
#include "m_string.h" #include "m_string.h"
#include "m_ctype.h" #include "m_ctype.h"
#ifdef HAVE_CHARSET_euc_kr #ifdef HAVE_CHARSET_euckr
static uchar NEAR ctype_euc_kr[257] = static uchar NEAR ctype_euc_kr[257] =

View File

@@ -45,6 +45,9 @@
#include "m_string.h" #include "m_string.h"
#include "m_ctype.h" #include "m_ctype.h"
#ifdef HAVE_CHARSET_cp1250
static uint16 tab_cp1250_uni[256]={ static uint16 tab_cp1250_uni[256]={
0,0x0001,0x0002,0x0003,0x0004,0x0005,0x0006,0x0007, 0,0x0001,0x0002,0x0003,0x0004,0x0005,0x0006,0x0007,
0x0008,0x0009,0x000A,0x000B,0x000C,0x000D,0x000E,0x000F, 0x0008,0x0009,0x000A,0x000B,0x000C,0x000D,0x000E,0x000F,
@@ -673,4 +676,6 @@ CHARSET_INFO my_charset_cp1250_czech_ci =
}; };
#endif
#endif #endif