Commit ac93d7d6 authored by Alexander Barkov's avatar Alexander Barkov

MDEV-19593 Split create_schema_table() into virtual methods in Type_handler

parent 0928596a
...@@ -1142,6 +1142,8 @@ class Field: public Value_source ...@@ -1142,6 +1142,8 @@ class Field: public Value_source
{ {
return Information_schema_character_attributes(); return Information_schema_character_attributes();
} }
virtual void update_data_type_statistics(Data_type_statistics *st) const
{ }
/* /*
Caller beware: sql_type can change str.Ptr, so check Caller beware: sql_type can change str.Ptr, so check
ptr() to see if it changed if you are using your own buffer ptr() to see if it changed if you are using your own buffer
...@@ -3566,6 +3568,11 @@ class Field_string :public Field_longstr { ...@@ -3566,6 +3568,11 @@ class Field_string :public Field_longstr {
my_decimal *val_decimal(my_decimal *); my_decimal *val_decimal(my_decimal *);
int cmp(const uchar *,const uchar *); int cmp(const uchar *,const uchar *);
void sort_string(uchar *buff,uint length); void sort_string(uchar *buff,uint length);
void update_data_type_statistics(Data_type_statistics *st) const
{
st->m_fixed_string_count++;
st->m_fixed_string_total_length+= pack_length();
}
void sql_type(String &str) const; void sql_type(String &str) const;
uint is_equal(Create_field *new_field); uint is_equal(Create_field *new_field);
virtual uchar *pack(uchar *to, const uchar *from, virtual uchar *pack(uchar *to, const uchar *from,
...@@ -3663,6 +3670,11 @@ class Field_varstring :public Field_longstr { ...@@ -3663,6 +3670,11 @@ class Field_varstring :public Field_longstr {
!compression_method() == !from->compression_method() && !compression_method() == !from->compression_method() &&
length_bytes == ((Field_varstring*) from)->length_bytes; length_bytes == ((Field_varstring*) from)->length_bytes;
} }
void update_data_type_statistics(Data_type_statistics *st) const
{
st->m_variable_string_count++;
st->m_variable_string_total_length+= pack_length();
}
int store(const char *to,size_t length,CHARSET_INFO *charset); int store(const char *to,size_t length,CHARSET_INFO *charset);
using Field_str::store; using Field_str::store;
double val_real(void); double val_real(void);
...@@ -3869,6 +3881,10 @@ class Field_blob :public Field_longstr { ...@@ -3869,6 +3881,10 @@ class Field_blob :public Field_longstr {
uint32 chars= octets / field_charset->mbminlen; uint32 chars= octets / field_charset->mbminlen;
return Information_schema_character_attributes(octets, chars); return Information_schema_character_attributes(octets, chars);
} }
void update_data_type_statistics(Data_type_statistics *st) const
{
st->m_blob_count++;
}
void make_send_field(Send_field *); void make_send_field(Send_field *);
Copy_func *get_copy_func(const Field *from) const Copy_func *get_copy_func(const Field *from) const
{ {
...@@ -4346,6 +4362,10 @@ class Field_bit :public Field { ...@@ -4346,6 +4362,10 @@ class Field_bit :public Field {
{ {
return Information_schema_numeric_attributes(field_length); return Information_schema_numeric_attributes(field_length);
} }
void update_data_type_statistics(Data_type_statistics *st) const
{
st->m_uneven_bit_length+= field_length & 7;
}
uint size_of() const { return sizeof(*this); } uint size_of() const { return sizeof(*this); }
int reset(void) { int reset(void) {
bzero(ptr, bytes_in_rec); bzero(ptr, bytes_in_rec);
......
...@@ -1506,7 +1506,6 @@ class Item: public Value_source, ...@@ -1506,7 +1506,6 @@ class Item: public Value_source,
virtual Field *get_tmp_table_field() { return 0; } virtual Field *get_tmp_table_field() { return 0; }
virtual Field *create_field_for_create_select(TABLE *table); virtual Field *create_field_for_create_select(TABLE *table);
virtual Field *create_field_for_schema(THD *thd, TABLE *table);
virtual const char *full_name() const { return name.str ? name.str : "???"; } virtual const char *full_name() const { return name.str ? name.str : "???"; }
const char *field_name_or_null() const char *field_name_or_null()
{ return real_item()->type() == Item::FIELD_ITEM ? name.str : NULL; } { return real_item()->type() == Item::FIELD_ITEM ? name.str : NULL; }
...@@ -4492,46 +4491,6 @@ class Item_partition_func_safe_string: public Item_string ...@@ -4492,46 +4491,6 @@ class Item_partition_func_safe_string: public Item_string
}; };
class Item_return_date_time :public Item_partition_func_safe_string
{
enum_field_types date_time_field_type;
public:
Item_return_date_time(THD *thd, const LEX_CSTRING &name_arg,
enum_field_types field_type_arg, uint dec_arg= 0):
Item_partition_func_safe_string(thd, name_arg,
0/*length is not important*/,
&my_charset_bin),
date_time_field_type(field_type_arg)
{ decimals= dec_arg; }
const Type_handler *type_handler() const
{
return Type_handler::get_handler_by_field_type(date_time_field_type);
}
};
class Item_blob :public Item_partition_func_safe_string
{
public:
Item_blob(THD *thd, const LEX_CSTRING &name_arg, uint length):
Item_partition_func_safe_string(thd, name_arg, length, &my_charset_bin)
{ }
enum Type type() const { return TYPE_HOLDER; }
const Type_handler *type_handler() const
{
return Type_handler::blob_type_handler(max_length);
}
const Type_handler *real_type_handler() const
{
// Should not be called, Item_blob is used for SHOW purposes only.
DBUG_ASSERT(0);
return &type_handler_varchar;
}
Field *create_field_for_schema(THD *thd, TABLE *table)
{ return tmp_table_field_from_field_type(table); }
};
/** /**
Item_empty_string -- is a utility class to put an item into List<Item> Item_empty_string -- is a utility class to put an item into List<Item>
which is then used in protocol.send_result_set_metadata() when sending SHOW output to which is then used in protocol.send_result_set_metadata() when sending SHOW output to
......
...@@ -19,7 +19,7 @@ ...@@ -19,7 +19,7 @@
class Item; class Item;
struct TABLE_LIST; struct TABLE_LIST;
class THD; class THD;
typedef struct st_field_info ST_FIELD_INFO; struct ST_FIELD_INFO;
typedef struct st_schema_table ST_SCHEMA_TABLE; typedef struct st_schema_table ST_SCHEMA_TABLE;
extern ST_FIELD_INFO query_profile_statistics_info[]; extern ST_FIELD_INFO query_profile_statistics_info[];
......
This diff is collapsed.
...@@ -2419,6 +2419,13 @@ TABLE *create_tmp_table(THD *thd,TMP_TABLE_PARAM *param,List<Item> &fields, ...@@ -2419,6 +2419,13 @@ TABLE *create_tmp_table(THD *thd,TMP_TABLE_PARAM *param,List<Item> &fields,
ulonglong select_options, ha_rows rows_limit, ulonglong select_options, ha_rows rows_limit,
const LEX_CSTRING *alias, bool do_not_open=FALSE, const LEX_CSTRING *alias, bool do_not_open=FALSE,
bool keep_row_order= FALSE); bool keep_row_order= FALSE);
TABLE *create_tmp_table_for_schema(THD *thd, TMP_TABLE_PARAM *param,
const ST_SCHEMA_TABLE &schema_table,
const MY_BITMAP &bitmap,
longlong select_options,
const LEX_CSTRING &alias,
bool keep_row_order);
void free_tmp_table(THD *thd, TABLE *entry); void free_tmp_table(THD *thd, TABLE *entry);
bool create_internal_tmp_table_from_heap(THD *thd, TABLE *table, bool create_internal_tmp_table_from_heap(THD *thd, TABLE *table,
TMP_ENGINE_COLUMNDEF *start_recinfo, TMP_ENGINE_COLUMNDEF *start_recinfo,
......
...@@ -8164,13 +8164,11 @@ mark_all_fields_used_in_query(THD *thd, ...@@ -8164,13 +8164,11 @@ mark_all_fields_used_in_query(THD *thd,
TABLE *create_schema_table(THD *thd, TABLE_LIST *table_list) TABLE *create_schema_table(THD *thd, TABLE_LIST *table_list)
{ {
uint field_count; uint field_count;
Item *item, *all_items; Item *all_items;
TABLE *table; TABLE *table;
List<Item> field_list;
ST_SCHEMA_TABLE *schema_table= table_list->schema_table; ST_SCHEMA_TABLE *schema_table= table_list->schema_table;
ST_FIELD_INFO *fields_info= schema_table->fields_info; ST_FIELD_INFO *fields_info= schema_table->fields_info;
ST_FIELD_INFO *fields; ST_FIELD_INFO *fields;
MEM_ROOT *mem_root= thd->mem_root;
MY_BITMAP bitmap; MY_BITMAP bitmap;
my_bitmap_map *buf; my_bitmap_map *buf;
DBUG_ENTER("create_schema_table"); DBUG_ENTER("create_schema_table");
...@@ -8189,120 +8187,6 @@ TABLE *create_schema_table(THD *thd, TABLE_LIST *table_list) ...@@ -8189,120 +8187,6 @@ TABLE *create_schema_table(THD *thd, TABLE_LIST *table_list)
mark_all_fields_used_in_query(thd, fields_info, &bitmap, all_items); mark_all_fields_used_in_query(thd, fields_info, &bitmap, all_items);
for (field_count=0; fields_info->field_name; fields_info++)
{
switch (fields_info->field_type) {
case MYSQL_TYPE_TINY:
case MYSQL_TYPE_LONG:
case MYSQL_TYPE_SHORT:
case MYSQL_TYPE_LONGLONG:
case MYSQL_TYPE_INT24:
if (!(item= new (mem_root)
Item_return_int(thd, fields_info->field_name,
fields_info->field_length,
fields_info->field_type,
fields_info->value)))
{
DBUG_RETURN(0);
}
item->unsigned_flag= (fields_info->field_flags & MY_I_S_UNSIGNED);
break;
case MYSQL_TYPE_DATE:
if (!(item=new (mem_root)
Item_return_date_time(thd, fields_info->get_name(),
fields_info->field_type)))
DBUG_RETURN(0);
break;
case MYSQL_TYPE_TIME:
if (!(item=new (mem_root)
Item_return_date_time(thd, fields_info->get_name(),
fields_info->field_type)))
DBUG_RETURN(0);
break;
case MYSQL_TYPE_TIMESTAMP:
case MYSQL_TYPE_DATETIME:
if (!(item=new (mem_root)
Item_return_date_time(thd, fields_info->get_name(),
fields_info->field_type,
fields_info->field_length)))
DBUG_RETURN(0);
item->decimals= fields_info->field_length;
break;
case MYSQL_TYPE_FLOAT:
case MYSQL_TYPE_DOUBLE:
if ((item= new (mem_root)
Item_float(thd, fields_info->field_name, 0.0,
NOT_FIXED_DEC,
fields_info->field_length)) == NULL)
DBUG_RETURN(NULL);
break;
case MYSQL_TYPE_DECIMAL:
case MYSQL_TYPE_NEWDECIMAL:
if (!(item= new (mem_root)
Item_decimal(thd, (longlong) fields_info->value, false)))
{
DBUG_RETURN(0);
}
/*
Create a type holder, as we want the type of the item to defined
the type of the object, not the value
*/
if (!(item= new (mem_root) Item_type_holder(thd, item)))
DBUG_RETURN(0);
item->unsigned_flag= (fields_info->field_flags & MY_I_S_UNSIGNED);
item->decimals= fields_info->field_length%10;
item->max_length= (fields_info->field_length/100)%100;
if (item->unsigned_flag == 0)
item->max_length+= 1;
if (item->decimals > 0)
item->max_length+= 1;
item->set_name(thd, fields_info->get_name());
break;
case MYSQL_TYPE_TINY_BLOB:
case MYSQL_TYPE_MEDIUM_BLOB:
case MYSQL_TYPE_LONG_BLOB:
case MYSQL_TYPE_BLOB:
if (bitmap_is_set(&bitmap, field_count))
{
if (!(item= new (mem_root)
Item_blob(thd, fields_info->get_name(),
fields_info->field_length)))
{
DBUG_RETURN(0);
}
}
else
{
if (!(item= new (mem_root)
Item_empty_string(thd, "", 0, system_charset_info)))
{
DBUG_RETURN(0);
}
item->set_name(thd, fields_info->get_name());
}
break;
default:
{
bool show_field;
/* Don't let unimplemented types pass through. Could be a grave error. */
DBUG_ASSERT(fields_info->field_type == MYSQL_TYPE_STRING);
show_field= bitmap_is_set(&bitmap, field_count);
if (!(item= new (mem_root)
Item_empty_string(thd, "",
show_field ? fields_info->field_length : 0,
system_charset_info)))
{
DBUG_RETURN(0);
}
item->set_name(thd, fields_info->get_name());
break;
}
}
field_list.push_back(item, thd->mem_root);
item->maybe_null= (fields_info->field_flags & MY_I_S_MAYBE_NULL);
field_count++;
}
TMP_TABLE_PARAM *tmp_table_param = TMP_TABLE_PARAM *tmp_table_param =
(TMP_TABLE_PARAM*) (thd->alloc(sizeof(TMP_TABLE_PARAM))); (TMP_TABLE_PARAM*) (thd->alloc(sizeof(TMP_TABLE_PARAM)));
tmp_table_param->init(); tmp_table_param->init();
...@@ -8311,11 +8195,13 @@ TABLE *create_schema_table(THD *thd, TABLE_LIST *table_list) ...@@ -8311,11 +8195,13 @@ TABLE *create_schema_table(THD *thd, TABLE_LIST *table_list)
tmp_table_param->schema_table= 1; tmp_table_param->schema_table= 1;
SELECT_LEX *select_lex= table_list->select_lex; SELECT_LEX *select_lex= table_list->select_lex;
bool keep_row_order= is_show_command(thd); bool keep_row_order= is_show_command(thd);
if (!(table= create_tmp_table(thd, tmp_table_param, if (!(table= create_tmp_table_for_schema(thd, tmp_table_param,
field_list, (ORDER*) 0, 0, 0, *schema_table, bitmap,
(select_lex->options | thd->variables.option_bits | (select_lex->options |
TMP_TABLE_ALL_COLUMNS), HA_POS_ERROR, thd->variables.option_bits |
&table_list->alias, false, keep_row_order))) TMP_TABLE_ALL_COLUMNS),
table_list->alias,
keep_row_order)))
DBUG_RETURN(0); DBUG_RETURN(0);
my_bitmap_map* bitmaps= my_bitmap_map* bitmaps=
(my_bitmap_map*) thd->alloc(bitmap_buffer_size(field_count)); (my_bitmap_map*) thd->alloc(bitmap_buffer_size(field_count));
......
...@@ -3436,6 +3436,196 @@ Field *Type_handler_set::make_table_field(const LEX_CSTRING *name, ...@@ -3436,6 +3436,196 @@ Field *Type_handler_set::make_table_field(const LEX_CSTRING *name,
attr.collation); attr.collation);
} }
/*************************************************************************/
Field *Type_handler_float::make_schema_field(TABLE *table,
const Record_addr &addr,
const ST_FIELD_INFO &def,
bool show_field) const
{
Lex_cstring name(def.field_name);
return new (table->in_use->mem_root)
Field_float(addr.ptr(), def.field_length,
addr.null_ptr(), addr.null_bit(),
Field::NONE, &name,
(uint8) NOT_FIXED_DEC,
0/*zerofill*/, def.unsigned_flag());
}
Field *Type_handler_double::make_schema_field(TABLE *table,
const Record_addr &addr,
const ST_FIELD_INFO &def,
bool show_field) const
{
Lex_cstring name(def.field_name);
return new (table->in_use->mem_root)
Field_double(addr.ptr(), def.field_length,
addr.null_ptr(), addr.null_bit(),
Field::NONE, &name,
(uint8) NOT_FIXED_DEC,
0/*zerofill*/, def.unsigned_flag());
}
Field *Type_handler_decimal_result::make_schema_field(TABLE *table,
const Record_addr &addr,
const ST_FIELD_INFO &def,
bool show_field) const
{
Lex_cstring name(def.field_name);
uint dec= def.field_length % 10;
uint prec= (def.field_length / 100) % 100;
DBUG_ASSERT(dec <= DECIMAL_MAX_SCALE);
uint32 len= my_decimal_precision_to_length(prec, dec, def.unsigned_flag());
return new (table->in_use->mem_root)
Field_new_decimal(addr.ptr(), len, addr.null_ptr(), addr.null_bit(),
Field::NONE, &name,
(uint8) dec, 0/*zerofill*/, def.unsigned_flag());
}
Field *Type_handler_blob_common::make_schema_field(TABLE *table,
const Record_addr &addr,
const ST_FIELD_INFO &def,
bool show_field) const
{
Lex_cstring name(def.field_name);
if (show_field)
{
return new (table->in_use->mem_root)
Field_blob(addr.ptr(), addr.null_ptr(), addr.null_bit(),
Field::NONE, &name, table->s,
length_bytes(),
&my_charset_bin);
}
else
return new (table->in_use->mem_root)
Field_null(addr.ptr(), 0, Field::NONE, &name, &my_charset_bin);
}
Field *Type_handler_string::make_schema_field(TABLE *table,
const Record_addr &addr,
const ST_FIELD_INFO &def,
bool show_field) const
{
DBUG_ASSERT(def.field_length);
Lex_cstring name(def.field_name);
uint32 octet_length= (uint32) def.field_length * 3;
if (def.field_length * 3 > MAX_FIELD_VARCHARLENGTH)
{
Field *field= new (table->in_use->mem_root)
Field_blob(addr.ptr(), addr.null_ptr(), addr.null_bit(), Field::NONE,
&name, table->s, 4, system_charset_info);
if (field)
field->field_length= octet_length;
return field;
}
else if (show_field)
{
return new (table->in_use->mem_root)
Field_varstring(addr.ptr(), octet_length,
HA_VARCHAR_PACKLENGTH(octet_length),
addr.null_ptr(), addr.null_bit(),
Field::NONE, &name,
table->s, system_charset_info);
}
else
return new (table->in_use->mem_root)
Field_null(addr.ptr(), 0, Field::NONE, &name, system_charset_info);
}
Field *Type_handler_tiny::make_schema_field(TABLE *table,
const Record_addr &addr,
const ST_FIELD_INFO &def,
bool show_field) const
{
Lex_cstring name(def.field_name);
return new (table->in_use->mem_root)
Field_tiny(addr.ptr(), def.field_length,
addr.null_ptr(), addr.null_bit(), Field::NONE, &name,
0/*zerofill*/, def.unsigned_flag());
}
Field *Type_handler_short::make_schema_field(TABLE *table,
const Record_addr &addr,
const ST_FIELD_INFO &def,
bool show_field) const
{
Lex_cstring name(def.field_name);
return new (table->in_use->mem_root)
Field_short(addr.ptr(), def.field_length,
addr.null_ptr(), addr.null_bit(), Field::NONE, &name,
0/*zerofill*/, def.unsigned_flag());
}
Field *Type_handler_long::make_schema_field(TABLE *table,
const Record_addr &addr,
const ST_FIELD_INFO &def,
bool show_field) const
{
Lex_cstring name(def.field_name);
return new (table->in_use->mem_root)
Field_long(addr.ptr(), def.field_length,
addr.null_ptr(), addr.null_bit(), Field::NONE, &name,
0/*zerofill*/, def.unsigned_flag());
}
Field *Type_handler_longlong::make_schema_field(TABLE *table,
const Record_addr &addr,
const ST_FIELD_INFO &def,
bool show_field) const
{
Lex_cstring name(def.field_name);
return new (table->in_use->mem_root)
Field_longlong(addr.ptr(), def.field_length,
addr.null_ptr(), addr.null_bit(), Field::NONE, &name,
0/*zerofill*/, def.unsigned_flag());
}
Field *Type_handler_date_common::make_schema_field(TABLE *table,
const Record_addr &addr,
const ST_FIELD_INFO &def,
bool show_field) const
{
Lex_cstring name(def.field_name);
return new (table->in_use->mem_root)
Field_newdate(addr.ptr(), addr.null_ptr(), addr.null_bit(),
Field::NONE, &name);
}
Field *Type_handler_time_common::make_schema_field(TABLE *table,
const Record_addr &addr,
const ST_FIELD_INFO &def,
bool show_field) const
{
Lex_cstring name(def.field_name);
return new_Field_time(table->in_use->mem_root,
addr.ptr(), addr.null_ptr(), addr.null_bit(),
Field::NONE, &name, def.fsp());
}
Field *Type_handler_datetime_common::make_schema_field(TABLE *table,
const Record_addr &addr,
const ST_FIELD_INFO &def,
bool show_field) const
{
Lex_cstring name(def.field_name);
return new_Field_datetime(table->in_use->mem_root,
addr.ptr(), addr.null_ptr(), addr.null_bit(),
Field::NONE, &name, def.fsp());
}
/*************************************************************************/ /*************************************************************************/
/* /*
......
This diff is collapsed.
...@@ -1670,7 +1670,7 @@ bool fk_modifies_child(enum_fk_option opt); ...@@ -1670,7 +1670,7 @@ bool fk_modifies_child(enum_fk_option opt);
#define OPEN_FRM_ONLY 1U // open FRM file only #define OPEN_FRM_ONLY 1U // open FRM file only
#define OPEN_FULL_TABLE 2U // open FRM,MYD, MYI files #define OPEN_FULL_TABLE 2U // open FRM,MYD, MYI files
typedef struct st_field_info struct ST_FIELD_INFO
{ {
/** /**
This is used as column name. This is used as column name.
...@@ -1712,7 +1712,13 @@ typedef struct st_field_info ...@@ -1712,7 +1712,13 @@ typedef struct st_field_info
{ {
return LEX_CSTRING({old_name, strlen(old_name)}); return LEX_CSTRING({old_name, strlen(old_name)});
} }
} ST_FIELD_INFO; bool unsigned_flag() const { return field_flags & MY_I_S_UNSIGNED; }
uint fsp() const
{
DBUG_ASSERT(field_length <= TIME_SECOND_PART_DIGITS);
return field_length;
}
};
struct TABLE_LIST; struct TABLE_LIST;
......
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