2002-12-11 08:17:51 +01:00
|
|
|
/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
|
|
|
|
|
|
|
|
This program is free software; you can redistribute it and/or modify
|
|
|
|
it under the terms of the GNU General Public License as published by
|
|
|
|
the Free Software Foundation; either version 2 of the License, or
|
|
|
|
(at your option) any later version.
|
|
|
|
|
|
|
|
This program is distributed in the hope that it will be useful,
|
|
|
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
|
GNU General Public License for more details.
|
|
|
|
|
|
|
|
You should have received a copy of the GNU General Public License
|
|
|
|
along with this program; if not, write to the Free Software
|
|
|
|
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
|
|
|
|
|
2005-05-04 15:05:56 +02:00
|
|
|
#ifdef USE_PRAGMA_INTERFACE
|
2002-12-11 08:17:51 +01:00
|
|
|
#pragma interface /* gcc class implementation */
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
|
|
class i_string;
|
|
|
|
class THD;
|
2003-01-20 15:47:25 +01:00
|
|
|
typedef struct st_mysql_field MYSQL_FIELD;
|
2003-04-23 16:37:33 +02:00
|
|
|
typedef struct st_mysql_rows MYSQL_ROWS;
|
|
|
|
|
2002-12-11 08:17:51 +01:00
|
|
|
class Protocol
|
|
|
|
{
|
|
|
|
protected:
|
|
|
|
THD *thd;
|
|
|
|
String *packet;
|
2004-05-25 00:03:49 +02:00
|
|
|
String *convert;
|
2002-12-11 08:17:51 +01:00
|
|
|
uint field_pos;
|
|
|
|
#ifndef DEBUG_OFF
|
|
|
|
enum enum_field_types *field_types;
|
|
|
|
#endif
|
2003-01-15 09:11:44 +01:00
|
|
|
uint field_count;
|
2004-06-09 19:36:48 +02:00
|
|
|
#ifndef EMBEDDED_LIBRARY
|
2003-01-15 09:11:44 +01:00
|
|
|
bool net_store_data(const char *from, uint length);
|
2004-06-09 19:36:48 +02:00
|
|
|
#else
|
|
|
|
virtual bool net_store_data(const char *from, uint length);
|
2003-01-15 09:11:44 +01:00
|
|
|
char **next_field;
|
2003-01-20 15:47:25 +01:00
|
|
|
MYSQL_FIELD *next_mysql_field;
|
2003-01-15 09:11:44 +01:00
|
|
|
MEM_ROOT *alloc;
|
2002-12-17 16:33:25 +01:00
|
|
|
#endif
|
2004-05-25 00:03:49 +02:00
|
|
|
bool store_string_aux(const char *from, uint length,
|
|
|
|
CHARSET_INFO *fromcs, CHARSET_INFO *tocs);
|
2002-12-11 08:17:51 +01:00
|
|
|
public:
|
|
|
|
Protocol() {}
|
2003-11-28 11:18:13 +01:00
|
|
|
Protocol(THD *thd_arg) { init(thd_arg); }
|
2003-03-21 12:18:52 +01:00
|
|
|
virtual ~Protocol() {}
|
2003-11-28 11:18:13 +01:00
|
|
|
void init(THD* thd_arg);
|
Port of cursors to be pushed into 5.0 tree:
- client side part is simple and may be considered stable
- server side part now just joggles with THD state to save execution
state and has no additional locking wisdom.
Lot's of it are to be rewritten.
include/mysql.h:
Cursor patch to push into the main tree, client library part (considered
stable):
- new statement attribute STMT_ATTR_CURSOR_TYPE
- MYSQL_STMT::flags to store statement cursor type
- MYSQL_STMT::server_status to store server status (i. e. if the server
was able to open a cursor for this query).
include/mysql_com.h:
Cursor patch to push into the main tree, client library part (considered
stable):
- new COMmand, COM_FETCH, to fetch K rows from read-only cursor.
By design should support scrollable cursors as well.
- a few new server statuses:
SERVER_STATUS_CURSOR_EXISTS is sent by server in reply to COM_EXECUTE,
when cursor was successfully opened for this query
SERVER_STATUS_LAST_ROW_SENT is sent along with the last row to prevent one
more round trip just for finding out that all rows were fetched from
this cursor (this is server mem savier also).
- and finally, all possible values of STMT_ATTR_CURSOR_TYPE,
while now we support only CURSORT_TYPE_NO_CURSOR and
CURSOR_TYPE_READ_ONLY
libmysql/libmysql.c:
Cursor patch to push into the main tree, client library part (considered
stable):
- simple additions to mysql_stmt_fetch implementation to read data
from an opened cursor: we can read up to iteration count rows per
one request; read rows are buffered in the same way as rows of
mysql_stmt_store_result.
- now send stmt->flags to server to let him now if we wish to have
a cursor for this statement.
- support for setting/getting statement cursor type.
libmysqld/examples/Makefile.am:
Testing cursors was originally implemented in C++. Now when these tests
go into client_test, it's time to convert it to C++ as well.
libmysqld/lib_sql.cc:
- cleanup: send_fields flags are now named.
sql/ha_innodb.cc:
- cleanup: send_fields flags are now named.
sql/mysql_priv.h:
- cursors support: declaration for server-side handler of COM_FETCH
sql/protocol.cc:
- cleanup: send_fields flags are now named.
- we can't anymore assert that field_types[field_pos] is sensible:
if we have COM_EXCUTE(stmt1), COM_EXECUTE(stmt2), COM_FETCH(stmt1)
field_types[field_pos] will point to fields of stmt2.
sql/protocol.h:
- cleanup: send_fields flag_s_ are now named.
sql/protocol_cursor.cc:
- cleanup: send_fields flags are now named.
sql/repl_failsafe.cc:
- cleanup: send_fields flags are now named.
sql/slave.cc:
- cleanup: send_fields flags are now named.
sql/sp.cc:
- cleanup: send_fields flags are now named.
sql/sp_head.cc:
- cleanup: send_fields flags are now named.
sql/sql_acl.cc:
- cleanup: send_fields flags are now named.
sql/sql_class.cc:
- cleanup: send_fields flags are now named.
sql/sql_class.h:
- cleanup: send_fields flags are now named.
sql/sql_error.cc:
- cleanup: send_fields flags are now named.
sql/sql_handler.cc:
- cleanup: send_fields flags are now named.
sql/sql_help.cc:
- cleanup: send_fields flags are now named.
sql/sql_parse.cc:
Server side support for cursors:
- handle COM_FETCH
- enforce assumption that whenever we free thd->free_list,
we reset it to zero. This way it's much easier to handle free_list
in prepared statements implementation.
sql/sql_prepare.cc:
Server side support for cursors:
- implementation of mysql_stmt_fetch (fetch some rows from open cursor).
- management of cursors memory is quite tricky now.
- execute_stmt can't be reused anymore in mysql_stmt_execute and
mysql_sql_stmt_execute
sql/sql_repl.cc:
- cleanup: send_fields flags are now named.
sql/sql_select.cc:
Server side support for cursors:
- implementation of Cursor::open, Cursor::fetch (buggy when it comes to
non-equi joins), cursor cleanups.
- -4 -3 -0 constants indicating return value of sub_select and end_send are
to be renamed to something more readable:
it turned out to be not so simple, so it should come with the other patch.
sql/sql_select.h:
Server side support for cursors:
- declaration of Cursor class.
- JOIN::fetch_limit contains runtime value of rows fetched via cursor.
sql/sql_show.cc:
- cleanup: send_fields flags are now named.
sql/sql_table.cc:
- cleanup: send_fields flags are now named.
sql/sql_union.cc:
- if there was a cursor, don't cleanup unit: we'll need it to fetch
the rest of the rows.
tests/Makefile.am:
Now client_test is in C++.
tests/client_test.cc:
A few elementary tests for cursors.
BitKeeper/etc/ignore:
Added libmysqld/examples/client_test.cc to the ignore list
2004-08-03 12:32:21 +02:00
|
|
|
|
2004-08-28 08:32:27 +02:00
|
|
|
enum { SEND_NUM_ROWS= 1, SEND_DEFAULTS= 2, SEND_EOF= 4 };
|
2004-11-03 11:39:38 +01:00
|
|
|
virtual bool send_fields(List<Item> *list, uint flags);
|
Port of cursors to be pushed into 5.0 tree:
- client side part is simple and may be considered stable
- server side part now just joggles with THD state to save execution
state and has no additional locking wisdom.
Lot's of it are to be rewritten.
include/mysql.h:
Cursor patch to push into the main tree, client library part (considered
stable):
- new statement attribute STMT_ATTR_CURSOR_TYPE
- MYSQL_STMT::flags to store statement cursor type
- MYSQL_STMT::server_status to store server status (i. e. if the server
was able to open a cursor for this query).
include/mysql_com.h:
Cursor patch to push into the main tree, client library part (considered
stable):
- new COMmand, COM_FETCH, to fetch K rows from read-only cursor.
By design should support scrollable cursors as well.
- a few new server statuses:
SERVER_STATUS_CURSOR_EXISTS is sent by server in reply to COM_EXECUTE,
when cursor was successfully opened for this query
SERVER_STATUS_LAST_ROW_SENT is sent along with the last row to prevent one
more round trip just for finding out that all rows were fetched from
this cursor (this is server mem savier also).
- and finally, all possible values of STMT_ATTR_CURSOR_TYPE,
while now we support only CURSORT_TYPE_NO_CURSOR and
CURSOR_TYPE_READ_ONLY
libmysql/libmysql.c:
Cursor patch to push into the main tree, client library part (considered
stable):
- simple additions to mysql_stmt_fetch implementation to read data
from an opened cursor: we can read up to iteration count rows per
one request; read rows are buffered in the same way as rows of
mysql_stmt_store_result.
- now send stmt->flags to server to let him now if we wish to have
a cursor for this statement.
- support for setting/getting statement cursor type.
libmysqld/examples/Makefile.am:
Testing cursors was originally implemented in C++. Now when these tests
go into client_test, it's time to convert it to C++ as well.
libmysqld/lib_sql.cc:
- cleanup: send_fields flags are now named.
sql/ha_innodb.cc:
- cleanup: send_fields flags are now named.
sql/mysql_priv.h:
- cursors support: declaration for server-side handler of COM_FETCH
sql/protocol.cc:
- cleanup: send_fields flags are now named.
- we can't anymore assert that field_types[field_pos] is sensible:
if we have COM_EXCUTE(stmt1), COM_EXECUTE(stmt2), COM_FETCH(stmt1)
field_types[field_pos] will point to fields of stmt2.
sql/protocol.h:
- cleanup: send_fields flag_s_ are now named.
sql/protocol_cursor.cc:
- cleanup: send_fields flags are now named.
sql/repl_failsafe.cc:
- cleanup: send_fields flags are now named.
sql/slave.cc:
- cleanup: send_fields flags are now named.
sql/sp.cc:
- cleanup: send_fields flags are now named.
sql/sp_head.cc:
- cleanup: send_fields flags are now named.
sql/sql_acl.cc:
- cleanup: send_fields flags are now named.
sql/sql_class.cc:
- cleanup: send_fields flags are now named.
sql/sql_class.h:
- cleanup: send_fields flags are now named.
sql/sql_error.cc:
- cleanup: send_fields flags are now named.
sql/sql_handler.cc:
- cleanup: send_fields flags are now named.
sql/sql_help.cc:
- cleanup: send_fields flags are now named.
sql/sql_parse.cc:
Server side support for cursors:
- handle COM_FETCH
- enforce assumption that whenever we free thd->free_list,
we reset it to zero. This way it's much easier to handle free_list
in prepared statements implementation.
sql/sql_prepare.cc:
Server side support for cursors:
- implementation of mysql_stmt_fetch (fetch some rows from open cursor).
- management of cursors memory is quite tricky now.
- execute_stmt can't be reused anymore in mysql_stmt_execute and
mysql_sql_stmt_execute
sql/sql_repl.cc:
- cleanup: send_fields flags are now named.
sql/sql_select.cc:
Server side support for cursors:
- implementation of Cursor::open, Cursor::fetch (buggy when it comes to
non-equi joins), cursor cleanups.
- -4 -3 -0 constants indicating return value of sub_select and end_send are
to be renamed to something more readable:
it turned out to be not so simple, so it should come with the other patch.
sql/sql_select.h:
Server side support for cursors:
- declaration of Cursor class.
- JOIN::fetch_limit contains runtime value of rows fetched via cursor.
sql/sql_show.cc:
- cleanup: send_fields flags are now named.
sql/sql_table.cc:
- cleanup: send_fields flags are now named.
sql/sql_union.cc:
- if there was a cursor, don't cleanup unit: we'll need it to fetch
the rest of the rows.
tests/Makefile.am:
Now client_test is in C++.
tests/client_test.cc:
A few elementary tests for cursors.
BitKeeper/etc/ignore:
Added libmysqld/examples/client_test.cc to the ignore list
2004-08-03 12:32:21 +02:00
|
|
|
|
2002-12-11 08:17:51 +01:00
|
|
|
bool store(I_List<i_string> *str_list);
|
2003-03-17 10:14:04 +01:00
|
|
|
bool store(const char *from, CHARSET_INFO *cs);
|
2002-12-11 08:17:51 +01:00
|
|
|
String *storage_packet() { return packet; }
|
|
|
|
inline void free() { packet->free(); }
|
2003-09-17 17:48:53 +02:00
|
|
|
virtual bool write();
|
2002-12-11 08:17:51 +01:00
|
|
|
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); }
|
2003-05-29 23:47:31 +02:00
|
|
|
inline bool store(String *str)
|
2003-08-19 15:00:12 +02:00
|
|
|
{ return store((char*) str->ptr(), str->length(), str->charset()); }
|
2002-12-17 16:33:25 +01:00
|
|
|
|
2003-01-15 09:11:44 +01:00
|
|
|
virtual bool prepare_for_send(List<Item> *item_list)
|
|
|
|
{
|
|
|
|
field_count=item_list->elements;
|
|
|
|
return 0;
|
|
|
|
}
|
2004-11-02 19:13:27 +01:00
|
|
|
virtual bool flush();
|
2002-12-11 08:17:51 +01:00
|
|
|
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;
|
2005-02-08 23:50:45 +01:00
|
|
|
virtual bool store_decimal(const my_decimal *)=0;
|
2003-03-17 10:14:04 +01:00
|
|
|
virtual bool store(const char *from, uint length, CHARSET_INFO *cs)=0;
|
2003-04-07 10:52:48 +02:00
|
|
|
virtual bool store(const char *from, uint length,
|
|
|
|
CHARSET_INFO *fromcs, CHARSET_INFO *tocs)=0;
|
2002-12-11 08:17:51 +01:00
|
|
|
virtual bool store(float from, uint32 decimals, String *buffer)=0;
|
|
|
|
virtual bool store(double from, uint32 decimals, String *buffer)=0;
|
|
|
|
virtual bool store(TIME *time)=0;
|
|
|
|
virtual bool store_date(TIME *time)=0;
|
|
|
|
virtual bool store_time(TIME *time)=0;
|
|
|
|
virtual bool store(Field *field)=0;
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
/* Class used for the old (MySQL 4.0 protocol) */
|
|
|
|
|
|
|
|
class Protocol_simple :public Protocol
|
|
|
|
{
|
|
|
|
public:
|
|
|
|
Protocol_simple() {}
|
2003-11-28 11:18:13 +01:00
|
|
|
Protocol_simple(THD *thd_arg) :Protocol(thd_arg) {}
|
2002-12-11 08:17:51 +01:00
|
|
|
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);
|
2005-02-08 23:50:45 +01:00
|
|
|
virtual bool store_decimal(const my_decimal *);
|
2003-03-17 10:14:04 +01:00
|
|
|
virtual bool store(const char *from, uint length, CHARSET_INFO *cs);
|
2003-04-07 10:52:48 +02:00
|
|
|
virtual bool store(const char *from, uint length,
|
|
|
|
CHARSET_INFO *fromcs, CHARSET_INFO *tocs);
|
2002-12-11 08:17:51 +01:00
|
|
|
virtual bool store(TIME *time);
|
|
|
|
virtual bool store_date(TIME *time);
|
|
|
|
virtual bool store_time(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);
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
class Protocol_prep :public Protocol
|
|
|
|
{
|
|
|
|
private:
|
2003-01-15 09:11:44 +01:00
|
|
|
uint bit_fields;
|
2002-12-11 08:17:51 +01:00
|
|
|
public:
|
|
|
|
Protocol_prep() {}
|
2003-11-28 11:18:13 +01:00
|
|
|
Protocol_prep(THD *thd_arg) :Protocol(thd_arg) {}
|
2002-12-11 08:17:51 +01:00
|
|
|
virtual bool prepare_for_send(List<Item> *item_list);
|
|
|
|
virtual void prepare_for_resend();
|
2003-09-17 17:48:53 +02:00
|
|
|
#ifdef EMBEDDED_LIBRARY
|
|
|
|
virtual bool write();
|
2003-09-18 09:25:00 +02:00
|
|
|
bool net_store_data(const char *from, uint length);
|
2003-09-17 17:48:53 +02:00
|
|
|
#endif
|
2002-12-11 08:17:51 +01:00
|
|
|
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);
|
2005-02-08 23:50:45 +01:00
|
|
|
virtual bool store_decimal(const my_decimal *);
|
2003-03-17 10:14:04 +01:00
|
|
|
virtual bool store(const char *from,uint length, CHARSET_INFO *cs);
|
2003-04-07 10:52:48 +02:00
|
|
|
virtual bool store(const char *from, uint length,
|
|
|
|
CHARSET_INFO *fromcs, CHARSET_INFO *tocs);
|
2002-12-11 08:17:51 +01:00
|
|
|
virtual bool store(TIME *time);
|
|
|
|
virtual bool store_date(TIME *time);
|
|
|
|
virtual bool store_time(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);
|
|
|
|
};
|
|
|
|
|
2003-04-23 16:37:33 +02:00
|
|
|
class Protocol_cursor :public Protocol_simple
|
|
|
|
{
|
|
|
|
public:
|
|
|
|
MEM_ROOT *alloc;
|
|
|
|
MYSQL_FIELD *fields;
|
|
|
|
MYSQL_ROWS *data;
|
|
|
|
MYSQL_ROWS **prev_record;
|
|
|
|
ulong row_count;
|
|
|
|
|
2005-06-01 12:18:41 +02:00
|
|
|
Protocol_cursor() :data(NULL) {}
|
|
|
|
Protocol_cursor(THD *thd_arg, MEM_ROOT *ini_alloc) :Protocol_simple(thd_arg), alloc(ini_alloc), data(NULL) {}
|
2003-04-23 16:37:33 +02:00
|
|
|
bool prepare_for_send(List<Item> *item_list)
|
|
|
|
{
|
2003-10-10 16:57:21 +02:00
|
|
|
row_count= 0;
|
2003-04-23 16:37:33 +02:00
|
|
|
fields= NULL;
|
|
|
|
data= NULL;
|
|
|
|
prev_record= &data;
|
|
|
|
return Protocol_simple::prepare_for_send(item_list);
|
|
|
|
}
|
2004-11-03 11:39:38 +01:00
|
|
|
bool send_fields(List<Item> *list, uint flags);
|
2003-04-23 16:37:33 +02:00
|
|
|
bool write();
|
2003-10-10 16:57:21 +02:00
|
|
|
uint get_field_count() { return field_count; }
|
2003-04-23 16:37:33 +02:00
|
|
|
};
|
|
|
|
|
2002-12-11 08:17:51 +01:00
|
|
|
void send_warning(THD *thd, uint sql_errno, const char *err=0);
|
2004-10-20 15:06:54 +02:00
|
|
|
void net_printf_error(THD *thd, uint sql_errno, ...);
|
|
|
|
void net_send_error(THD *thd, uint sql_errno=0, const char *err=0);
|
2002-12-11 08:17:51 +01:00
|
|
|
void send_ok(THD *thd, ha_rows affected_rows=0L, ulonglong id=0L,
|
|
|
|
const char *info=0);
|
2005-06-30 14:17:10 +02:00
|
|
|
void send_eof(THD *thd);
|
2003-07-18 16:25:54 +02:00
|
|
|
bool send_old_password_request(THD *thd);
|
2002-12-11 08:17:51 +01:00
|
|
|
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,int32 from);
|
|
|
|
char *net_store_data(char *to,longlong from);
|
2003-09-17 17:48:53 +02:00
|
|
|
|