Commit 6a83d375 authored by hf@deer.mysql.r18.ru's avatar hf@deer.mysql.r18.ru

Merge abotchkov@bk-internal.mysql.com:/home/bk/mysql-4.1

into deer.mysql.r18.ru:/home/hf/work/mysql-4.1.cursor
parents 6fd764a6 d69b5c4d
......@@ -236,6 +236,7 @@ client/mysqlshow
client/mysqltest
client/mysys_priv.h
client/select_test
client/ssl_test
client/thimble
client/thread_test
cmd-line-utils/libedit/common.h
......@@ -428,6 +429,9 @@ myisam/FT1.MYI
myisam/ft_dump
myisam/ft_eval
myisam/ft_test1
myisam/ftbench/data
myisam/ftbench/t
myisam/ftbench/var/*
myisam/mi_test1
myisam/mi_test2
myisam/mi_test3
......@@ -548,6 +552,7 @@ sql/mysqld-purecov
sql/mysqld-purify
sql/mysqld-quantify
sql/new.cc
sql/pack.c
sql/safe_to_cache_query.txt
sql/share/*.sys
sql/share/charsets/gmon.out
......@@ -602,7 +607,3 @@ vio/test-ssl
vio/test-sslclient
vio/test-sslserver
vio/viotest-ssl
myisam/ftbench/var/*
myisam/ftbench/data
myisam/ftbench/t
client/ssl_test
......@@ -70,7 +70,7 @@ linked_netware_sources:
#avoid recursive make calls in sql directory
linked_server_sources:
cd sql; rm -f mini_client_errors.c;@LN_CP_F@ ../libmysql/errmsg.c mini_client_errors.c
cd sql; rm -f mini_client_errors.c;@LN_CP_F@ ../libmysql/errmsg.c mini_client_errors.c; rm -f pack.c;@LN_CP_F@ ../sql-common/pack.c pack.c
echo timestamp > linked_server_sources
# Create permission databases
......
......@@ -721,6 +721,15 @@ typedef long longlong;
#endif
#endif
#if defined(NO_CLIENT_LONG_LONG)
typedef unsigned long my_ulonglong;
#elif defined (__WIN__)
typedef unsigned __int64 my_ulonglong;
#else
typedef unsigned long long my_ulonglong;
#endif
#ifdef USE_RAID
/*
The following is done with a if to not get problems with pre-processors
......
......@@ -101,6 +101,7 @@ typedef struct st_mysql_field {
typedef char **MYSQL_ROW; /* return data as array of strings */
typedef unsigned int MYSQL_FIELD_OFFSET; /* offset to current field */
#ifndef _global_h
#if defined(NO_CLIENT_LONG_LONG)
typedef unsigned long my_ulonglong;
#elif defined (__WIN__)
......@@ -108,6 +109,7 @@ typedef unsigned __int64 my_ulonglong;
#else
typedef unsigned long long my_ulonglong;
#endif
#endif
#define MYSQL_COUNT_ERROR (~(my_ulonglong) 0)
......
......@@ -330,6 +330,11 @@ void load_defaults(const char *conf_file, const char **groups,
my_bool my_thread_init(void);
void my_thread_end(void);
#ifdef _global_h
ulong STDCALL net_field_length(uchar **packet);
my_ulonglong net_field_length_ll(uchar **packet);
#endif
#ifdef __cplusplus
}
#endif
......
......@@ -36,6 +36,7 @@ link_sources:
ds=`echo $(dbugobjects) | sed "s;\.lo;.c;g"`; \
ms=`echo $(mysysobjects) | sed "s;\.lo;.c;g"`; \
vs=`echo $(vio_objects) | sed "s;\.lo;.c;g"`; \
scs=`echo $(sql_cmn_objects) | sed "s;\.lo;.c;g"`; \
for f in $$ss; do \
rm -f $(srcdir)/$$f; \
@LN_CP_F@ $(srcdir)/../strings/$$f $(srcdir)/$$f; \
......@@ -44,6 +45,10 @@ link_sources:
rm -f $(srcdir)/$$f; \
@LN_CP_F@ $(srcdir)/../vio/$$f $(srcdir)/$$f; \
done; \
for f in $$scs; do \
rm -f $(srcdir)/$$f; \
@LN_CP_F@ $(srcdir)/../sql-common/$$f $(srcdir)/$$f; \
done; \
for f in $(mystringsextra); do \
rm -f $(srcdir)/$$f; \
@LN_CP_F@ $(srcdir)/../strings/$$f $(srcdir)/$$f; \
......
......@@ -63,12 +63,13 @@ mysysobjects1 = my_init.lo my_static.lo my_malloc.lo my_realloc.lo \
my_pread.lo mf_cache.lo md5.lo sha1.lo\
my_getopt.lo my_gethostbyname.lo my_port.lo
sqlobjects = net.lo
sql_cmn_objects = pack.lo
# Not needed in the minimum library
mysysobjects2 = my_lib.lo
mysysobjects = $(mysysobjects1) $(mysysobjects2)
target_libadd = $(mysysobjects) $(mystringsobjects) $(dbugobjects) \
$(vio_objects) $(sqlobjects)
$(sql_cmn_objects) $(vio_objects) $(sqlobjects)
target_ldflags = -version-info @SHARED_LIB_VERSION@
vio_objects= vio.lo viosocket.lo viossl.lo viosslfactories.lo
CLEANFILES = $(target_libadd) $(SHLIBOBJS) \
......@@ -85,6 +86,7 @@ clean-local:
`echo $(dbugobjects) | sed "s;\.lo;.c;g"` \
`echo $(mysysobjects) | sed "s;\.lo;.c;g"` \
`echo $(vio_objects) | sed "s;\.lo;.c;g"` \
`echo $(sql_cmn_objects) | sed "s;\.lo;.c;g"` \
$(CHARSET_SRCS) $(CHARSET_OBJS) \
$(mystringsextra) $(mysysheaders) \
../linked_client_sources net.c
......
......@@ -612,71 +612,6 @@ net_safe_read(MYSQL *mysql)
return len;
}
/* Get the length of next field. Change parameter to point at fieldstart */
static ulong
net_field_length(uchar **packet)
{
reg1 uchar *pos= *packet;
if (*pos < 251)
{
(*packet)++;
return (ulong) *pos;
}
if (*pos == 251)
{
(*packet)++;
return NULL_LENGTH;
}
if (*pos == 252)
{
(*packet)+=3;
return (ulong) uint2korr(pos+1);
}
if (*pos == 253)
{
(*packet)+=4;
return (ulong) uint3korr(pos+1);
}
(*packet)+=9; /* Must be 254 when here */
return (ulong) uint4korr(pos+1);
}
/* Same as above, but returns ulonglong values */
static my_ulonglong
net_field_length_ll(uchar **packet)
{
reg1 uchar *pos= *packet;
if (*pos < 251)
{
(*packet)++;
return (my_ulonglong) *pos;
}
if (*pos == 251)
{
(*packet)++;
return (my_ulonglong) NULL_LENGTH;
}
if (*pos == 252)
{
(*packet)+=3;
return (my_ulonglong) uint2korr(pos+1);
}
if (*pos == 253)
{
(*packet)+=4;
return (my_ulonglong) uint3korr(pos+1);
}
(*packet)+=9; /* Must be 254 when here */
#ifdef NO_CLIENT_LONGLONG
return (my_ulonglong) uint4korr(pos+1);
#else
return (my_ulonglong) uint8korr(pos+1);
#endif
}
static void free_rows(MYSQL_DATA *cur)
{
if (cur)
......@@ -1388,7 +1323,8 @@ read_one_row(MYSQL *mysql,uint fields,MYSQL_ROW row, ulong *lengths)
{
uint field;
ulong pkt_len,len;
uchar *pos,*prev_pos, *end_pos;
uchar *pos, *end_pos;
uchar *prev_pos;
if ((pkt_len=net_safe_read(mysql)) == packet_error)
return -1;
......@@ -1422,7 +1358,7 @@ read_one_row(MYSQL *mysql,uint fields,MYSQL_ROW row, ulong *lengths)
}
if (prev_pos)
*prev_pos=0; /* Terminate prev field */
prev_pos=pos;
prev_pos= pos;
}
row[field]=(char*) prev_pos+1; /* End of last field */
*prev_pos=0; /* Terminate last field */
......@@ -5009,7 +4945,7 @@ static void fetch_results(MYSQL_BIND *param, uint field_type, uchar **row,
{
MYSQL_TIME tm;
length= read_binary_date(&tm,row);
length= read_binary_date(&tm, row);
tm.time_type= MYSQL_TIMESTAMP_DATE;
send_data_time(param, tm, length);
break;
......
#include <my_global.h>
#include <mysql_com.h>
#include <mysql.h>
/* Get the length of next field. Change parameter to point at fieldstart */
ulong STDCALL net_field_length(uchar **packet)
{
reg1 uchar *pos= (uchar *)*packet;
if (*pos < 251)
{
(*packet)++;
return (ulong) *pos;
}
if (*pos == 251)
{
(*packet)++;
return NULL_LENGTH;
}
if (*pos == 252)
{
(*packet)+=3;
return (ulong) uint2korr(pos+1);
}
if (*pos == 253)
{
(*packet)+=4;
return (ulong) uint3korr(pos+1);
}
(*packet)+=9; /* Must be 254 when here */
return (ulong) uint4korr(pos+1);
}
/* The same as above but returns longlong */
my_ulonglong net_field_length_ll(uchar **packet)
{
reg1 uchar *pos= *packet;
if (*pos < 251)
{
(*packet)++;
return (my_ulonglong) *pos;
}
if (*pos == 251)
{
(*packet)++;
return (my_ulonglong) NULL_LENGTH;
}
if (*pos == 252)
{
(*packet)+=3;
return (my_ulonglong) uint2korr(pos+1);
}
if (*pos == 253)
{
(*packet)+=4;
return (my_ulonglong) uint3korr(pos+1);
}
(*packet)+=9; /* Must be 254 when here */
#ifdef NO_CLIENT_LONGLONG
return (my_ulonglong) uint4korr(pos+1);
#else
return (my_ulonglong) uint8korr(pos+1);
#endif
}
......@@ -83,9 +83,9 @@ mysqld_SOURCES = sql_lex.cc sql_handler.cc \
sql_load.cc mf_iocache.cc field_conv.cc sql_show.cc \
sql_udf.cc sql_analyse.cc sql_analyse.h sql_cache.cc \
slave.cc sql_repl.cc sql_union.cc sql_derived.cc \
mini_client.cc mini_client_errors.c \
mini_client.cc mini_client_errors.c pack.c\
stacktrace.c repl_failsafe.h repl_failsafe.cc sql_olap.cc\
gstream.cc spatial.cc sql_help.cc
gstream.cc spatial.cc sql_help.cc protocol_cursor.cc
gen_lex_hash_SOURCES = gen_lex_hash.cc
gen_lex_hash_LDADD = $(LDADD) $(CXXLDFLAGS)
......@@ -102,6 +102,8 @@ AM_YFLAGS = -d
link_sources:
rm -f mini_client_errors.c
@LN_CP_F@ ../libmysql/errmsg.c mini_client_errors.c
rm -f pack.c
@LN_CP_F@ ../sql-common/pack.c pack.c
gen_lex_hash.o: gen_lex_hash.cc lex.h
$(CXXCOMPILE) -c $(INCLUDES) $<
......
......@@ -23,6 +23,7 @@
*/
#include <my_global.h>
#ifdef HAVE_EXTERNAL_CLIENT
/* my_pthread must be included early to be able to fix things */
......@@ -80,8 +81,6 @@ void mc_end_server(MYSQL *mysql);
static int mc_sock_connect(File s, const struct sockaddr *name, uint namelen, uint to);
static void mc_free_old_query(MYSQL *mysql);
static int mc_send_file_to_server(MYSQL *mysql, const char *filename);
static my_ulonglong mc_net_field_length_ll(uchar **packet);
static ulong mc_net_field_length(uchar **packet);
static int mc_read_one_row(MYSQL *mysql,uint fields,MYSQL_ROW row,
ulong *lengths);
static MYSQL_DATA *mc_read_rows(MYSQL *mysql,MYSQL_FIELD *mysql_fields,
......@@ -1085,15 +1084,15 @@ int mc_mysql_read_query_result(MYSQL *mysql)
mc_free_old_query(mysql); /* Free old result */
get_info:
pos=(uchar*) mysql->net.read_pos;
if ((field_count= mc_net_field_length(&pos)) == 0)
if ((field_count= net_field_length(&pos)) == 0)
{
mysql->affected_rows= mc_net_field_length_ll(&pos);
mysql->insert_id= mc_net_field_length_ll(&pos);
mysql->affected_rows= net_field_length_ll(&pos);
mysql->insert_id= net_field_length_ll(&pos);
if (mysql->server_capabilities & CLIENT_TRANSACTIONS)
{
mysql->server_status=uint2korr(pos); pos+=2;
}
if (pos < mysql->net.read_pos+length && mc_net_field_length(&pos))
if (pos < mysql->net.read_pos+length && net_field_length(&pos))
mysql->info=(char*) pos;
DBUG_RETURN(0);
}
......@@ -1107,7 +1106,7 @@ int mc_mysql_read_query_result(MYSQL *mysql)
if (!(mysql->server_status & SERVER_STATUS_AUTOCOMMIT))
mysql->server_status|= SERVER_STATUS_IN_TRANS;
mysql->extra_info= mc_net_field_length_ll(&pos); /* Maybe number of rec */
mysql->extra_info= net_field_length_ll(&pos); /* Maybe number of rec */
if (!(fields=mc_read_rows(mysql,(MYSQL_FIELD*) 0,5)))
DBUG_RETURN(-1);
if (!(mysql->fields=mc_unpack_fields(fields,&mysql->field_alloc,
......@@ -1190,68 +1189,6 @@ static int mc_send_file_to_server(MYSQL *mysql, const char *filename)
DBUG_RETURN(result);
}
/* Get the length of next field. Change parameter to point at fieldstart */
static ulong mc_net_field_length(uchar **packet)
{
reg1 uchar *pos= *packet;
if (*pos < 251)
{
(*packet)++;
return (ulong) *pos;
}
if (*pos == 251)
{
(*packet)++;
return NULL_LENGTH;
}
if (*pos == 252)
{
(*packet)+=3;
return (ulong) uint2korr(pos+1);
}
if (*pos == 253)
{
(*packet)+=4;
return (ulong) uint3korr(pos+1);
}
(*packet)+=9; /* Must be 254 when here */
return (ulong) uint4korr(pos+1);
}
/* Same as above, but returns ulonglong values */
static my_ulonglong mc_net_field_length_ll(uchar **packet)
{
reg1 uchar *pos= *packet;
if (*pos < 251)
{
(*packet)++;
return (my_ulonglong) *pos;
}
if (*pos == 251)
{
(*packet)++;
return (my_ulonglong) NULL_LENGTH;
}
if (*pos == 252)
{
(*packet)+=3;
return (my_ulonglong) uint2korr(pos+1);
}
if (*pos == 253)
{
(*packet)+=4;
return (my_ulonglong) uint3korr(pos+1);
}
(*packet)+=9; /* Must be 254 when here */
#ifdef NO_CLIENT_LONGLONG
return (my_ulonglong) uint4korr(pos+1);
#else
return (my_ulonglong) uint8korr(pos+1);
#endif
}
/* Read all rows (fields or data) from server */
static MYSQL_DATA *mc_read_rows(MYSQL *mysql,MYSQL_FIELD *mysql_fields,
......@@ -1301,7 +1238,7 @@ static MYSQL_DATA *mc_read_rows(MYSQL *mysql,MYSQL_FIELD *mysql_fields,
to= (char*) (cur->data+fields+1);
for (field=0 ; field < fields ; field++)
{
if ((len=(ulong) mc_net_field_length(&cp)) == NULL_LENGTH)
if ((len=(ulong) net_field_length(&cp)) == NULL_LENGTH)
{ /* null field */
cur->data[field] = 0;
}
......@@ -1342,7 +1279,8 @@ static int mc_read_one_row(MYSQL *mysql,uint fields,MYSQL_ROW row,
{
uint field;
ulong pkt_len,len;
uchar *pos,*prev_pos;
uchar *pos;
uchar *prev_pos;
if ((pkt_len=mc_net_safe_read(mysql)) == packet_error)
return -1;
......@@ -1352,7 +1290,7 @@ static int mc_read_one_row(MYSQL *mysql,uint fields,MYSQL_ROW row,
pos=mysql->net.read_pos;
for (field=0 ; field < fields ; field++)
{
if ((len=(ulong) mc_net_field_length(&pos)) == NULL_LENGTH)
if ((len=(ulong) net_field_length(&pos)) == NULL_LENGTH)
{ /* null field */
row[field] = 0;
*lengths++=0;
......@@ -1365,7 +1303,7 @@ static int mc_read_one_row(MYSQL *mysql,uint fields,MYSQL_ROW row,
}
if (prev_pos)
*prev_pos=0; /* Terminate prev field */
prev_pos=pos;
prev_pos= pos;
}
row[field]=(char*) prev_pos+1; /* End of last field */
*prev_pos=0; /* Terminate last field */
......
......@@ -22,9 +22,9 @@
class i_string;
class THD;
#ifdef EMBEDDED_LIBRARY
typedef struct st_mysql_field MYSQL_FIELD;
#endif
typedef struct st_mysql_rows MYSQL_ROWS;
class Protocol
{
protected:
......@@ -135,6 +135,28 @@ class Protocol_prep :public Protocol
virtual bool store(Field *field);
};
class Protocol_cursor :public Protocol_simple
{
public:
MEM_ROOT *alloc;
MYSQL_FIELD *fields;
MYSQL_ROWS *data;
MYSQL_ROWS **prev_record;
ulong row_count;
Protocol_cursor() {}
Protocol_cursor(THD *thd, MEM_ROOT *ini_alloc) :Protocol_simple(thd), alloc(ini_alloc) {}
bool prepare_for_send(List<Item> *item_list)
{
fields= NULL;
data= NULL;
prev_record= &data;
return Protocol_simple::prepare_for_send(item_list);
}
bool send_fields(List<Item> *list, uint flag);
bool write();
};
void send_warning(THD *thd, uint sql_errno, const char *err=0);
void net_printf(THD *thd,uint sql_errno, ...);
void send_ok(THD *thd, ha_rows affected_rows=0L, ulonglong id=0L,
......
/* Copyright (C) 2000-2003 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; 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 */
/*
Low level functions for storing data to be send to the MySQL client
The actual communction is handled by the net_xxx functions in net_serv.cc
*/
#ifdef __GNUC__
#pragma implementation // gcc: Class implementation
#endif
#include "mysql_priv.h"
#include <mysql.h>
bool Protocol_cursor::send_fields(List<Item> *list, uint flag)
{
List_iterator_fast<Item> it(*list);
Item *item;
MYSQL_FIELD *field, *client_field;
DBUG_ENTER("send_fields");
if (prepare_for_send(list))
return FALSE;
fields= (MYSQL_FIELD *)alloc_root(alloc, sizeof(MYSQL_FIELD) * field_count);
if (!fields)
goto err;
client_field= fields;
while ((item= it++))
{
Send_field server_field;
item->make_field(&server_field);
client_field->db= strdup_root(alloc, server_field.db_name);
client_field->table= strdup_root(alloc, server_field.table_name);
client_field->name= strdup_root(alloc, server_field.col_name);
client_field->org_table= strdup_root(alloc, server_field.org_table_name);
client_field->org_name= strdup_root(alloc, server_field.org_col_name);
client_field->length= server_field.length;
client_field->type= server_field.type;
client_field->flags= server_field.flags;
client_field->decimals= server_field.decimals;
client_field->db_length= strlen(client_field->db);
client_field->table_length= strlen(client_field->table);
client_field->name_length= strlen(client_field->name);
client_field->org_name_length= strlen(client_field->org_name);
client_field->org_table_length= strlen(client_field->org_table);
client_field->charsetnr= server_field.charsetnr;
if (INTERNAL_NUM_FIELD(client_field))
client_field->flags|= NUM_FLAG;
if (flag & 2)
{
char buff[80];
String tmp(buff, sizeof(buff), default_charset_info), *res;
if (!(res=item->val_str(&tmp)))
client_field->def= strdup_root(alloc, "");
else
client_field->def= strdup_root(alloc, tmp.ptr());
}
else
client_field->def=0;
client_field->max_length= 0;
++client_field;
}
DBUG_RETURN(FALSE);
err:
send_error(thd, ER_OUT_OF_RESOURCES); /* purecov: inspected */
DBUG_RETURN(TRUE); /* purecov: inspected */
}
/* Get the length of next field. Change parameter to point at fieldstart */
bool Protocol_cursor::write()
{
byte *cp= (byte *)packet->ptr();
byte *end_pos= (byte *)packet->ptr() + packet->length();
ulong len;
MYSQL_FIELD *cur_field= fields;
MYSQL_FIELD *fields_end= fields + field_count;
MYSQL_ROWS *new_record;
byte **data;
byte *to;
new_record= (MYSQL_ROWS *)alloc_root(alloc,
sizeof(MYSQL_ROWS) + (field_count + 1)*sizeof(char *) + packet->length());
if (!new_record)
goto err;
data= (byte **)(new_record + 1);
new_record->data= (char **)data;
to= (byte *)(fields + field_count + 1);
for (; cur_field < fields_end; ++cur_field, ++data)
{
if ((len=net_field_length((uchar **)&cp)))
{
*data= 0;
}
else
{
if ((long)len > (end_pos - cp))
{
// TODO error signal send_error(thd, CR_MALFORMED_PACKET);
return TRUE;
}
memcpy(to,(char*) cp,len);
to[len]=0;
to+=len+1;
cp+=len;
if (cur_field->max_length < len)
cur_field->max_length=len;
}
}
*prev_record= new_record;
prev_record= &new_record->next;
new_record->next= NULL;
row_count++;
return FALSE;
err:
// TODO error signal send_error(thd, ER_OUT_OF_RESOURCES);
return TRUE;
}
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment