MDEV-19125 Change Send_field::type from enum_field_types to Type_handler*
This commit is contained in:
parent
e10f9e6c81
commit
4d12a6458e
@ -1073,7 +1073,7 @@ bool Protocol_text::store_field_metadata(const THD * thd,
|
||||
client_field->length= server_field.max_octet_length(charset_for_protocol,
|
||||
thd_cs);
|
||||
}
|
||||
client_field->type= server_field.type;
|
||||
client_field->type= server_field.type_handler()->type_code_for_protocol();
|
||||
client_field->flags= (uint16) server_field.flags;
|
||||
client_field->decimals= server_field.decimals;
|
||||
|
||||
|
23
sql/field.cc
23
sql/field.cc
@ -1968,7 +1968,7 @@ void Field::make_send_field(Send_field *field)
|
||||
}
|
||||
field->col_name= field_name;
|
||||
field->length=field_length;
|
||||
field->type=type();
|
||||
field->set_handler(type_handler());
|
||||
field->flags=table->maybe_null ? (flags & ~NOT_NULL_FLAG) : flags;
|
||||
field->decimals= 0;
|
||||
}
|
||||
@ -8743,6 +8743,20 @@ uint Field_blob::is_equal(Create_field *new_field)
|
||||
}
|
||||
|
||||
|
||||
void Field_blob::make_send_field(Send_field *field)
|
||||
{
|
||||
/*
|
||||
Historically all BLOB variant Fields are displayed as MYSQL_TYPE_BLOB
|
||||
in the result set metadata. Note, Item can work differently and
|
||||
display the exact BLOB type, such as
|
||||
MYSQL_TYPE_{TINY_BLOB|BLOB|MEDIUM_BLOB|LONG_BLOB}.
|
||||
QQ: this should be made consistent eventually.
|
||||
*/
|
||||
Field_longstr::make_send_field(field);
|
||||
field->set_handler(&type_handler_blob);
|
||||
}
|
||||
|
||||
|
||||
int Field_blob_compressed::store(const char *from, size_t length,
|
||||
CHARSET_INFO *cs)
|
||||
{
|
||||
@ -10915,6 +10929,13 @@ bool Column_definition::set_compressed(const char *method)
|
||||
}
|
||||
|
||||
|
||||
Send_field::Send_field(THD *thd, Item *item)
|
||||
{
|
||||
item->make_send_field(thd, this);
|
||||
normalize();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
maximum possible display length for blob.
|
||||
|
||||
|
43
sql/field.h
43
sql/field.h
@ -3861,6 +3861,7 @@ public:
|
||||
uint32 chars= octets / field_charset->mbminlen;
|
||||
return Information_schema_character_attributes(octets, chars);
|
||||
}
|
||||
void make_send_field(Send_field *);
|
||||
Copy_func *get_copy_func(const Field *from) const
|
||||
{
|
||||
/*
|
||||
@ -4115,6 +4116,10 @@ public:
|
||||
{
|
||||
return Information_schema_character_attributes();
|
||||
}
|
||||
void make_send_field(Send_field *to)
|
||||
{
|
||||
Field_longstr::make_send_field(to);
|
||||
}
|
||||
bool can_optimize_range(const Item_bool_func *cond,
|
||||
const Item *item,
|
||||
bool is_eq_func) const;
|
||||
@ -4994,14 +4999,15 @@ public:
|
||||
A class for sending info to the client
|
||||
*/
|
||||
|
||||
class Send_field :public Sql_alloc {
|
||||
public:
|
||||
class Send_field :public Sql_alloc,
|
||||
public Type_handler_hybrid_field_type
|
||||
{
|
||||
public:
|
||||
const char *db_name;
|
||||
const char *table_name,*org_table_name;
|
||||
LEX_CSTRING col_name, org_col_name;
|
||||
ulong length;
|
||||
uint flags, decimals;
|
||||
enum_field_types type;
|
||||
Send_field() {}
|
||||
Send_field(Field *field)
|
||||
{
|
||||
@ -5009,11 +5015,12 @@ class Send_field :public Sql_alloc {
|
||||
DBUG_ASSERT(table_name != 0);
|
||||
normalize();
|
||||
}
|
||||
|
||||
Send_field(THD *thd, Item *item);
|
||||
Send_field(Field *field,
|
||||
const char *db_name_arg,
|
||||
const char *table_name_arg)
|
||||
:db_name(db_name_arg),
|
||||
:Type_handler_hybrid_field_type(field->type_handler()),
|
||||
db_name(db_name_arg),
|
||||
table_name(table_name_arg),
|
||||
org_table_name(table_name_arg),
|
||||
col_name(field->field_name),
|
||||
@ -5021,33 +5028,25 @@ class Send_field :public Sql_alloc {
|
||||
length(field->field_length),
|
||||
flags(field->table->maybe_null ?
|
||||
(field->flags & ~NOT_NULL_FLAG) : field->flags),
|
||||
decimals(field->decimals()),
|
||||
type(field->type())
|
||||
decimals(field->decimals())
|
||||
{
|
||||
normalize();
|
||||
}
|
||||
|
||||
// This should move to Type_handler eventually
|
||||
static enum_field_types protocol_type_code(enum_field_types type)
|
||||
{
|
||||
/* Keep things compatible for old clients */
|
||||
if (type == MYSQL_TYPE_VARCHAR)
|
||||
return MYSQL_TYPE_VAR_STRING;
|
||||
return type;
|
||||
}
|
||||
private:
|
||||
void normalize()
|
||||
{
|
||||
/* limit number of decimals for float and double */
|
||||
if (type == MYSQL_TYPE_FLOAT || type == MYSQL_TYPE_DOUBLE)
|
||||
if (type_handler()->field_type() == MYSQL_TYPE_FLOAT ||
|
||||
type_handler()->field_type() == MYSQL_TYPE_DOUBLE)
|
||||
set_if_smaller(decimals, FLOATING_POINT_DECIMALS);
|
||||
/* Keep things compatible for old clients */
|
||||
type= protocol_type_code(type);
|
||||
}
|
||||
|
||||
public:
|
||||
// This should move to Type_handler eventually
|
||||
uint32 max_char_length(CHARSET_INFO *cs) const
|
||||
{
|
||||
return type >= MYSQL_TYPE_TINY_BLOB && type <= MYSQL_TYPE_BLOB ?
|
||||
return type_handler()->field_type() >= MYSQL_TYPE_TINY_BLOB &&
|
||||
type_handler()->field_type() <= MYSQL_TYPE_BLOB ?
|
||||
length / cs->mbminlen :
|
||||
length / cs->mbmaxlen;
|
||||
}
|
||||
@ -5077,8 +5076,8 @@ class Send_field :public Sql_alloc {
|
||||
bool is_sane() const
|
||||
{
|
||||
return (decimals <= FLOATING_POINT_DECIMALS ||
|
||||
(type != MYSQL_TYPE_FLOAT && type != MYSQL_TYPE_DOUBLE)) &&
|
||||
type != MYSQL_TYPE_VARCHAR;
|
||||
(type_handler()->field_type() != MYSQL_TYPE_FLOAT &&
|
||||
type_handler()->field_type() != MYSQL_TYPE_DOUBLE));
|
||||
}
|
||||
};
|
||||
|
||||
|
21
sql/item.cc
21
sql/item.cc
@ -4696,7 +4696,7 @@ void
|
||||
Item_param::set_out_param_info(Send_field *info)
|
||||
{
|
||||
m_out_param_info= info;
|
||||
set_handler_by_field_type(m_out_param_info->type);
|
||||
set_handler(m_out_param_info->type_handler());
|
||||
}
|
||||
|
||||
|
||||
@ -4737,16 +4737,7 @@ void Item_param::make_send_field(THD *thd, Send_field *field)
|
||||
OUT-parameter info to fill out the names.
|
||||
*/
|
||||
|
||||
field->db_name= m_out_param_info->db_name;
|
||||
field->table_name= m_out_param_info->table_name;
|
||||
field->org_table_name= m_out_param_info->org_table_name;
|
||||
field->col_name= m_out_param_info->col_name;
|
||||
field->org_col_name= m_out_param_info->org_col_name;
|
||||
|
||||
field->length= m_out_param_info->length;
|
||||
field->flags= m_out_param_info->flags;
|
||||
field->decimals= m_out_param_info->decimals;
|
||||
field->type= m_out_param_info->type;
|
||||
*field= *m_out_param_info;
|
||||
}
|
||||
|
||||
bool Item_param::append_for_log(THD *thd, String *str)
|
||||
@ -6124,7 +6115,7 @@ Item *Item_field::replace_equal_field(THD *thd, uchar *arg)
|
||||
|
||||
|
||||
void Item::init_make_send_field(Send_field *tmp_field,
|
||||
enum enum_field_types field_type_arg)
|
||||
const Type_handler *h)
|
||||
{
|
||||
tmp_field->db_name= "";
|
||||
tmp_field->org_table_name= "";
|
||||
@ -6134,7 +6125,7 @@ void Item::init_make_send_field(Send_field *tmp_field,
|
||||
tmp_field->flags= (maybe_null ? 0 : NOT_NULL_FLAG) |
|
||||
(my_binary_compare(charset_for_protocol()) ?
|
||||
BINARY_FLAG : 0);
|
||||
tmp_field->type= field_type_arg;
|
||||
tmp_field->set_handler(h);
|
||||
tmp_field->length=max_length;
|
||||
tmp_field->decimals=decimals;
|
||||
if (unsigned_flag)
|
||||
@ -6143,13 +6134,13 @@ void Item::init_make_send_field(Send_field *tmp_field,
|
||||
|
||||
void Item::make_send_field(THD *thd, Send_field *tmp_field)
|
||||
{
|
||||
init_make_send_field(tmp_field, field_type());
|
||||
init_make_send_field(tmp_field, type_handler());
|
||||
}
|
||||
|
||||
|
||||
void Item_empty_string::make_send_field(THD *thd, Send_field *tmp_field)
|
||||
{
|
||||
init_make_send_field(tmp_field, string_type_handler()->field_type());
|
||||
init_make_send_field(tmp_field, string_type_handler());
|
||||
}
|
||||
|
||||
|
||||
|
@ -946,7 +946,7 @@ public:
|
||||
void set_name(THD *thd, const char *str, size_t length, CHARSET_INFO *cs);
|
||||
void set_name_no_truncate(THD *thd, const char *str, uint length,
|
||||
CHARSET_INFO *cs);
|
||||
void init_make_send_field(Send_field *tmp_field,enum enum_field_types type);
|
||||
void init_make_send_field(Send_field *tmp_field, const Type_handler *h);
|
||||
virtual void cleanup();
|
||||
virtual void make_send_field(THD *thd, Send_field *field);
|
||||
|
||||
|
@ -59,10 +59,6 @@ public:
|
||||
virtual void set(longlong nr)=0;
|
||||
const Type_handler *type_handler() const=0;
|
||||
void set(const char *str) { set(str,(uint) strlen(str), default_charset()); }
|
||||
void make_send_field(THD *thd, Send_field *tmp_field)
|
||||
{
|
||||
init_make_send_field(tmp_field,field_type());
|
||||
}
|
||||
unsigned int size_of() { return sizeof(*this);}
|
||||
bool check_vcol_func_processor(void *arg)
|
||||
{
|
||||
|
@ -756,7 +756,7 @@ void Protocol::init(THD *thd_arg)
|
||||
packet= &thd->packet;
|
||||
convert= &thd->convert_buffer;
|
||||
#ifndef DBUG_OFF
|
||||
field_types= 0;
|
||||
field_handlers= 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
@ -827,7 +827,7 @@ bool Protocol_text::store_field_metadata(const THD * thd,
|
||||
thd_charset);
|
||||
int4store(pos + 2, field_length);
|
||||
}
|
||||
pos[6]= field.type;
|
||||
pos[6]= field.type_handler()->type_code_for_protocol();
|
||||
int2store(pos + 7, field.flags);
|
||||
pos[9]= (char) field.decimals;
|
||||
pos[10]= 0; // For the future
|
||||
@ -844,7 +844,7 @@ bool Protocol_text::store_field_metadata(const THD * thd,
|
||||
pos[0]= 3;
|
||||
int3store(pos + 1, field.length);
|
||||
pos[4]= 1;
|
||||
pos[5]= field.type;
|
||||
pos[5]= field.type_handler()->type_code_for_protocol();
|
||||
pos[6]= 3;
|
||||
int2store(pos + 7, field.flags);
|
||||
pos[9]= (char) field.decimals;
|
||||
@ -890,8 +890,8 @@ bool Protocol::send_result_set_metadata(List<Item> *list, uint flags)
|
||||
}
|
||||
|
||||
#ifndef DBUG_OFF
|
||||
field_types= (enum_field_types*) thd->alloc(sizeof(field_types) *
|
||||
list->elements);
|
||||
field_handlers= (const Type_handler**) thd->alloc(sizeof(field_handlers[0]) *
|
||||
list->elements);
|
||||
#endif
|
||||
|
||||
for (uint pos= 0; (item=it++); pos++)
|
||||
@ -902,7 +902,7 @@ bool Protocol::send_result_set_metadata(List<Item> *list, uint flags)
|
||||
if (prot.write())
|
||||
DBUG_RETURN(1);
|
||||
#ifndef DBUG_OFF
|
||||
field_types[pos]= Send_field::protocol_type_code(item->field_type());
|
||||
field_handlers[pos]= item->type_handler();
|
||||
#endif
|
||||
}
|
||||
|
||||
@ -939,8 +939,8 @@ bool Protocol::send_list_fields(List<Field> *list, const TABLE_LIST *table_list)
|
||||
Protocol_text prot(thd, thd->variables.net_buffer_length);
|
||||
|
||||
#ifndef DBUG_OFF
|
||||
field_types= (enum_field_types*) thd->alloc(sizeof(field_types) *
|
||||
list->elements);
|
||||
field_handlers= (const Type_handler **) thd->alloc(sizeof(field_handlers[0]) *
|
||||
list->elements);
|
||||
#endif
|
||||
|
||||
for (uint pos= 0; (fld= it++); pos++)
|
||||
@ -952,7 +952,12 @@ bool Protocol::send_list_fields(List<Field> *list, const TABLE_LIST *table_list)
|
||||
if (prot.write())
|
||||
DBUG_RETURN(1);
|
||||
#ifndef DBUG_OFF
|
||||
field_types[pos]= Send_field::protocol_type_code(fld->type());
|
||||
/*
|
||||
Historically all BLOB variant Fields are displayed as
|
||||
MYSQL_TYPE_BLOB in metadata.
|
||||
See Field_blob::make_send_field() for more comments.
|
||||
*/
|
||||
field_handlers[pos]= Send_field(fld).type_handler();
|
||||
#endif
|
||||
}
|
||||
DBUG_RETURN(prepare_for_send(list->elements));
|
||||
@ -974,9 +979,7 @@ bool Protocol::write()
|
||||
|
||||
bool Protocol_text::store_field_metadata(THD *thd, Item *item, uint pos)
|
||||
{
|
||||
Send_field field;
|
||||
item->make_send_field(thd, &field);
|
||||
field.normalize();
|
||||
Send_field field(thd, item);
|
||||
return store_field_metadata(thd, field, item->charset_for_protocol(), pos);
|
||||
}
|
||||
|
||||
@ -1133,12 +1136,7 @@ bool Protocol_text::store(const char *from, size_t length,
|
||||
CHARSET_INFO *fromcs, CHARSET_INFO *tocs)
|
||||
{
|
||||
#ifndef DBUG_OFF
|
||||
DBUG_ASSERT(field_types == 0 ||
|
||||
field_types[field_pos] == MYSQL_TYPE_DECIMAL ||
|
||||
field_types[field_pos] == MYSQL_TYPE_BIT ||
|
||||
field_types[field_pos] == MYSQL_TYPE_NEWDECIMAL ||
|
||||
(field_types[field_pos] >= MYSQL_TYPE_ENUM &&
|
||||
field_types[field_pos] <= MYSQL_TYPE_GEOMETRY));
|
||||
DBUG_ASSERT(valid_handler(field_pos, PROTOCOL_SEND_STRING));
|
||||
field_pos++;
|
||||
#endif
|
||||
return store_string_aux(from, length, fromcs, tocs);
|
||||
@ -1152,14 +1150,8 @@ bool Protocol_text::store(const char *from, size_t length,
|
||||
#ifndef DBUG_OFF
|
||||
DBUG_PRINT("info", ("Protocol_text::store field %u (%u): %.*s", field_pos,
|
||||
field_count, (int) length, (length == 0 ? "" : from)));
|
||||
DBUG_ASSERT(field_types == 0 || field_pos < field_count);
|
||||
DBUG_ASSERT(field_types == 0 ||
|
||||
field_types[field_pos] == MYSQL_TYPE_DECIMAL ||
|
||||
field_types[field_pos] == MYSQL_TYPE_BIT ||
|
||||
field_types[field_pos] == MYSQL_TYPE_NEWDECIMAL ||
|
||||
field_types[field_pos] == MYSQL_TYPE_NEWDATE ||
|
||||
(field_types[field_pos] >= MYSQL_TYPE_ENUM &&
|
||||
field_types[field_pos] <= MYSQL_TYPE_GEOMETRY));
|
||||
DBUG_ASSERT(field_handlers == 0 || field_pos < field_count);
|
||||
DBUG_ASSERT(valid_handler(field_pos, PROTOCOL_SEND_STRING));
|
||||
field_pos++;
|
||||
#endif
|
||||
return store_string_aux(from, length, fromcs, tocs);
|
||||
@ -1169,7 +1161,7 @@ bool Protocol_text::store(const char *from, size_t length,
|
||||
bool Protocol_text::store_tiny(longlong from)
|
||||
{
|
||||
#ifndef DBUG_OFF
|
||||
DBUG_ASSERT(field_types == 0 || field_types[field_pos] == MYSQL_TYPE_TINY);
|
||||
DBUG_ASSERT(valid_handler(field_pos, PROTOCOL_SEND_TINY));
|
||||
field_pos++;
|
||||
#endif
|
||||
char buff[22];
|
||||
@ -1181,9 +1173,7 @@ bool Protocol_text::store_tiny(longlong from)
|
||||
bool Protocol_text::store_short(longlong from)
|
||||
{
|
||||
#ifndef DBUG_OFF
|
||||
DBUG_ASSERT(field_types == 0 ||
|
||||
field_types[field_pos] == MYSQL_TYPE_YEAR ||
|
||||
field_types[field_pos] == MYSQL_TYPE_SHORT);
|
||||
DBUG_ASSERT(valid_handler(field_pos, PROTOCOL_SEND_SHORT));
|
||||
field_pos++;
|
||||
#endif
|
||||
char buff[22];
|
||||
@ -1196,9 +1186,7 @@ bool Protocol_text::store_short(longlong from)
|
||||
bool Protocol_text::store_long(longlong from)
|
||||
{
|
||||
#ifndef DBUG_OFF
|
||||
DBUG_ASSERT(field_types == 0 ||
|
||||
field_types[field_pos] == MYSQL_TYPE_INT24 ||
|
||||
field_types[field_pos] == MYSQL_TYPE_LONG);
|
||||
DBUG_ASSERT(valid_handler(field_pos, PROTOCOL_SEND_LONG));
|
||||
field_pos++;
|
||||
#endif
|
||||
char buff[22];
|
||||
@ -1211,8 +1199,7 @@ bool Protocol_text::store_long(longlong from)
|
||||
bool Protocol_text::store_longlong(longlong from, bool unsigned_flag)
|
||||
{
|
||||
#ifndef DBUG_OFF
|
||||
DBUG_ASSERT(field_types == 0 ||
|
||||
field_types[field_pos] == MYSQL_TYPE_LONGLONG);
|
||||
DBUG_ASSERT(valid_handler(field_pos, PROTOCOL_SEND_LONGLONG));
|
||||
field_pos++;
|
||||
#endif
|
||||
char buff[22];
|
||||
@ -1226,8 +1213,7 @@ bool Protocol_text::store_longlong(longlong from, bool unsigned_flag)
|
||||
bool Protocol_text::store_decimal(const my_decimal *d)
|
||||
{
|
||||
#ifndef DBUG_OFF
|
||||
DBUG_ASSERT(field_types == 0 ||
|
||||
field_types[field_pos] == MYSQL_TYPE_NEWDECIMAL);
|
||||
DBUG_ASSERT(0); // This method is not used yet
|
||||
field_pos++;
|
||||
#endif
|
||||
StringBuffer<DECIMAL_MAX_STR_LENGTH> str;
|
||||
@ -1239,8 +1225,7 @@ bool Protocol_text::store_decimal(const my_decimal *d)
|
||||
bool Protocol_text::store(float from, uint32 decimals, String *buffer)
|
||||
{
|
||||
#ifndef DBUG_OFF
|
||||
DBUG_ASSERT(field_types == 0 ||
|
||||
field_types[field_pos] == MYSQL_TYPE_FLOAT);
|
||||
DBUG_ASSERT(valid_handler(field_pos, PROTOCOL_SEND_FLOAT));
|
||||
field_pos++;
|
||||
#endif
|
||||
buffer->set_real((double) from, decimals, thd->charset());
|
||||
@ -1251,8 +1236,7 @@ bool Protocol_text::store(float from, uint32 decimals, String *buffer)
|
||||
bool Protocol_text::store(double from, uint32 decimals, String *buffer)
|
||||
{
|
||||
#ifndef DBUG_OFF
|
||||
DBUG_ASSERT(field_types == 0 ||
|
||||
field_types[field_pos] == MYSQL_TYPE_DOUBLE);
|
||||
DBUG_ASSERT(valid_handler(field_pos, PROTOCOL_SEND_DOUBLE));
|
||||
field_pos++;
|
||||
#endif
|
||||
buffer->set_real(from, decimals, thd->charset());
|
||||
@ -1290,9 +1274,7 @@ bool Protocol_text::store(Field *field)
|
||||
bool Protocol_text::store(MYSQL_TIME *tm, int decimals)
|
||||
{
|
||||
#ifndef DBUG_OFF
|
||||
DBUG_ASSERT(field_types == 0 ||
|
||||
field_types[field_pos] == MYSQL_TYPE_DATETIME ||
|
||||
field_types[field_pos] == MYSQL_TYPE_TIMESTAMP);
|
||||
DBUG_ASSERT(valid_handler(field_pos, PROTOCOL_SEND_DATETIME));
|
||||
field_pos++;
|
||||
#endif
|
||||
char buff[MAX_DATE_STRING_REP_LENGTH];
|
||||
@ -1304,8 +1286,7 @@ bool Protocol_text::store(MYSQL_TIME *tm, int decimals)
|
||||
bool Protocol_text::store_date(MYSQL_TIME *tm)
|
||||
{
|
||||
#ifndef DBUG_OFF
|
||||
DBUG_ASSERT(field_types == 0 ||
|
||||
field_types[field_pos] == MYSQL_TYPE_DATE);
|
||||
DBUG_ASSERT(valid_handler(field_pos, PROTOCOL_SEND_DATE));
|
||||
field_pos++;
|
||||
#endif
|
||||
char buff[MAX_DATE_STRING_REP_LENGTH];
|
||||
@ -1317,8 +1298,7 @@ bool Protocol_text::store_date(MYSQL_TIME *tm)
|
||||
bool Protocol_text::store_time(MYSQL_TIME *tm, int decimals)
|
||||
{
|
||||
#ifndef DBUG_OFF
|
||||
DBUG_ASSERT(field_types == 0 ||
|
||||
field_types[field_pos] == MYSQL_TYPE_TIME);
|
||||
DBUG_ASSERT(valid_handler(field_pos, PROTOCOL_SEND_TIME));
|
||||
field_pos++;
|
||||
#endif
|
||||
char buff[MAX_DATE_STRING_REP_LENGTH];
|
||||
@ -1475,8 +1455,7 @@ bool Protocol_binary::store_longlong(longlong from, bool unsigned_flag)
|
||||
bool Protocol_binary::store_decimal(const my_decimal *d)
|
||||
{
|
||||
#ifndef DBUG_OFF
|
||||
DBUG_ASSERT(field_types == 0 ||
|
||||
field_types[field_pos] == MYSQL_TYPE_NEWDECIMAL);
|
||||
DBUG_ASSERT(0); // This method is not used yet
|
||||
field_pos++;
|
||||
#endif
|
||||
StringBuffer<DECIMAL_MAX_STR_LENGTH> str;
|
||||
|
@ -22,6 +22,7 @@
|
||||
|
||||
#include "sql_error.h"
|
||||
#include "my_decimal.h" /* my_decimal */
|
||||
#include "sql_type.h"
|
||||
|
||||
class i_string;
|
||||
class Field;
|
||||
@ -40,7 +41,12 @@ protected:
|
||||
String *convert;
|
||||
uint field_pos;
|
||||
#ifndef DBUG_OFF
|
||||
enum enum_field_types *field_types;
|
||||
const Type_handler **field_handlers;
|
||||
bool valid_handler(uint pos, protocol_send_type_t type) const
|
||||
{
|
||||
return field_handlers == 0 ||
|
||||
field_handlers[field_pos]->protocol_send_type() == type;
|
||||
}
|
||||
#endif
|
||||
uint field_count;
|
||||
#ifndef EMBEDDED_LIBRARY
|
||||
|
@ -5289,6 +5289,7 @@ bool Protocol_local::store_longlong(longlong value, bool unsigned_flag)
|
||||
|
||||
bool Protocol_local::store_decimal(const my_decimal *value)
|
||||
{
|
||||
DBUG_ASSERT(0); // This method is not used yet
|
||||
StringBuffer<DECIMAL_MAX_STR_LENGTH> str;
|
||||
return value->to_string(&str) ? store_column(str.ptr(), str.length()) : true;
|
||||
}
|
||||
|
@ -82,6 +82,21 @@ class Virtual_column_info;
|
||||
|
||||
#define my_charset_numeric my_charset_latin1
|
||||
|
||||
enum protocol_send_type_t
|
||||
{
|
||||
PROTOCOL_SEND_STRING,
|
||||
PROTOCOL_SEND_FLOAT,
|
||||
PROTOCOL_SEND_DOUBLE,
|
||||
PROTOCOL_SEND_TINY,
|
||||
PROTOCOL_SEND_SHORT,
|
||||
PROTOCOL_SEND_LONG,
|
||||
PROTOCOL_SEND_LONGLONG,
|
||||
PROTOCOL_SEND_DATETIME,
|
||||
PROTOCOL_SEND_DATE,
|
||||
PROTOCOL_SEND_TIME
|
||||
};
|
||||
|
||||
|
||||
enum scalar_comparison_op
|
||||
{
|
||||
SCALAR_CMP_EQ,
|
||||
@ -3185,6 +3200,11 @@ public:
|
||||
DBUG_ASSERT(is_traditional_type());
|
||||
return field_type();
|
||||
}
|
||||
virtual enum_field_types type_code_for_protocol() const
|
||||
{
|
||||
return field_type();
|
||||
}
|
||||
virtual protocol_send_type_t protocol_send_type() const= 0;
|
||||
virtual Item_result result_type() const= 0;
|
||||
virtual Item_result cmp_type() const= 0;
|
||||
virtual enum_mysql_timestamp_type mysql_timestamp_type() const
|
||||
@ -3706,6 +3726,11 @@ public:
|
||||
DBUG_ASSERT(0);
|
||||
return MYSQL_TYPE_NULL;
|
||||
};
|
||||
protocol_send_type_t protocol_send_type() const
|
||||
{
|
||||
DBUG_ASSERT(0);
|
||||
return PROTOCOL_SEND_STRING;
|
||||
}
|
||||
Item_result result_type() const
|
||||
{
|
||||
return ROW_RESULT;
|
||||
@ -4143,6 +4168,10 @@ public:
|
||||
class Type_handler_decimal_result: public Type_handler_numeric
|
||||
{
|
||||
public:
|
||||
protocol_send_type_t protocol_send_type() const
|
||||
{
|
||||
return PROTOCOL_SEND_STRING;
|
||||
}
|
||||
Item_result result_type() const { return DECIMAL_RESULT; }
|
||||
Item_result cmp_type() const { return DECIMAL_RESULT; }
|
||||
virtual ~Type_handler_decimal_result() {};
|
||||
@ -4533,6 +4562,10 @@ class Type_handler_string_result: public Type_handler
|
||||
{
|
||||
uint Item_temporal_precision(THD *thd, Item *item, bool is_time) const;
|
||||
public:
|
||||
protocol_send_type_t protocol_send_type() const
|
||||
{
|
||||
return PROTOCOL_SEND_STRING;
|
||||
}
|
||||
Item_result result_type() const { return STRING_RESULT; }
|
||||
Item_result cmp_type() const { return STRING_RESULT; }
|
||||
CHARSET_INFO *charset_for_protocol(const Item *item) const;
|
||||
@ -4692,6 +4725,10 @@ public:
|
||||
virtual ~Type_handler_tiny() {}
|
||||
const Name name() const { return m_name_tiny; }
|
||||
enum_field_types field_type() const { return MYSQL_TYPE_TINY; }
|
||||
protocol_send_type_t protocol_send_type() const
|
||||
{
|
||||
return PROTOCOL_SEND_TINY;
|
||||
}
|
||||
const Type_limits_int *type_limits_int_by_unsigned_flag(bool unsigned_fl) const
|
||||
{
|
||||
return unsigned_fl ? &m_limits_uint8 : &m_limits_sint8;
|
||||
@ -4733,6 +4770,10 @@ public:
|
||||
virtual ~Type_handler_short() {}
|
||||
const Name name() const { return m_name_short; }
|
||||
enum_field_types field_type() const { return MYSQL_TYPE_SHORT; }
|
||||
protocol_send_type_t protocol_send_type() const
|
||||
{
|
||||
return PROTOCOL_SEND_SHORT;
|
||||
}
|
||||
bool Item_send(Item *item, Protocol *protocol, st_value *buf) const
|
||||
{
|
||||
return Item_send_short(item, protocol, buf);
|
||||
@ -4774,6 +4815,10 @@ public:
|
||||
virtual ~Type_handler_long() {}
|
||||
const Name name() const { return m_name_int; }
|
||||
enum_field_types field_type() const { return MYSQL_TYPE_LONG; }
|
||||
protocol_send_type_t protocol_send_type() const
|
||||
{
|
||||
return PROTOCOL_SEND_LONG;
|
||||
}
|
||||
const Type_limits_int *type_limits_int_by_unsigned_flag(bool unsigned_fl) const
|
||||
{
|
||||
return unsigned_fl ? &m_limits_uint32 : &m_limits_sint32;
|
||||
@ -4826,6 +4871,10 @@ public:
|
||||
virtual ~Type_handler_longlong() {}
|
||||
const Name name() const { return m_name_longlong; }
|
||||
enum_field_types field_type() const { return MYSQL_TYPE_LONGLONG; }
|
||||
protocol_send_type_t protocol_send_type() const
|
||||
{
|
||||
return PROTOCOL_SEND_LONGLONG;
|
||||
}
|
||||
const Type_limits_int *type_limits_int_by_unsigned_flag(bool unsigned_fl) const
|
||||
{
|
||||
return unsigned_fl ? &m_limits_uint64 : &m_limits_sint64;
|
||||
@ -4882,6 +4931,10 @@ public:
|
||||
virtual ~Type_handler_int24() {}
|
||||
const Name name() const { return m_name_mediumint; }
|
||||
enum_field_types field_type() const { return MYSQL_TYPE_INT24; }
|
||||
protocol_send_type_t protocol_send_type() const
|
||||
{
|
||||
return PROTOCOL_SEND_LONG;
|
||||
}
|
||||
bool Item_send(Item *item, Protocol *protocol, st_value *buf) const
|
||||
{
|
||||
return Item_send_long(item, protocol, buf);
|
||||
@ -4919,6 +4972,10 @@ public:
|
||||
virtual ~Type_handler_year() {}
|
||||
const Name name() const { return m_name_year; }
|
||||
enum_field_types field_type() const { return MYSQL_TYPE_YEAR; }
|
||||
protocol_send_type_t protocol_send_type() const
|
||||
{
|
||||
return PROTOCOL_SEND_SHORT;
|
||||
}
|
||||
uint32 max_display_length(const Item *item) const;
|
||||
uint32 calc_pack_length(uint32 length) const { return 1; }
|
||||
bool Item_send(Item *item, Protocol *protocol, st_value *buf) const
|
||||
@ -4964,6 +5021,10 @@ public:
|
||||
virtual ~Type_handler_bit() {}
|
||||
const Name name() const { return m_name_bit; }
|
||||
enum_field_types field_type() const { return MYSQL_TYPE_BIT; }
|
||||
protocol_send_type_t protocol_send_type() const
|
||||
{
|
||||
return PROTOCOL_SEND_STRING;
|
||||
}
|
||||
uint32 max_display_length(const Item *item) const;
|
||||
uint32 calc_pack_length(uint32 length) const { return length / 8; }
|
||||
bool Item_send(Item *item, Protocol *protocol, st_value *buf) const
|
||||
@ -5012,6 +5073,10 @@ public:
|
||||
virtual ~Type_handler_float() {}
|
||||
const Name name() const { return m_name_float; }
|
||||
enum_field_types field_type() const { return MYSQL_TYPE_FLOAT; }
|
||||
protocol_send_type_t protocol_send_type() const
|
||||
{
|
||||
return PROTOCOL_SEND_FLOAT;
|
||||
}
|
||||
bool type_can_have_auto_increment_attribute() const { return true; }
|
||||
uint32 max_display_length(const Item *item) const { return 25; }
|
||||
uint32 calc_pack_length(uint32 length) const { return sizeof(float); }
|
||||
@ -5050,6 +5115,10 @@ public:
|
||||
virtual ~Type_handler_double() {}
|
||||
const Name name() const { return m_name_double; }
|
||||
enum_field_types field_type() const { return MYSQL_TYPE_DOUBLE; }
|
||||
protocol_send_type_t protocol_send_type() const
|
||||
{
|
||||
return PROTOCOL_SEND_DOUBLE;
|
||||
}
|
||||
bool type_can_have_auto_increment_attribute() const { return true; }
|
||||
uint32 max_display_length(const Item *item) const { return 53; }
|
||||
uint32 calc_pack_length(uint32 length) const { return sizeof(double); }
|
||||
@ -5089,6 +5158,10 @@ public:
|
||||
virtual ~Type_handler_time_common() { }
|
||||
const Name name() const { return m_name_time; }
|
||||
enum_field_types field_type() const { return MYSQL_TYPE_TIME; }
|
||||
protocol_send_type_t protocol_send_type() const
|
||||
{
|
||||
return PROTOCOL_SEND_TIME;
|
||||
}
|
||||
enum_mysql_timestamp_type mysql_timestamp_type() const
|
||||
{
|
||||
return MYSQL_TIMESTAMP_TIME;
|
||||
@ -5245,6 +5318,10 @@ public:
|
||||
const Name name() const { return m_name_date; }
|
||||
const Type_handler *type_handler_for_comparison() const;
|
||||
enum_field_types field_type() const { return MYSQL_TYPE_DATE; }
|
||||
protocol_send_type_t protocol_send_type() const
|
||||
{
|
||||
return PROTOCOL_SEND_DATE;
|
||||
}
|
||||
enum_mysql_timestamp_type mysql_timestamp_type() const
|
||||
{
|
||||
return MYSQL_TIMESTAMP_DATE;
|
||||
@ -5334,6 +5411,10 @@ public:
|
||||
const Name name() const { return m_name_datetime; }
|
||||
const Type_handler *type_handler_for_comparison() const;
|
||||
enum_field_types field_type() const { return MYSQL_TYPE_DATETIME; }
|
||||
protocol_send_type_t protocol_send_type() const
|
||||
{
|
||||
return PROTOCOL_SEND_DATETIME;
|
||||
}
|
||||
enum_mysql_timestamp_type mysql_timestamp_type() const
|
||||
{
|
||||
return MYSQL_TIMESTAMP_DATETIME;
|
||||
@ -5443,6 +5524,10 @@ public:
|
||||
const Type_handler *type_handler_for_comparison() const;
|
||||
const Type_handler *type_handler_for_native_format() const;
|
||||
enum_field_types field_type() const { return MYSQL_TYPE_TIMESTAMP; }
|
||||
protocol_send_type_t protocol_send_type() const
|
||||
{
|
||||
return PROTOCOL_SEND_DATETIME;
|
||||
}
|
||||
enum_mysql_timestamp_type mysql_timestamp_type() const
|
||||
{
|
||||
return MYSQL_TIMESTAMP_DATETIME;
|
||||
@ -5756,6 +5841,10 @@ public:
|
||||
virtual ~Type_handler_varchar() {}
|
||||
const Name name() const { return m_name_varchar; }
|
||||
enum_field_types field_type() const { return MYSQL_TYPE_VARCHAR; }
|
||||
enum_field_types type_code_for_protocol() const
|
||||
{
|
||||
return MYSQL_TYPE_VAR_STRING; // Keep things compatible for old clients
|
||||
}
|
||||
uint32 calc_pack_length(uint32 length) const
|
||||
{
|
||||
return (length + (length < 256 ? 1: 2));
|
||||
|
@ -8397,6 +8397,50 @@ static void test_list_fields()
|
||||
}
|
||||
|
||||
|
||||
static void test_list_fields_blob()
|
||||
{
|
||||
MYSQL_RES *result;
|
||||
int rc;
|
||||
myheader("test_list_fields_blob");
|
||||
|
||||
rc= mysql_query(mysql, "drop table if exists t1");
|
||||
myquery(rc);
|
||||
|
||||
rc= mysql_query(mysql, "create table t1(c1 tinyblob, c2 blob, c3 mediumblob, c4 longblob)");
|
||||
myquery(rc);
|
||||
|
||||
result= mysql_list_fields(mysql, "t1", NULL);
|
||||
mytest(result);
|
||||
|
||||
rc= my_process_result_set(result);
|
||||
DIE_UNLESS(rc == 0);
|
||||
|
||||
/*
|
||||
All BLOB variant Fields are displayed as MYSQL_TYPE_BLOB in
|
||||
the result set metadata. Note, some Items display the exact
|
||||
BLOB type. This inconsistency should be fixed eventually.
|
||||
*/
|
||||
verify_prepare_field(result, 0, "c1", "c1", MYSQL_TYPE_BLOB,
|
||||
"t1", "t1",
|
||||
current_db, 255, NULL);
|
||||
|
||||
verify_prepare_field(result, 1, "c2", "c2", MYSQL_TYPE_BLOB,
|
||||
"t1", "t1",
|
||||
current_db, 65535, NULL);
|
||||
|
||||
verify_prepare_field(result, 2, "c3", "c3", MYSQL_TYPE_BLOB,
|
||||
"t1", "t1",
|
||||
current_db, 16777215, NULL);
|
||||
|
||||
verify_prepare_field(result, 3, "c4", "c4", MYSQL_TYPE_BLOB,
|
||||
"t1", "t1",
|
||||
current_db, 4294967295ULL, NULL);
|
||||
|
||||
mysql_free_result(result);
|
||||
myquery(mysql_query(mysql, "drop table t1"));
|
||||
}
|
||||
|
||||
|
||||
static void test_list_fields_default()
|
||||
{
|
||||
int rc, i;
|
||||
@ -20843,6 +20887,7 @@ static struct my_tests_st my_tests[]= {
|
||||
{ "test_fetch_column", test_fetch_column },
|
||||
{ "test_mem_overun", test_mem_overun },
|
||||
{ "test_list_fields", test_list_fields },
|
||||
{ "test_list_fields_blob", test_list_fields_blob },
|
||||
{ "test_list_fields_default", test_list_fields_default },
|
||||
{ "test_free_result", test_free_result },
|
||||
{ "test_free_store_result", test_free_store_result },
|
||||
|
Loading…
x
Reference in New Issue
Block a user