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
{
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
ptr() to see if it changed if you are using your own buffer
......@@ -3566,6 +3568,11 @@ class Field_string :public Field_longstr {
my_decimal *val_decimal(my_decimal *);
int cmp(const uchar *,const uchar *);
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;
uint is_equal(Create_field *new_field);
virtual uchar *pack(uchar *to, const uchar *from,
......@@ -3663,6 +3670,11 @@ class Field_varstring :public Field_longstr {
!compression_method() == !from->compression_method() &&
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);
using Field_str::store;
double val_real(void);
......@@ -3869,6 +3881,10 @@ class Field_blob :public Field_longstr {
uint32 chars= octets / field_charset->mbminlen;
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 *);
Copy_func *get_copy_func(const Field *from) const
{
......@@ -4346,6 +4362,10 @@ class Field_bit :public Field {
{
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); }
int reset(void) {
bzero(ptr, bytes_in_rec);
......
......@@ -1506,7 +1506,6 @@ class Item: public Value_source,
virtual Field *get_tmp_table_field() { return 0; }
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 : "???"; }
const char *field_name_or_null()
{ return real_item()->type() == Item::FIELD_ITEM ? name.str : NULL; }
......@@ -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>
which is then used in protocol.send_result_set_metadata() when sending SHOW output to
......
......@@ -19,7 +19,7 @@
class Item;
struct TABLE_LIST;
class THD;
typedef struct st_field_info ST_FIELD_INFO;
struct ST_FIELD_INFO;
typedef struct st_schema_table ST_SCHEMA_TABLE;
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,
ulonglong select_options, ha_rows rows_limit,
const LEX_CSTRING *alias, bool do_not_open=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);
bool create_internal_tmp_table_from_heap(THD *thd, TABLE *table,
TMP_ENGINE_COLUMNDEF *start_recinfo,
......
......@@ -8164,13 +8164,11 @@ mark_all_fields_used_in_query(THD *thd,
TABLE *create_schema_table(THD *thd, TABLE_LIST *table_list)
{
uint field_count;
Item *item, *all_items;
Item *all_items;
TABLE *table;
List<Item> field_list;
ST_SCHEMA_TABLE *schema_table= table_list->schema_table;
ST_FIELD_INFO *fields_info= schema_table->fields_info;
ST_FIELD_INFO *fields;
MEM_ROOT *mem_root= thd->mem_root;
MY_BITMAP bitmap;
my_bitmap_map *buf;
DBUG_ENTER("create_schema_table");
......@@ -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);
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*) (thd->alloc(sizeof(TMP_TABLE_PARAM)));
tmp_table_param->init();
......@@ -8311,11 +8195,13 @@ TABLE *create_schema_table(THD *thd, TABLE_LIST *table_list)
tmp_table_param->schema_table= 1;
SELECT_LEX *select_lex= table_list->select_lex;
bool keep_row_order= is_show_command(thd);
if (!(table= create_tmp_table(thd, tmp_table_param,
field_list, (ORDER*) 0, 0, 0,
(select_lex->options | thd->variables.option_bits |
TMP_TABLE_ALL_COLUMNS), HA_POS_ERROR,
&table_list->alias, false, keep_row_order)))
if (!(table= create_tmp_table_for_schema(thd, tmp_table_param,
*schema_table, bitmap,
(select_lex->options |
thd->variables.option_bits |
TMP_TABLE_ALL_COLUMNS),
table_list->alias,
keep_row_order)))
DBUG_RETURN(0);
my_bitmap_map* bitmaps=
(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,
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);
#define OPEN_FRM_ONLY 1U // open FRM file only
#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.
......@@ -1712,7 +1712,13 @@ typedef struct st_field_info
{
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;
......
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