Commit 5f64e3e8 authored by unknown's avatar unknown

Added charset number to result header


Docs/internals.texi:
  Updated protocol information
sql/mysql_priv.h:
  Removed clear_error_message()
sql/mysqld.cc:
  Removed not used function clear_error_message
sql/protocol.cc:
  Simple code cleanup
sql/sql_parse.cc:
  Changed clear_error_message() to thd->clear_error()
  Simple optimization.
parent b58dd39b
...@@ -1719,9 +1719,16 @@ The field description result set contains the meta info for a result set. ...@@ -1719,9 +1719,16 @@ The field description result set contains the meta info for a result set.
@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:
@itemize
@item 2 byte int @tab Character set number
@item 3 byte int @tab Length of column definition @item 3 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)
@end itemize
@item string int @tab Default value, only set when using mysql_list_fields(). @item string int @tab Default value, only set when using mysql_list_fields().
@end multitable @end multitable
......
...@@ -84,6 +84,7 @@ typedef struct st_mysql_field { ...@@ -84,6 +84,7 @@ typedef struct st_mysql_field {
unsigned long max_length; /* Max width of selected set */ unsigned long max_length; /* Max width of selected set */
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 */
unsigned int charsetnr; /* Character set */
enum enum_field_types type; /* Type of field. Se mysql_com.h for types */ enum enum_field_types type; /* Type of field. Se mysql_com.h for types */
} MYSQL_FIELD; } MYSQL_FIELD;
......
...@@ -1150,25 +1150,29 @@ unpack_fields(MYSQL_DATA *data,MEM_ROOT *alloc,uint fields, ...@@ -1150,25 +1150,29 @@ unpack_fields(MYSQL_DATA *data,MEM_ROOT *alloc,uint fields,
free_rows(data); /* Free old data */ free_rows(data); /* Free old data */
DBUG_RETURN(0); DBUG_RETURN(0);
} }
bzero((char*) field, (uint) sizeof(MYSQL_FIELD)*fields);
if (server_capabilities & CLIENT_PROTOCOL_41) if (server_capabilities & CLIENT_PROTOCOL_41)
{ {
/* server is 4.1, and returns the new field result format */ /* server is 4.1, and returns the new field result format */
for (row=data->data; row ; row = row->next,field++) for (row=data->data; row ; row = row->next,field++)
{ {
uchar *pos;
field->db = strdup_root(alloc,(char*) row->data[0]); field->db = strdup_root(alloc,(char*) row->data[0]);
field->table = strdup_root(alloc,(char*) row->data[1]); field->table = strdup_root(alloc,(char*) row->data[1]);
field->org_table= strdup_root(alloc,(char*) row->data[2]); field->org_table= strdup_root(alloc,(char*) row->data[2]);
field->name = strdup_root(alloc,(char*) row->data[3]); field->name = strdup_root(alloc,(char*) row->data[3]);
field->org_name = strdup_root(alloc,(char*) row->data[4]); field->org_name = strdup_root(alloc,(char*) row->data[4]);
field->length = (uint) uint3korr(row->data[5]); /* Unpack fixed length parts */
field->type = (enum enum_field_types) (uchar) row->data[6][0]; pos= (uchar*) row->data[5];
field->charsetnr= uint2korr(pos);
field->flags= uint2korr(row->data[7]); field->length= (uint) uint3korr(pos+2);
field->decimals=(uint) (uchar) row->data[7][2]; field->type= (enum enum_field_types) pos[5];
field->flags= uint2korr(pos+6);
field->decimals= (uint) pos[8];
if (INTERNAL_NUM_FIELD(field)) if (INTERNAL_NUM_FIELD(field))
field->flags|= NUM_FLAG; field->flags|= NUM_FLAG;
if (default_value && row->data[8]) if (default_value && row->data[6])
field->def=strdup_root(alloc,(char*) row->data[8]); field->def=strdup_root(alloc,(char*) row->data[8]);
else else
field->def=0; field->def=0;
...@@ -2841,7 +2845,7 @@ get_info: ...@@ -2841,7 +2845,7 @@ get_info:
mysql->extra_info= net_field_length_ll(&pos); /* Maybe number of rec */ mysql->extra_info= net_field_length_ll(&pos); /* Maybe number of rec */
if (!(fields=read_rows(mysql,(MYSQL_FIELD*)0, (protocol_41(mysql) ? 8 : 5)))) if (!(fields=read_rows(mysql,(MYSQL_FIELD*)0, 5)))
DBUG_RETURN(1); DBUG_RETURN(1);
if (!(mysql->fields=unpack_fields(fields,&mysql->field_alloc, if (!(mysql->fields=unpack_fields(fields,&mysql->field_alloc,
(uint) field_count,0, (uint) field_count,0,
...@@ -3212,8 +3216,7 @@ mysql_list_fields(MYSQL *mysql, const char *table, const char *wild) ...@@ -3212,8 +3216,7 @@ mysql_list_fields(MYSQL *mysql, const char *table, const char *wild)
end=strmake(strmake(buff, table,128)+1,wild ? wild : "",128); end=strmake(strmake(buff, table,128)+1,wild ? wild : "",128);
if (simple_command(mysql,COM_FIELD_LIST,buff,(ulong) (end-buff),1) || if (simple_command(mysql,COM_FIELD_LIST,buff,(ulong) (end-buff),1) ||
!(query = read_rows(mysql,(MYSQL_FIELD*) 0, !(query = read_rows(mysql,(MYSQL_FIELD*) 0, 6)))
(protocol_41(mysql) ? 9 : 6))))
DBUG_RETURN(NULL); DBUG_RETURN(NULL);
free_old_query(mysql); free_old_query(mysql);
...@@ -3250,7 +3253,7 @@ mysql_list_processes(MYSQL *mysql) ...@@ -3250,7 +3253,7 @@ mysql_list_processes(MYSQL *mysql)
free_old_query(mysql); free_old_query(mysql);
pos=(uchar*) mysql->net.read_pos; pos=(uchar*) mysql->net.read_pos;
field_count=(uint) net_field_length(&pos); field_count=(uint) net_field_length(&pos);
if (!(fields = read_rows(mysql,(MYSQL_FIELD*)0,protocol_41(mysql) ? 8: 5))) if (!(fields = read_rows(mysql,(MYSQL_FIELD*) 0, 5)))
DBUG_RETURN(NULL); DBUG_RETURN(NULL);
if (!(mysql->fields=unpack_fields(fields,&mysql->field_alloc,field_count,0, if (!(mysql->fields=unpack_fields(fields,&mysql->field_alloc,field_count,0,
mysql->server_capabilities))) mysql->server_capabilities)))
......
...@@ -223,6 +223,7 @@ void Field_num::make_field(Send_field *field) ...@@ -223,6 +223,7 @@ void Field_num::make_field(Send_field *field)
field->org_table_name=table->real_name; field->org_table_name=table->real_name;
field->table_name=table_name; field->table_name=table_name;
field->col_name=field->org_col_name=field_name; field->col_name=field->org_col_name=field_name;
field->charsetnr= charset()->number;
field->length=field_length; field->length=field_length;
field->type=type(); field->type=type();
field->flags=table->maybe_null ? (flags & ~NOT_NULL_FLAG) : flags; field->flags=table->maybe_null ? (flags & ~NOT_NULL_FLAG) : flags;
...@@ -237,6 +238,7 @@ void Field_str::make_field(Send_field *field) ...@@ -237,6 +238,7 @@ void Field_str::make_field(Send_field *field)
field->org_table_name=table->real_name; field->org_table_name=table->real_name;
field->table_name=table_name; field->table_name=table_name;
field->col_name=field->org_col_name=field_name; field->col_name=field->org_col_name=field_name;
field->charsetnr= charset()->number;
field->length=field_length; field->length=field_length;
field->type=type(); field->type=type();
field->flags=table->maybe_null ? (flags & ~NOT_NULL_FLAG) : flags; field->flags=table->maybe_null ? (flags & ~NOT_NULL_FLAG) : flags;
......
...@@ -1056,7 +1056,8 @@ class Send_field { ...@@ -1056,7 +1056,8 @@ class Send_field {
const char *db_name; const char *db_name;
const char *table_name,*org_table_name; const char *table_name,*org_table_name;
const char *col_name,*org_col_name; const char *col_name,*org_col_name;
uint length,flags,decimals; ulong length;
uint charsetnr, flags, decimals;
enum_field_types type; enum_field_types type;
Send_field() {} Send_field() {}
}; };
......
...@@ -685,11 +685,13 @@ bool Item_field::fix_fields(THD *thd, TABLE_LIST *tables, Item **ref) ...@@ -685,11 +685,13 @@ bool Item_field::fix_fields(THD *thd, TABLE_LIST *tables, Item **ref)
void Item::init_make_field(Send_field *tmp_field, void Item::init_make_field(Send_field *tmp_field,
enum enum_field_types field_type) enum enum_field_types field_type)
{ {
tmp_field->db_name=(char*) ""; char *empty_name= (char*) "";
tmp_field->org_table_name=(char*) ""; tmp_field->db_name= empty_name;
tmp_field->org_col_name=(char*) ""; tmp_field->org_table_name= empty_name;
tmp_field->table_name=(char*) ""; tmp_field->org_col_name= empty_name;
tmp_field->col_name=name; tmp_field->table_name= empty_name;
tmp_field->col_name= name;
tmp_field->charsetnr= charset()->number;
tmp_field->flags=maybe_null ? 0 : NOT_NULL_FLAG; tmp_field->flags=maybe_null ? 0 : NOT_NULL_FLAG;
tmp_field->type=field_type; tmp_field->type=field_type;
tmp_field->length=max_length; tmp_field->length=max_length;
......
...@@ -654,8 +654,6 @@ bool open_log(MYSQL_LOG *log, const char *hostname, ...@@ -654,8 +654,6 @@ bool open_log(MYSQL_LOG *log, const char *hostname,
const char *index_file_name, const char *index_file_name,
enum_log_type type, bool read_append = 0, enum_log_type type, bool read_append = 0,
bool no_auto_events = 0); bool no_auto_events = 0);
/* mysqld.cc */
void clear_error_message(THD *thd);
/* /*
External variables External variables
......
...@@ -1736,17 +1736,6 @@ extern "C" int my_message_sql(uint error, const char *str, ...@@ -1736,17 +1736,6 @@ extern "C" int my_message_sql(uint error, const char *str,
DBUG_RETURN(0); DBUG_RETURN(0);
} }
/*
Forget last error message (if we got one)
*/
void clear_error_message(THD *thd)
{
thd->clear_error();
}
#ifdef __WIN__ #ifdef __WIN__
struct utsname struct utsname
......
...@@ -132,6 +132,7 @@ void net_send_error(NET *net, uint sql_errno, const char *err) ...@@ -132,6 +132,7 @@ void net_send_error(NET *net, uint sql_errno, const char *err)
} }
#endif #endif
/* /*
Send a warning to the end user Send a warning to the end user
...@@ -284,8 +285,8 @@ void my_net_local_init(NET *net __attribute__(unused)) ...@@ -284,8 +285,8 @@ void my_net_local_init(NET *net __attribute__(unused))
If net->no_send_ok return without sending packet If net->no_send_ok return without sending packet
*/ */
#ifndef EMBEDDED_LIBRARY
#ifndef EMBEDDED_LIBRARY
void void
send_ok(THD *thd, ha_rows affected_rows, ulonglong id, const char *message) send_ok(THD *thd, ha_rows affected_rows, ulonglong id, const char *message)
{ {
...@@ -375,7 +376,6 @@ send_eof(THD *thd, bool no_flush) ...@@ -375,7 +376,6 @@ send_eof(THD *thd, bool no_flush)
/**************************************************************************** /****************************************************************************
Store a field length in logical packet Store a field length in logical packet
This is used to code the string length for normal protocol This is used to code the string length for normal protocol
****************************************************************************/ ****************************************************************************/
...@@ -457,9 +457,6 @@ char *net_store_data(char *to,longlong from) ...@@ -457,9 +457,6 @@ char *net_store_data(char *to,longlong from)
return to+length; return to+length;
} }
/*
Function called by my_net_init() to set some check variables
*/
/***************************************************************************** /*****************************************************************************
Default Protocol functions Default Protocol functions
...@@ -475,6 +472,7 @@ void Protocol::init(THD *thd_arg) ...@@ -475,6 +472,7 @@ void Protocol::init(THD *thd_arg)
#endif #endif
} }
/* /*
Send name and type of result to client. Send name and type of result to client.
...@@ -534,35 +532,55 @@ bool Protocol::send_fields(List<Item> *list, uint flag) ...@@ -534,35 +532,55 @@ bool Protocol::send_fields(List<Item> *list, uint flag)
prot.store(field.org_table_name, prot.store(field.org_table_name,
(uint) strlen(field.org_table_name)) || (uint) strlen(field.org_table_name)) ||
prot.store(field.col_name, (uint) strlen(field.col_name)) || prot.store(field.col_name, (uint) strlen(field.col_name)) ||
prot.store(field.org_col_name, (uint) strlen(field.org_col_name))) prot.store(field.org_col_name, (uint) strlen(field.org_col_name)) ||
packet->realloc(packet->length()+12))
goto err; goto err;
/* Store fixed length fields */
pos= (char*) packet->ptr()+packet->length();
*pos++= 11; // Length of packed fields
int2store(pos, field.charsetnr);
int3store(pos+2, field.length);
pos[5]= field.type;
int2store(pos+6,field.flags);
pos[8]= (char) field.decimals;
pos[9]= 0; // For the future
pos[10]= 0; // For the future
pos+= 11;
} }
else else
{ {
if (prot.store(field.table_name, (uint) strlen(field.table_name)) || if (prot.store(field.table_name, (uint) strlen(field.table_name)) ||
prot.store(field.col_name, (uint) strlen(field.col_name))) prot.store(field.col_name, (uint) strlen(field.col_name)) ||
goto err; packet->realloc(packet->length()+10))
}
if (packet->realloc(packet->length()+10))
goto err; goto err;
pos= (char*) packet->ptr()+packet->length(); pos= (char*) packet->ptr()+packet->length();
#ifdef TO_BE_DELETED_IN_6 #ifdef TO_BE_DELETED_IN_6
if (!(thd->client_capabilities & CLIENT_LONG_FLAG)) if (!(thd->client_capabilities & CLIENT_LONG_FLAG))
{ {
packet->length(packet->length()+9); pos[0]=3;
pos[0]=3; int3store(pos+1,field.length); int3store(pos+1,field.length);
pos[4]=1; pos[5]=field.type; pos[4]=1;
pos[6]=2; pos[7]=(char) field.flags; pos[8]= (char) field.decimals; pos[5]=field.type;
pos[6]=2;
pos[7]= (char) field.flags;
pos[8]= (char) field.decimals;
pos+= 9;
} }
else else
#endif #endif
{ {
packet->length(packet->length()+10); pos[0]=3;
pos[0]=3; int3store(pos+1,field.length); int3store(pos+1,field.length);
pos[4]=1; pos[5]=field.type; pos[4]=1;
pos[6]=3; int2store(pos+7,field.flags); pos[9]= (char) field.decimals; pos[5]=field.type;
pos[6]=3;
int2store(pos+7,field.flags);
pos[9]= (char) field.decimals;
pos+= 10;
}
} }
packet->length((uint) (pos - packet->ptr()));
if (flag & 2) if (flag & 2)
item->send(&prot, &tmp); // Send default value item->send(&prot, &tmp); // Send default value
if (prot.write()) if (prot.write())
...@@ -580,6 +598,7 @@ err: ...@@ -580,6 +598,7 @@ err:
DBUG_RETURN(1); /* purecov: inspected */ DBUG_RETURN(1); /* purecov: inspected */
} }
bool Protocol::send_records_num(List<Item> *list, ulonglong records) bool Protocol::send_records_num(List<Item> *list, ulonglong records)
{ {
char *pos; char *pos;
...@@ -589,13 +608,12 @@ bool Protocol::send_records_num(List<Item> *list, ulonglong records) ...@@ -589,13 +608,12 @@ bool Protocol::send_records_num(List<Item> *list, ulonglong records)
return my_net_write(&thd->net, buff,(uint) (pos-buff)); return my_net_write(&thd->net, buff,(uint) (pos-buff));
} }
bool Protocol::write() bool Protocol::write()
{ {
DBUG_ENTER("Protocol::write"); DBUG_ENTER("Protocol::write");
DBUG_RETURN(my_net_write(&thd->net, packet->ptr(), packet->length())); DBUG_RETURN(my_net_write(&thd->net, packet->ptr(), packet->length()));
} }
#endif /* EMBEDDED_LIBRARY */ #endif /* EMBEDDED_LIBRARY */
...@@ -653,7 +671,6 @@ bool Protocol::store(I_List<i_string>* str_list) ...@@ -653,7 +671,6 @@ bool Protocol::store(I_List<i_string>* str_list)
and client when you are not using prepared statements. and client when you are not using prepared statements.
All data are sent as 'packed-string-length' followed by 'string-data' All data are sent as 'packed-string-length' followed by 'string-data'
****************************************************************************/ ****************************************************************************/
#ifndef EMBEDDED_LIBRARY #ifndef EMBEDDED_LIBRARY
...@@ -676,6 +693,7 @@ bool Protocol_simple::store_null() ...@@ -676,6 +693,7 @@ bool Protocol_simple::store_null()
} }
#endif #endif
bool Protocol_simple::store(const char *from, uint length) bool Protocol_simple::store(const char *from, uint length)
{ {
#ifndef DEBUG_OFF #ifndef DEBUG_OFF
...@@ -701,6 +719,7 @@ bool Protocol_simple::store_tiny(longlong from) ...@@ -701,6 +719,7 @@ bool Protocol_simple::store_tiny(longlong from)
(uint) (int10_to_str((int) from,buff, -10)-buff)); (uint) (int10_to_str((int) from,buff, -10)-buff));
} }
bool Protocol_simple::store_short(longlong from) bool Protocol_simple::store_short(longlong from)
{ {
#ifndef DEBUG_OFF #ifndef DEBUG_OFF
...@@ -712,6 +731,7 @@ bool Protocol_simple::store_short(longlong from) ...@@ -712,6 +731,7 @@ bool Protocol_simple::store_short(longlong from)
(uint) (int10_to_str((int) from,buff, -10)-buff)); (uint) (int10_to_str((int) from,buff, -10)-buff));
} }
bool Protocol_simple::store_long(longlong from) bool Protocol_simple::store_long(longlong from)
{ {
#ifndef DEBUG_OFF #ifndef DEBUG_OFF
...@@ -747,6 +767,7 @@ bool Protocol_simple::store(float from, uint32 decimals, String *buffer) ...@@ -747,6 +767,7 @@ bool Protocol_simple::store(float from, uint32 decimals, String *buffer)
return net_store_data((char*) buffer->ptr(), buffer->length()); return net_store_data((char*) buffer->ptr(), buffer->length());
} }
bool Protocol_simple::store(double from, uint32 decimals, String *buffer) bool Protocol_simple::store(double from, uint32 decimals, String *buffer)
{ {
#ifndef DEBUG_OFF #ifndef DEBUG_OFF
...@@ -833,17 +854,18 @@ bool Protocol_simple::store_time(TIME *tm) ...@@ -833,17 +854,18 @@ bool Protocol_simple::store_time(TIME *tm)
Data format: Data format:
[ok:1] <-- reserved ok packet [ok:1] reserved ok packet
[null_field:(field_count+7+2)/8] <-- reserved to send null data. The size is [null_field:(field_count+7+2)/8] reserved to send null data. The size is
calculated using: calculated using:
bit_fields= (field_count+7+2)/8; bit_fields= (field_count+7+2)/8;
2 bits are reserved 2 bits are reserved for identifying type
[[length]data] <-- data field (the length applies only for of package.
[[length]data] data field (the length applies only for
string/binary/time/timestamp fields and string/binary/time/timestamp fields and
rest of them are not sent as they have rest of them are not sent as they have
the default length that client understands the default length that client understands
based on the field type based on the field type
[..]..[[length]data] <-- data [..]..[[length]data] data
****************************************************************************/ ****************************************************************************/
bool Protocol_prep::prepare_for_send(List<Item> *item_list) bool Protocol_prep::prepare_for_send(List<Item> *item_list)
...@@ -983,7 +1005,7 @@ bool Protocol_prep::store(double from, uint32 decimals, String *buffer) ...@@ -983,7 +1005,7 @@ bool Protocol_prep::store(double from, uint32 decimals, String *buffer)
bool Protocol_prep::store(Field *field) bool Protocol_prep::store(Field *field)
{ {
/* /*
We should not count up field_pos here as send_binary() will call another We should not increment field_pos here as send_binary() will call another
protocol function to do this for us protocol function to do this for us
*/ */
if (field->is_null()) if (field->is_null())
...@@ -1057,10 +1079,3 @@ bool Protocol_prep::store_time(TIME *tm) ...@@ -1057,10 +1079,3 @@ bool Protocol_prep::store_time(TIME *tm)
buff[0]=(char) length; // Length is stored first buff[0]=(char) length; // Length is stored first
return packet->append(buff, length+1, PACKET_BUFFET_EXTRA_ALLOC); return packet->append(buff, length+1, PACKET_BUFFET_EXTRA_ALLOC);
} }
#if 0
bool Protocol_prep::send_fields(List<Item> *list, uint flag)
{
return prepare_for_send(list);
};
#endif
...@@ -1069,7 +1069,7 @@ bool dispatch_command(enum enum_server_command command, THD *thd, ...@@ -1069,7 +1069,7 @@ bool dispatch_command(enum enum_server_command command, THD *thd,
case COM_CHANGE_USER: case COM_CHANGE_USER:
{ {
thd->change_user(); thd->change_user();
clear_error_message(thd); // If errors from rollback thd->clear_error(); // If errors from rollback
statistic_increment(com_other,&LOCK_status); statistic_increment(com_other,&LOCK_status);
char *user= (char*) packet; char *user= (char*) packet;
...@@ -1210,7 +1210,7 @@ bool dispatch_command(enum enum_server_command command, THD *thd, ...@@ -1210,7 +1210,7 @@ bool dispatch_command(enum enum_server_command command, THD *thd,
DBUG_PRINT("query",("%-.4096s",thd->query)); DBUG_PRINT("query",("%-.4096s",thd->query));
mysql_parse(thd,thd->query, thd->query_length); mysql_parse(thd,thd->query, thd->query_length);
while (!thd->fatal_error && thd->lex.found_colon) while (!thd->killed && !thd->fatal_error && thd->lex.found_colon)
{ {
char *packet= thd->lex.found_colon; char *packet= thd->lex.found_colon;
/* /*
...@@ -1229,7 +1229,6 @@ bool dispatch_command(enum enum_server_command command, THD *thd, ...@@ -1229,7 +1229,6 @@ bool dispatch_command(enum enum_server_command command, THD *thd,
} }
thd->query_length= length; thd->query_length= length;
thd->query= packet; thd->query= packet;
thd->net.last_error[0]= '\0';
VOID(pthread_mutex_lock(&LOCK_thread_count)); VOID(pthread_mutex_lock(&LOCK_thread_count));
thd->query_id= query_id++; thd->query_id= query_id++;
VOID(pthread_mutex_unlock(&LOCK_thread_count)); VOID(pthread_mutex_unlock(&LOCK_thread_count));
...@@ -3259,8 +3258,7 @@ mysql_parse(THD *thd, char *inBuf, uint length) ...@@ -3259,8 +3258,7 @@ mysql_parse(THD *thd, char *inBuf, uint length)
DBUG_ENTER("mysql_parse"); DBUG_ENTER("mysql_parse");
mysql_init_query(thd); mysql_init_query(thd);
thd->query_length = length; thd->clear_error();
thd->net.report_error= 0;
if (query_cache_send_result_to_client(thd, inBuf, length) <= 0) if (query_cache_send_result_to_client(thd, inBuf, length) <= 0)
{ {
......
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