mirror of
https://github.com/MariaDB/server.git
synced 2025-01-17 20:42:30 +01:00
bfae473053
check_user()/check_connection()/check_for_max_user_connections(). This is a pre-requisite patch for the fix for Bug#12713 "Error in a stored function called from a SELECT doesn't cause ROLLBACK of statem" Implement review comments. sql/mysql_priv.h: check_for_max_user_connections() is used in one place only, make it static. sql/mysqld.cc: Remove net_printf_error(): a consolidation of error reporting facilities is necessary to simplify maintenance of the query cache, the client-server protocol, stored procedure continue handlers. Rewrite the only place where its use is somewhat justified (my_error() can not be used since we need to report an error for the thread that does not exist) with my_snprintf()/net_send_error(). sql/protocol.cc: Remove net_printf_error(). sql/protocol.h: Remove net_printf_error(). sql/sql_connect.cc: Remove net_printf_error(). In check_connection()/check_user()/ check_for_max_user_connections() do not write directly to the network, but use the standard my_error() mechanism to record an error in THD. It will be sent to the client by the caller. This was the last place in the server that would attempt to send an error directly, mainly left untouched by 5.0 refactoring because it is executed only during thread startup. sql/sql_parse.cc: In the old code, when res was greater than 0, it contained an exact error code, e.g. ER_OUT_OF_RESOURCES or NO SUCH DATABASE, or ER_HANDSHAKE_ERROR. I don't know the reason why this error code was ignored, and instead a generic ER_UNKNOWN_COM_ERROR was pushed into the error stack, but knowing the relaxed attitude towards preserving the error codes in the old code, I'm inclinded to think that it was a bug. After this patch, the most specific error message is already pushed, so calling my_message() again is useless. If res is < 0, the error used to be already sent. This is not done by the new code, but will be done later, in the end of dispatch_command(). When this is done, clear_error() will be called for us - it is in the first lines of do_command. To sum up, this change is to remove COM_CHANGE_USER specific error handling in favor of the standard one employed for all other COM_* commands.
183 lines
6.2 KiB
C++
183 lines
6.2 KiB
C++
/* Copyright (C) 2002-2006 MySQL AB
|
|
|
|
This program is free software; you can redistribute it and/or modify
|
|
it under the terms of the GNU General Public License as published by
|
|
the Free Software Foundation; version 2 of the License.
|
|
|
|
This program is distributed in the hope that it will be useful,
|
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
GNU General Public License for more details.
|
|
|
|
You should have received a copy of the GNU General Public License
|
|
along with this program; if not, write to the Free Software
|
|
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
|
|
|
|
#ifdef USE_PRAGMA_INTERFACE
|
|
#pragma interface /* gcc class implementation */
|
|
#endif
|
|
|
|
|
|
class i_string;
|
|
class THD;
|
|
typedef struct st_mysql_field MYSQL_FIELD;
|
|
typedef struct st_mysql_rows MYSQL_ROWS;
|
|
|
|
class Protocol
|
|
{
|
|
protected:
|
|
THD *thd;
|
|
String *packet;
|
|
String *convert;
|
|
uint field_pos;
|
|
#ifndef DBUG_OFF
|
|
enum enum_field_types *field_types;
|
|
#endif
|
|
uint field_count;
|
|
#ifndef EMBEDDED_LIBRARY
|
|
bool net_store_data(const uchar *from, size_t length);
|
|
#else
|
|
virtual bool net_store_data(const uchar *from, size_t length);
|
|
char **next_field;
|
|
MYSQL_FIELD *next_mysql_field;
|
|
MEM_ROOT *alloc;
|
|
#endif
|
|
bool store_string_aux(const char *from, size_t length,
|
|
CHARSET_INFO *fromcs, CHARSET_INFO *tocs);
|
|
public:
|
|
Protocol() {}
|
|
Protocol(THD *thd_arg) { init(thd_arg); }
|
|
virtual ~Protocol() {}
|
|
void init(THD* thd_arg);
|
|
|
|
enum { SEND_NUM_ROWS= 1, SEND_DEFAULTS= 2, SEND_EOF= 4 };
|
|
virtual bool send_fields(List<Item> *list, uint flags);
|
|
|
|
bool store(I_List<i_string> *str_list);
|
|
bool store(const char *from, CHARSET_INFO *cs);
|
|
String *storage_packet() { return packet; }
|
|
inline void free() { packet->free(); }
|
|
virtual bool write();
|
|
inline bool store(int from)
|
|
{ return store_long((longlong) from); }
|
|
inline bool store(uint32 from)
|
|
{ return store_long((longlong) from); }
|
|
inline bool store(longlong from)
|
|
{ return store_longlong((longlong) from, 0); }
|
|
inline bool store(ulonglong from)
|
|
{ return store_longlong((longlong) from, 1); }
|
|
inline bool store(String *str)
|
|
{ return store((char*) str->ptr(), str->length(), str->charset()); }
|
|
|
|
virtual bool prepare_for_send(List<Item> *item_list)
|
|
{
|
|
field_count=item_list->elements;
|
|
return 0;
|
|
}
|
|
virtual bool flush();
|
|
virtual void prepare_for_resend()=0;
|
|
|
|
virtual bool store_null()=0;
|
|
virtual bool store_tiny(longlong from)=0;
|
|
virtual bool store_short(longlong from)=0;
|
|
virtual bool store_long(longlong from)=0;
|
|
virtual bool store_longlong(longlong from, bool unsigned_flag)=0;
|
|
virtual bool store_decimal(const my_decimal *)=0;
|
|
virtual bool store(const char *from, size_t length, CHARSET_INFO *cs)=0;
|
|
virtual bool store(const char *from, size_t length,
|
|
CHARSET_INFO *fromcs, CHARSET_INFO *tocs)=0;
|
|
virtual bool store(float from, uint32 decimals, String *buffer)=0;
|
|
virtual bool store(double from, uint32 decimals, String *buffer)=0;
|
|
virtual bool store(MYSQL_TIME *time)=0;
|
|
virtual bool store_date(MYSQL_TIME *time)=0;
|
|
virtual bool store_time(MYSQL_TIME *time)=0;
|
|
virtual bool store(Field *field)=0;
|
|
#ifdef EMBEDDED_LIBRARY
|
|
int begin_dataset();
|
|
virtual void remove_last_row() {}
|
|
#else
|
|
void remove_last_row() {}
|
|
#endif
|
|
enum enum_protocol_type
|
|
{
|
|
PROTOCOL_TEXT= 0, PROTOCOL_BINARY= 1
|
|
/*
|
|
before adding here or change the values, consider that it is cast to a
|
|
bit in sql_cache.cc.
|
|
*/
|
|
};
|
|
virtual enum enum_protocol_type type()= 0;
|
|
};
|
|
|
|
|
|
/* Class used for the old (MySQL 4.0 protocol) */
|
|
|
|
class Protocol_text :public Protocol
|
|
{
|
|
public:
|
|
Protocol_text() {}
|
|
Protocol_text(THD *thd_arg) :Protocol(thd_arg) {}
|
|
virtual void prepare_for_resend();
|
|
virtual bool store_null();
|
|
virtual bool store_tiny(longlong from);
|
|
virtual bool store_short(longlong from);
|
|
virtual bool store_long(longlong from);
|
|
virtual bool store_longlong(longlong from, bool unsigned_flag);
|
|
virtual bool store_decimal(const my_decimal *);
|
|
virtual bool store(const char *from, size_t length, CHARSET_INFO *cs);
|
|
virtual bool store(const char *from, size_t length,
|
|
CHARSET_INFO *fromcs, CHARSET_INFO *tocs);
|
|
virtual bool store(MYSQL_TIME *time);
|
|
virtual bool store_date(MYSQL_TIME *time);
|
|
virtual bool store_time(MYSQL_TIME *time);
|
|
virtual bool store(float nr, uint32 decimals, String *buffer);
|
|
virtual bool store(double from, uint32 decimals, String *buffer);
|
|
virtual bool store(Field *field);
|
|
#ifdef EMBEDDED_LIBRARY
|
|
void remove_last_row();
|
|
#endif
|
|
virtual enum enum_protocol_type type() { return PROTOCOL_TEXT; };
|
|
};
|
|
|
|
|
|
class Protocol_binary :public Protocol
|
|
{
|
|
private:
|
|
uint bit_fields;
|
|
public:
|
|
Protocol_binary() {}
|
|
Protocol_binary(THD *thd_arg) :Protocol(thd_arg) {}
|
|
virtual bool prepare_for_send(List<Item> *item_list);
|
|
virtual void prepare_for_resend();
|
|
#ifdef EMBEDDED_LIBRARY
|
|
virtual bool write();
|
|
bool net_store_data(const uchar *from, size_t length);
|
|
#endif
|
|
virtual bool store_null();
|
|
virtual bool store_tiny(longlong from);
|
|
virtual bool store_short(longlong from);
|
|
virtual bool store_long(longlong from);
|
|
virtual bool store_longlong(longlong from, bool unsigned_flag);
|
|
virtual bool store_decimal(const my_decimal *);
|
|
virtual bool store(const char *from, size_t length, CHARSET_INFO *cs);
|
|
virtual bool store(const char *from, size_t length,
|
|
CHARSET_INFO *fromcs, CHARSET_INFO *tocs);
|
|
virtual bool store(MYSQL_TIME *time);
|
|
virtual bool store_date(MYSQL_TIME *time);
|
|
virtual bool store_time(MYSQL_TIME *time);
|
|
virtual bool store(float nr, uint32 decimals, String *buffer);
|
|
virtual bool store(double from, uint32 decimals, String *buffer);
|
|
virtual bool store(Field *field);
|
|
virtual enum enum_protocol_type type() { return PROTOCOL_BINARY; };
|
|
};
|
|
|
|
void send_warning(THD *thd, uint sql_errno, const char *err=0);
|
|
void net_send_error(THD *thd, uint sql_errno=0, const char *err=0);
|
|
void send_ok(THD *thd, ha_rows affected_rows=0L, ulonglong id=0L,
|
|
const char *info=0);
|
|
void send_eof(THD *thd);
|
|
bool send_old_password_request(THD *thd);
|
|
uchar *net_store_data(uchar *to,const uchar *from, size_t length);
|
|
uchar *net_store_data(uchar *to,int32 from);
|
|
uchar *net_store_data(uchar *to,longlong from);
|
|
|