Commit f5845574 authored by Alexander Barkov's avatar Alexander Barkov

MDEV-9216 Split field.cc:make_field() into virtual methods in Type_handler

parent dc580225
...@@ -10529,21 +10529,32 @@ uint pack_length_to_packflag(uint type) ...@@ -10529,21 +10529,32 @@ uint pack_length_to_packflag(uint type)
} }
Field *make_field(TABLE_SHARE *share, uint Column_definition_attributes::pack_flag_to_pack_length() const
MEM_ROOT *mem_root,
const Record_addr *rec,
uint32 field_length,
uint pack_flag,
const Type_handler *handler,
CHARSET_INFO *field_charset,
Field::geometry_type geom_type, uint srid,
Field::utype unireg_check,
TYPELIB *interval,
const LEX_CSTRING *field_name,
uint32 flags)
{ {
uint type= f_packtype(pack_flag); // 0..15
DBUG_ASSERT(type < 16);
switch (type) {
case MYSQL_TYPE_TINY: return 1;
case MYSQL_TYPE_SHORT: return 2;
case MYSQL_TYPE_LONG: return 4;
case MYSQL_TYPE_LONGLONG: return 8;
case MYSQL_TYPE_INT24: return 3;
}
return 0; // This should not happen
}
Field *Column_definition_attributes::make_field(TABLE_SHARE *share,
MEM_ROOT *mem_root,
const Record_addr *rec,
const Type_handler *handler,
const LEX_CSTRING *field_name,
uint32 flags)
const
{
DBUG_ASSERT(length <= UINT_MAX32);
DBUG_PRINT("debug", ("field_type: %s, field_length: %u, interval: %p, pack_flag: %s%s%s%s%s", DBUG_PRINT("debug", ("field_type: %s, field_length: %u, interval: %p, pack_flag: %s%s%s%s%s",
handler->name().ptr(), field_length, interval, handler->name().ptr(), (uint) length, interval,
FLAGSTR(pack_flag, FIELDFLAG_BINARY), FLAGSTR(pack_flag, FIELDFLAG_BINARY),
FLAGSTR(pack_flag, FIELDFLAG_INTERVAL), FLAGSTR(pack_flag, FIELDFLAG_INTERVAL),
FLAGSTR(pack_flag, FIELDFLAG_NUMBER), FLAGSTR(pack_flag, FIELDFLAG_NUMBER),
...@@ -10552,288 +10563,51 @@ Field *make_field(TABLE_SHARE *share, ...@@ -10552,288 +10563,51 @@ Field *make_field(TABLE_SHARE *share,
Record_addr addr(rec->ptr(), f_maybe_null(pack_flag) ? rec->null() : Record_addr addr(rec->ptr(), f_maybe_null(pack_flag) ? rec->null() :
Bit_addr()); Bit_addr());
/*
if (handler == &type_handler_row) Special code for the BIT-alike data types
{ who store data bits together with NULL-bits.
DBUG_ASSERT(field_length == 0); */
DBUG_ASSERT(f_maybe_null(pack_flag)); Bit_addr bit(rec->null());
return new (mem_root) Field_row(addr.ptr(), field_name); if (f_maybe_null(pack_flag))
} bit.inc();
return handler->make_table_field_from_def(share, mem_root, field_name,
if (f_is_alpha(pack_flag)) addr, bit, this, flags);
{
if (!f_is_packed(pack_flag))
{
enum_field_types field_type= handler->real_field_type();
if (field_type == MYSQL_TYPE_STRING ||
field_type == MYSQL_TYPE_DECIMAL || // 3.23 or 4.0 string
field_type == MYSQL_TYPE_VAR_STRING)
return new (mem_root)
Field_string(addr.ptr(), field_length,
addr.null_ptr(), addr.null_bit(),
unireg_check, field_name,
field_charset);
if (field_type == MYSQL_TYPE_VARCHAR)
{
if (unireg_check == Field::TMYSQL_COMPRESSED)
return new (mem_root)
Field_varstring_compressed(
addr.ptr(), field_length,
HA_VARCHAR_PACKLENGTH(field_length),
addr.null_ptr(), addr.null_bit(),
unireg_check, field_name,
share, field_charset, zlib_compression_method);
return new (mem_root)
Field_varstring(addr.ptr(), field_length,
HA_VARCHAR_PACKLENGTH(field_length),
addr.null_ptr(), addr.null_bit(),
unireg_check, field_name,
share,
field_charset);
}
return 0; // Error
}
// MYSQL_TYPE_VAR_STRING is handled above
DBUG_ASSERT(f_packtype(pack_flag) != MYSQL_TYPE_VAR_STRING);
const Type_handler *tmp;
tmp= Type_handler::get_handler_by_real_type((enum_field_types)
f_packtype(pack_flag));
uint pack_length= tmp->calc_pack_length(field_length);
#ifdef HAVE_SPATIAL
if (f_is_geom(pack_flag))
{
status_var_increment(current_thd->status_var.feature_gis);
return new (mem_root)
Field_geom(addr.ptr(), addr.null_ptr(), addr.null_bit(),
unireg_check, field_name, share,
pack_length, geom_type, srid);
}
#endif
if (f_is_blob(pack_flag))
{
if (unireg_check == Field::TMYSQL_COMPRESSED)
return new (mem_root)
Field_blob_compressed(addr.ptr(), addr.null_ptr(), addr.null_bit(),
unireg_check, field_name, share,
pack_length, field_charset, zlib_compression_method);
return new (mem_root)
Field_blob(addr.ptr(), addr.null_ptr(), addr.null_bit(),
unireg_check, field_name, share,
pack_length, field_charset);
}
if (interval)
{
if (f_is_enum(pack_flag))
return new (mem_root)
Field_enum(addr.ptr(), field_length, addr.null_ptr(), addr.null_bit(),
unireg_check, field_name,
pack_length, interval, field_charset);
else
return new (mem_root)
Field_set(addr.ptr(), field_length, addr.null_ptr(), addr.null_bit(),
unireg_check, field_name,
pack_length, interval, field_charset);
}
}
switch (handler->real_field_type()) {
case MYSQL_TYPE_DECIMAL:
return new (mem_root)
Field_decimal(addr.ptr(), field_length, addr.null_ptr(), addr.null_bit(),
unireg_check, field_name,
f_decimals(pack_flag),
f_is_zerofill(pack_flag) != 0,
f_is_dec(pack_flag) == 0);
case MYSQL_TYPE_NEWDECIMAL:
return new (mem_root)
Field_new_decimal(addr.ptr(), field_length,
addr.null_ptr(), addr.null_bit(),
unireg_check, field_name,
f_decimals(pack_flag),
f_is_zerofill(pack_flag) != 0,
f_is_dec(pack_flag) == 0);
case MYSQL_TYPE_FLOAT:
{
int decimals= f_decimals(pack_flag);
if (decimals == FLOATING_POINT_DECIMALS)
decimals= NOT_FIXED_DEC;
return new (mem_root)
Field_float(addr.ptr(), field_length, addr.null_ptr(), addr.null_bit(),
unireg_check, field_name,
decimals,
f_is_zerofill(pack_flag) != 0,
f_is_dec(pack_flag)== 0);
}
case MYSQL_TYPE_DOUBLE:
{
int decimals= f_decimals(pack_flag);
if (decimals == FLOATING_POINT_DECIMALS)
decimals= NOT_FIXED_DEC;
return new (mem_root)
Field_double(addr.ptr(), field_length, addr.null_ptr(), addr.null_bit(),
unireg_check, field_name,
decimals,
f_is_zerofill(pack_flag) != 0,
f_is_dec(pack_flag)== 0);
}
case MYSQL_TYPE_TINY:
return new (mem_root)
Field_tiny(addr.ptr(), field_length, addr.null_ptr(), addr.null_bit(),
unireg_check, field_name,
f_is_zerofill(pack_flag) != 0,
f_is_dec(pack_flag) == 0);
case MYSQL_TYPE_SHORT:
return new (mem_root)
Field_short(addr.ptr(), field_length, addr.null_ptr(), addr.null_bit(),
unireg_check, field_name,
f_is_zerofill(pack_flag) != 0,
f_is_dec(pack_flag) == 0);
case MYSQL_TYPE_INT24:
return new (mem_root)
Field_medium(addr.ptr(), field_length, addr.null_ptr(), addr.null_bit(),
unireg_check, field_name,
f_is_zerofill(pack_flag) != 0,
f_is_dec(pack_flag) == 0);
case MYSQL_TYPE_LONG:
return new (mem_root)
Field_long(addr.ptr(), field_length, addr.null_ptr(), addr.null_bit(),
unireg_check, field_name,
f_is_zerofill(pack_flag) != 0,
f_is_dec(pack_flag) == 0);
case MYSQL_TYPE_LONGLONG:
if (flags & (VERS_SYS_START_FLAG|VERS_SYS_END_FLAG))
{
return new (mem_root)
Field_vers_trx_id(addr.ptr(), field_length,
addr.null_ptr(), addr.null_bit(),
unireg_check, field_name,
f_is_zerofill(pack_flag) != 0,
f_is_dec(pack_flag) == 0);
}
else
{
return new (mem_root)
Field_longlong(addr.ptr(), field_length,
addr.null_ptr(), addr.null_bit(),
unireg_check, field_name,
f_is_zerofill(pack_flag) != 0,
f_is_dec(pack_flag) == 0);
}
case MYSQL_TYPE_TIMESTAMP:
{
uint dec= field_length > MAX_DATETIME_WIDTH ?
field_length - MAX_DATETIME_WIDTH - 1: 0;
return new_Field_timestamp(mem_root, addr.ptr(),
addr.null_ptr(), addr.null_bit(),
unireg_check, field_name, share, dec);
}
case MYSQL_TYPE_TIMESTAMP2:
{
uint dec= field_length > MAX_DATETIME_WIDTH ?
field_length - MAX_DATETIME_WIDTH - 1: 0;
return new (mem_root)
Field_timestampf(addr.ptr(), addr.null_ptr(), addr.null_bit(),
unireg_check, field_name, share, dec);
}
case MYSQL_TYPE_YEAR:
return new (mem_root)
Field_year(addr.ptr(), field_length, addr.null_ptr(), addr.null_bit(),
unireg_check, field_name);
case MYSQL_TYPE_DATE:
return new (mem_root)
Field_date(addr.ptr(), addr.null_ptr(), addr.null_bit(),
unireg_check, field_name);
case MYSQL_TYPE_NEWDATE:
return new (mem_root)
Field_newdate(addr.ptr(), addr.null_ptr(), addr.null_bit(),
unireg_check, field_name);
case MYSQL_TYPE_TIME:
{
uint dec= field_length > MIN_TIME_WIDTH ?
field_length - MIN_TIME_WIDTH - 1: 0;
return new_Field_time(mem_root, addr.ptr(),
addr.null_ptr(), addr.null_bit(),
unireg_check, field_name, dec);
}
case MYSQL_TYPE_TIME2:
{
uint dec= field_length > MIN_TIME_WIDTH ?
field_length - MIN_TIME_WIDTH - 1: 0;
return new (mem_root)
Field_timef(addr.ptr(), addr.null_ptr(), addr.null_bit(), unireg_check,
field_name, dec);
}
case MYSQL_TYPE_DATETIME:
{
uint dec= field_length > MAX_DATETIME_WIDTH ?
field_length - MAX_DATETIME_WIDTH - 1: 0;
return new_Field_datetime(mem_root, addr.ptr(),
addr.null_ptr(), addr.null_bit(),
unireg_check, field_name, dec);
}
case MYSQL_TYPE_DATETIME2:
{
uint dec= field_length > MAX_DATETIME_WIDTH ?
field_length - MAX_DATETIME_WIDTH - 1: 0;
return new (mem_root)
Field_datetimef(addr.ptr(), addr.null_ptr(), addr.null_bit(),
unireg_check, field_name, dec);
}
case MYSQL_TYPE_NULL:
return new (mem_root)
Field_null(addr.ptr(), field_length, unireg_check, field_name,
field_charset);
case MYSQL_TYPE_BIT:
{
Bit_addr bit(rec->null());
if (!f_bit_as_char(pack_flag) && f_maybe_null(pack_flag))
bit.inc();
return (f_bit_as_char(pack_flag) ?
new (mem_root)
Field_bit_as_char(addr.ptr(), field_length,
addr.null_ptr(), addr.null_bit(),
unireg_check, field_name) :
new (mem_root)
Field_bit(addr.ptr(), field_length,
addr.null_ptr(), addr.null_bit(),
bit.ptr(), bit.offs(), unireg_check, field_name));
}
default: // Impossible (Wrong version)
break;
}
return 0;
} }
bool Field_vers_trx_id::test_if_equality_guarantees_uniqueness(const Item* item) const bool Field_vers_trx_id::test_if_equality_guarantees_uniqueness(const Item* item) const
{ {
return item->type() == Item::DATE_ITEM; return item->type() == Item::DATE_ITEM;
} }
Column_definition_attributes::Column_definition_attributes(const Field *field)
:length(field->field_length),
unireg_check(field->unireg_check),
interval(NULL),
charset(field->charset()), // May be NULL ptr
srid(0),
geom_type(Field::GEOM_GEOMETRY),
pack_flag(0)
{}
/** Create a field suitable for create of table. */ /** Create a field suitable for create of table. */
Column_definition::Column_definition(THD *thd, Field *old_field, Column_definition::Column_definition(THD *thd, Field *old_field,
Field *orig_field) Field *orig_field)
:Column_definition_attributes(old_field)
{ {
on_update= NULL; on_update= NULL;
field_name= old_field->field_name; field_name= old_field->field_name;
length= old_field->field_length;
flags= old_field->flags; flags= old_field->flags;
unireg_check=old_field->unireg_check;
pack_length=old_field->pack_length(); pack_length=old_field->pack_length();
key_length= old_field->key_length(); key_length= old_field->key_length();
set_handler(old_field->type_handler()); set_handler(old_field->type_handler());
charset= old_field->charset(); // May be NULL ptr
comment= old_field->comment; comment= old_field->comment;
decimals= old_field->decimals(); decimals= old_field->decimals();
vcol_info= old_field->vcol_info; vcol_info= old_field->vcol_info;
option_list= old_field->option_list; option_list= old_field->option_list;
pack_flag= 0;
compression_method_ptr= 0; compression_method_ptr= 0;
versioning= VERSIONING_NOT_SET; versioning= VERSIONING_NOT_SET;
invisible= old_field->invisible; invisible= old_field->invisible;
......
...@@ -4072,21 +4072,53 @@ class Field_row: public Field_null ...@@ -4072,21 +4072,53 @@ class Field_row: public Field_null
extern const LEX_CSTRING null_clex_str; extern const LEX_CSTRING null_clex_str;
Field *make_field(TABLE_SHARE *share, MEM_ROOT *mem_root, class Column_definition_attributes
const Record_addr *rec, {
uint32 field_length, public:
uint pack_flag, const Type_handler *handler, /*
CHARSET_INFO *cs, At various stages in execution this can be length of field in bytes or
Field::geometry_type geom_type, uint srid, max number of characters.
Field::utype unireg_check, */
TYPELIB *interval, const LEX_CSTRING *field_name, ulonglong length;
uint32 flags); Field::utype unireg_check;
TYPELIB *interval; // Which interval to use
CHARSET_INFO *charset;
uint32 srid;
Field::geometry_type geom_type;
uint pack_flag;
Column_definition_attributes()
:length(0),
unireg_check(Field::NONE),
interval(NULL),
charset(&my_charset_bin),
srid(0),
geom_type(Field::GEOM_GEOMETRY),
pack_flag(0)
{ }
Column_definition_attributes(const Field *field);
Field *make_field(TABLE_SHARE *share, MEM_ROOT *mem_root,
const Record_addr *rec,
const Type_handler *handler,
const LEX_CSTRING *field_name,
uint32 flags) const;
uint temporal_dec(uint intlen) const
{
return (uint) (length > intlen ? length - intlen - 1 : 0);
}
uint pack_flag_to_pack_length() const;
void frm_pack_basic(uchar *buff) const;
void frm_pack_charset(uchar *buff) const;
void frm_unpack_basic(const uchar *buff);
bool frm_unpack_charset(TABLE_SHARE *share, const uchar *buff);
};
/* /*
Create field class for CREATE TABLE Create field class for CREATE TABLE
*/ */
class Column_definition: public Sql_alloc, class Column_definition: public Sql_alloc,
public Type_handler_hybrid_field_type public Type_handler_hybrid_field_type,
public Column_definition_attributes
{ {
/** /**
Create "interval" from "interval_list". Create "interval" from "interval_list".
...@@ -4141,11 +4173,6 @@ class Column_definition: public Sql_alloc, ...@@ -4141,11 +4173,6 @@ class Column_definition: public Sql_alloc,
WITHOUT_VERSIONING WITHOUT_VERSIONING
}; };
Item *on_update; // ON UPDATE NOW() Item *on_update; // ON UPDATE NOW()
/*
At various stages in execution this can be length of field in bytes or
max number of characters.
*/
ulonglong length;
field_visibility_t invisible; field_visibility_t invisible;
/* /*
The value of `length' as set by parser: is the number of characters The value of `length' as set by parser: is the number of characters
...@@ -4153,15 +4180,9 @@ class Column_definition: public Sql_alloc, ...@@ -4153,15 +4180,9 @@ class Column_definition: public Sql_alloc,
*/ */
uint32 char_length; uint32 char_length;
uint decimals, flags, pack_length, key_length; uint decimals, flags, pack_length, key_length;
Field::utype unireg_check;
TYPELIB *interval; // Which interval to use
List<String> interval_list; List<String> interval_list;
CHARSET_INFO *charset;
uint32 srid;
Field::geometry_type geom_type;
engine_option_value *option_list; engine_option_value *option_list;
uint pack_flag;
/* /*
This is additinal data provided for any computed(virtual) field. This is additinal data provided for any computed(virtual) field.
...@@ -4179,11 +4200,9 @@ class Column_definition: public Sql_alloc, ...@@ -4179,11 +4200,9 @@ class Column_definition: public Sql_alloc,
:Type_handler_hybrid_field_type(&type_handler_null), :Type_handler_hybrid_field_type(&type_handler_null),
compression_method_ptr(0), compression_method_ptr(0),
comment(null_clex_str), comment(null_clex_str),
on_update(NULL), length(0), invisible(VISIBLE), decimals(0), on_update(NULL), invisible(VISIBLE), decimals(0),
flags(0), pack_length(0), key_length(0), unireg_check(Field::NONE), flags(0), pack_length(0), key_length(0),
interval(0), charset(&my_charset_bin), option_list(NULL),
srid(0), geom_type(Field::GEOM_GEOMETRY),
option_list(NULL), pack_flag(0),
vcol_info(0), default_value(0), check_constraint(0), vcol_info(0), default_value(0), check_constraint(0),
versioning(VERSIONING_NOT_SET) versioning(VERSIONING_NOT_SET)
{ {
...@@ -4316,10 +4335,9 @@ class Column_definition: public Sql_alloc, ...@@ -4316,10 +4335,9 @@ class Column_definition: public Sql_alloc,
const Record_addr *addr, const Record_addr *addr,
const LEX_CSTRING *field_name_arg) const const LEX_CSTRING *field_name_arg) const
{ {
return ::make_field(share, mem_root, addr, (uint32) length, return Column_definition_attributes::make_field(share, mem_root, addr,
pack_flag, type_handler(), charset, type_handler(),
geom_type, srid, unireg_check, interval, field_name_arg, flags);
field_name_arg, flags);
} }
Field *make_field(TABLE_SHARE *share, MEM_ROOT *mem_root, Field *make_field(TABLE_SHARE *share, MEM_ROOT *mem_root,
const LEX_CSTRING *field_name_arg) const const LEX_CSTRING *field_name_arg) const
...@@ -4647,7 +4665,7 @@ bool check_expression(Virtual_column_info *vcol, LEX_CSTRING *name, ...@@ -4647,7 +4665,7 @@ bool check_expression(Virtual_column_info *vcol, LEX_CSTRING *name,
#define FIELDFLAG_DEC_SHIFT 8 #define FIELDFLAG_DEC_SHIFT 8
#define FIELDFLAG_MAX_DEC 63U #define FIELDFLAG_MAX_DEC 63U
#define MTYP_TYPENR(type) (type & 127U) /* Remove bits from type */ #define MTYP_TYPENR(type) ((type) & 127U) // Remove bits from type
#define f_is_dec(x) ((x) & FIELDFLAG_DECIMAL) #define f_is_dec(x) ((x) & FIELDFLAG_DECIMAL)
#define f_is_num(x) ((x) & FIELDFLAG_NUMBER) #define f_is_num(x) ((x) & FIELDFLAG_NUMBER)
......
...@@ -5780,3 +5780,487 @@ void Type_handler_geometry::Item_param_set_param_func(Item_param *param, ...@@ -5780,3 +5780,487 @@ void Type_handler_geometry::Item_param_set_param_func(Item_param *param,
#endif #endif
/***************************************************************************/ /***************************************************************************/
Field *Type_handler_row::
make_table_field_from_def(TABLE_SHARE *share, MEM_ROOT *mem_root,
const LEX_CSTRING *name,
const Record_addr &rec, const Bit_addr &bit,
const Column_definition_attributes *attr,
uint32 flags) const
{
DBUG_ASSERT(attr->length == 0);
DBUG_ASSERT(f_maybe_null(attr->pack_flag));
return new (mem_root) Field_row(rec.ptr(), name);
}
Field *Type_handler_olddecimal::
make_table_field_from_def(TABLE_SHARE *share, MEM_ROOT *mem_root,
const LEX_CSTRING *name,
const Record_addr &rec, const Bit_addr &bit,
const Column_definition_attributes *attr,
uint32 flags) const
{
return new (mem_root)
Field_decimal(rec.ptr(), (uint32) attr->length,
rec.null_ptr(), rec.null_bit(),
attr->unireg_check, name,
f_decimals(attr->pack_flag),
f_is_zerofill(attr->pack_flag) != 0,
f_is_dec(attr->pack_flag) == 0);
}
Field *Type_handler_newdecimal::
make_table_field_from_def(TABLE_SHARE *share, MEM_ROOT *mem_root,
const LEX_CSTRING *name,
const Record_addr &rec, const Bit_addr &bit,
const Column_definition_attributes *attr,
uint32 flags) const
{
return new (mem_root)
Field_new_decimal(rec.ptr(), (uint32) attr->length,
rec.null_ptr(), rec.null_bit(),
attr->unireg_check, name,
f_decimals(attr->pack_flag),
f_is_zerofill(attr->pack_flag) != 0,
f_is_dec(attr->pack_flag) == 0);
}
Field *Type_handler_float::
make_table_field_from_def(TABLE_SHARE *share, MEM_ROOT *mem_root,
const LEX_CSTRING *name,
const Record_addr &rec, const Bit_addr &bit,
const Column_definition_attributes *attr,
uint32 flags) const
{
int decimals= f_decimals(attr->pack_flag);
if (decimals == FLOATING_POINT_DECIMALS)
decimals= NOT_FIXED_DEC;
return new (mem_root)
Field_float(rec.ptr(), (uint32) attr->length,
rec.null_ptr(), rec.null_bit(),
attr->unireg_check, name, decimals,
f_is_zerofill(attr->pack_flag) != 0,
f_is_dec(attr->pack_flag)== 0);
}
Field *Type_handler_double::
make_table_field_from_def(TABLE_SHARE *share, MEM_ROOT *mem_root,
const LEX_CSTRING *name,
const Record_addr &rec, const Bit_addr &bit,
const Column_definition_attributes *attr,
uint32 flags) const
{
int decimals= f_decimals(attr->pack_flag);
if (decimals == FLOATING_POINT_DECIMALS)
decimals= NOT_FIXED_DEC;
return new (mem_root)
Field_double(rec.ptr(), (uint32) attr->length,
rec.null_ptr(), rec.null_bit(),
attr->unireg_check, name, decimals,
f_is_zerofill(attr->pack_flag) != 0,
f_is_dec(attr->pack_flag)== 0);
}
Field *Type_handler_tiny::
make_table_field_from_def(TABLE_SHARE *share, MEM_ROOT *mem_root,
const LEX_CSTRING *name,
const Record_addr &rec, const Bit_addr &bit,
const Column_definition_attributes *attr,
uint32 flags) const
{
return new (mem_root)
Field_tiny(rec.ptr(), (uint32) attr->length, rec.null_ptr(), rec.null_bit(),
attr->unireg_check, name,
f_is_zerofill(attr->pack_flag) != 0,
f_is_dec(attr->pack_flag) == 0);
}
Field *Type_handler_short::
make_table_field_from_def(TABLE_SHARE *share, MEM_ROOT *mem_root,
const LEX_CSTRING *name,
const Record_addr &rec, const Bit_addr &bit,
const Column_definition_attributes *attr,
uint32 flags) const
{
return new (mem_root)
Field_short(rec.ptr(), (uint32) attr->length,
rec.null_ptr(), rec.null_bit(),
attr->unireg_check, name,
f_is_zerofill(attr->pack_flag) != 0,
f_is_dec(attr->pack_flag) == 0);
}
Field *Type_handler_int24::
make_table_field_from_def(TABLE_SHARE *share, MEM_ROOT *mem_root,
const LEX_CSTRING *name,
const Record_addr &rec, const Bit_addr &bit,
const Column_definition_attributes *attr,
uint32 flags) const
{
return new (mem_root)
Field_medium(rec.ptr(), (uint32) attr->length,
rec.null_ptr(), rec.null_bit(),
attr->unireg_check, name,
f_is_zerofill(attr->pack_flag) != 0,
f_is_dec(attr->pack_flag) == 0);
}
Field *Type_handler_long::
make_table_field_from_def(TABLE_SHARE *share, MEM_ROOT *mem_root,
const LEX_CSTRING *name,
const Record_addr &rec, const Bit_addr &bit,
const Column_definition_attributes *attr,
uint32 flags) const
{
return new (mem_root)
Field_long(rec.ptr(), (uint32) attr->length, rec.null_ptr(), rec.null_bit(),
attr->unireg_check, name,
f_is_zerofill(attr->pack_flag) != 0,
f_is_dec(attr->pack_flag) == 0);
}
Field *Type_handler_longlong::
make_table_field_from_def(TABLE_SHARE *share, MEM_ROOT *mem_root,
const LEX_CSTRING *name,
const Record_addr &rec, const Bit_addr &bit,
const Column_definition_attributes *attr,
uint32 flags) const
{
if (flags & (VERS_SYS_START_FLAG|VERS_SYS_END_FLAG))
return new (mem_root)
Field_vers_trx_id(rec.ptr(), (uint32) attr->length,
rec.null_ptr(), rec.null_bit(),
attr->unireg_check, name,
f_is_zerofill(attr->pack_flag) != 0,
f_is_dec(attr->pack_flag) == 0);
return new (mem_root)
Field_longlong(rec.ptr(), (uint32) attr->length,
rec.null_ptr(), rec.null_bit(),
attr->unireg_check, name,
f_is_zerofill(attr->pack_flag) != 0,
f_is_dec(attr->pack_flag) == 0);
}
Field *Type_handler_timestamp::
make_table_field_from_def(TABLE_SHARE *share, MEM_ROOT *mem_root,
const LEX_CSTRING *name,
const Record_addr &rec, const Bit_addr &bit,
const Column_definition_attributes *attr,
uint32 flags) const
{
return new_Field_timestamp(mem_root,
rec.ptr(), rec.null_ptr(), rec.null_bit(),
attr->unireg_check, name, share,
attr->temporal_dec(MAX_DATETIME_WIDTH));
}
Field *Type_handler_timestamp2::
make_table_field_from_def(TABLE_SHARE *share, MEM_ROOT *mem_root,
const LEX_CSTRING *name,
const Record_addr &rec, const Bit_addr &bit,
const Column_definition_attributes *attr,
uint32 flags) const
{
return new (mem_root)
Field_timestampf(rec.ptr(), rec.null_ptr(), rec.null_bit(),
attr->unireg_check,
name, share, attr->temporal_dec(MAX_DATETIME_WIDTH));
}
Field *Type_handler_year::
make_table_field_from_def(TABLE_SHARE *share, MEM_ROOT *mem_root,
const LEX_CSTRING *name,
const Record_addr &rec, const Bit_addr &bit,
const Column_definition_attributes *attr,
uint32 flags) const
{
return new (mem_root)
Field_year(rec.ptr(), (uint32) attr->length, rec.null_ptr(), rec.null_bit(),
attr->unireg_check, name);
}
Field *Type_handler_date::
make_table_field_from_def(TABLE_SHARE *share, MEM_ROOT *mem_root,
const LEX_CSTRING *name,
const Record_addr &rec, const Bit_addr &bit,
const Column_definition_attributes *attr,
uint32 flags) const
{
return new (mem_root)
Field_date(rec.ptr(),rec.null_ptr(),rec.null_bit(),
attr->unireg_check, name);
}
Field *Type_handler_newdate::
make_table_field_from_def(TABLE_SHARE *share, MEM_ROOT *mem_root,
const LEX_CSTRING *name,
const Record_addr &rec, const Bit_addr &bit,
const Column_definition_attributes *attr,
uint32 flags) const
{
return new (mem_root)
Field_newdate(rec.ptr(), rec.null_ptr(), rec.null_bit(),
attr->unireg_check, name);
}
Field *Type_handler_time::
make_table_field_from_def(TABLE_SHARE *share, MEM_ROOT *mem_root,
const LEX_CSTRING *name,
const Record_addr &rec, const Bit_addr &bit,
const Column_definition_attributes *attr,
uint32 flags) const
{
return new_Field_time(mem_root, rec.ptr(), rec.null_ptr(), rec.null_bit(),
attr->unireg_check, name,
attr->temporal_dec(MIN_TIME_WIDTH));
}
Field *Type_handler_time2::
make_table_field_from_def(TABLE_SHARE *share, MEM_ROOT *mem_root,
const LEX_CSTRING *name,
const Record_addr &rec, const Bit_addr &bit,
const Column_definition_attributes *attr,
uint32 flags) const
{
return new (mem_root)
Field_timef(rec.ptr(), rec.null_ptr(), rec.null_bit(),
attr->unireg_check, name,
attr->temporal_dec(MIN_TIME_WIDTH));
}
Field *Type_handler_datetime::
make_table_field_from_def(TABLE_SHARE *share, MEM_ROOT *mem_root,
const LEX_CSTRING *name,
const Record_addr &rec, const Bit_addr &bit,
const Column_definition_attributes *attr,
uint32 flags) const
{
return new_Field_datetime(mem_root, rec.ptr(), rec.null_ptr(), rec.null_bit(),
attr->unireg_check, name,
attr->temporal_dec(MAX_DATETIME_WIDTH));
}
Field *Type_handler_datetime2::
make_table_field_from_def(TABLE_SHARE *share, MEM_ROOT *mem_root,
const LEX_CSTRING *name,
const Record_addr &rec, const Bit_addr &bit,
const Column_definition_attributes *attr,
uint32 flags) const
{
return new (mem_root)
Field_datetimef(rec.ptr(), rec.null_ptr(), rec.null_bit(),
attr->unireg_check, name,
attr->temporal_dec(MAX_DATETIME_WIDTH));
}
Field *Type_handler_null::
make_table_field_from_def(TABLE_SHARE *share, MEM_ROOT *mem_root,
const LEX_CSTRING *name,
const Record_addr &rec, const Bit_addr &bit,
const Column_definition_attributes *attr,
uint32 flags) const
{
return new (mem_root)
Field_null(rec.ptr(), (uint32) attr->length, attr->unireg_check,
name, attr->charset);
}
Field *Type_handler_bit::
make_table_field_from_def(TABLE_SHARE *share, MEM_ROOT *mem_root,
const LEX_CSTRING *name,
const Record_addr &rec, const Bit_addr &bit,
const Column_definition_attributes *attr,
uint32 flags) const
{
return f_bit_as_char(attr->pack_flag) ?
new (mem_root) Field_bit_as_char(rec.ptr(), (uint32) attr->length,
rec.null_ptr(), rec.null_bit(),
attr->unireg_check, name) :
new (mem_root) Field_bit(rec.ptr(), (uint32) attr->length,
rec.null_ptr(), rec.null_bit(),
bit.ptr(), bit.offs(), attr->unireg_check, name);
}
#ifdef HAVE_SPATIAL
Field *Type_handler_geometry::
make_table_field_from_def(TABLE_SHARE *share, MEM_ROOT *mem_root,
const LEX_CSTRING *name,
const Record_addr &rec, const Bit_addr &bit,
const Column_definition_attributes *attr,
uint32 flags) const
{
status_var_increment(current_thd->status_var.feature_gis);
return new (mem_root)
Field_geom(rec.ptr(), rec.null_ptr(), rec.null_bit(),
attr->unireg_check, name, share,
attr->pack_flag_to_pack_length(), attr->geom_type, attr->srid);
}
#endif
Field *Type_handler_string::
make_table_field_from_def(TABLE_SHARE *share, MEM_ROOT *mem_root,
const LEX_CSTRING *name,
const Record_addr &rec, const Bit_addr &bit,
const Column_definition_attributes *attr,
uint32 flags) const
{
return new (mem_root)
Field_string(rec.ptr(), (uint32) attr->length,
rec.null_ptr(), rec.null_bit(),
attr->unireg_check, name, attr->charset);
}
Field *Type_handler_varchar::
make_table_field_from_def(TABLE_SHARE *share, MEM_ROOT *mem_root,
const LEX_CSTRING *name,
const Record_addr &rec, const Bit_addr &bit,
const Column_definition_attributes *attr,
uint32 flags) const
{
if (attr->unireg_check == Field::TMYSQL_COMPRESSED)
return new (mem_root)
Field_varstring_compressed(rec.ptr(), (uint32) attr->length,
HA_VARCHAR_PACKLENGTH((uint32) attr->length),
rec.null_ptr(), rec.null_bit(),
attr->unireg_check, name, share, attr->charset,
zlib_compression_method);
return new (mem_root)
Field_varstring(rec.ptr(), (uint32) attr->length,
HA_VARCHAR_PACKLENGTH((uint32) attr->length),
rec.null_ptr(), rec.null_bit(),
attr->unireg_check, name, share, attr->charset);
}
Field *Type_handler_blob_common::
make_table_field_from_def(TABLE_SHARE *share, MEM_ROOT *mem_root,
const LEX_CSTRING *name,
const Record_addr &rec, const Bit_addr &bit,
const Column_definition_attributes *attr,
uint32 flags) const
{
if (attr->unireg_check == Field::TMYSQL_COMPRESSED)
return new (mem_root)
Field_blob_compressed(rec.ptr(), rec.null_ptr(), rec.null_bit(),
attr->unireg_check, name, share,
attr->pack_flag_to_pack_length(), attr->charset,
zlib_compression_method);
return new (mem_root)
Field_blob(rec.ptr(), rec.null_ptr(), rec.null_bit(),
attr->unireg_check, name, share,
attr->pack_flag_to_pack_length(), attr->charset);
}
Field *Type_handler_enum::
make_table_field_from_def(TABLE_SHARE *share, MEM_ROOT *mem_root,
const LEX_CSTRING *name,
const Record_addr &rec, const Bit_addr &bit,
const Column_definition_attributes *attr,
uint32 flags) const
{
return new (mem_root)
Field_enum(rec.ptr(), (uint32) attr->length, rec.null_ptr(), rec.null_bit(),
attr->unireg_check, name, attr->pack_flag_to_pack_length(),
attr->interval, attr->charset);
}
Field *Type_handler_set::
make_table_field_from_def(TABLE_SHARE *share, MEM_ROOT *mem_root,
const LEX_CSTRING *name,
const Record_addr &rec, const Bit_addr &bit,
const Column_definition_attributes *attr,
uint32 flags) const
{
return new (mem_root)
Field_set(rec.ptr(), (uint32) attr->length, rec.null_ptr(), rec.null_bit(),
attr->unireg_check, name, attr->pack_flag_to_pack_length(),
attr->interval, attr->charset);
}
/***************************************************************************/
void Type_handler::
Column_definition_attributes_frm_pack(const Column_definition_attributes *def,
uchar *buff) const
{
def->frm_pack_basic(buff);
def->frm_pack_charset(buff);
}
#ifdef HAVE_SPATIAL
void Type_handler_geometry::
Column_definition_attributes_frm_pack(const Column_definition_attributes *def,
uchar *buff) const
{
def->frm_pack_basic(buff);
buff[11]= 0;
buff[14]= (uchar) def->geom_type;
}
#endif
/***************************************************************************/
bool Type_handler::
Column_definition_attributes_frm_unpack(Column_definition_attributes *attr,
TABLE_SHARE *share,
const uchar *buffer,
LEX_CUSTRING *gis_options)
const
{
attr->frm_unpack_basic(buffer);
return attr->frm_unpack_charset(share, buffer);
}
#ifdef HAVE_SPATIAL
bool Type_handler_geometry::
Column_definition_attributes_frm_unpack(Column_definition_attributes *attr,
TABLE_SHARE *share,
const uchar *buffer,
LEX_CUSTRING *gis_options)
const
{
uint gis_opt_read, gis_length, gis_decimals;
Field_geom::storage_type st_type;
attr->frm_unpack_basic(buffer);
// charset and geometry_type share the same byte in frm
attr->geom_type= (Field::geometry_type) buffer[14];
gis_opt_read= gis_field_options_read(gis_options->str,
gis_options->length,
&st_type, &gis_length,
&gis_decimals, &attr->srid);
gis_options->str+= gis_opt_read;
gis_options->length-= gis_opt_read;
return false;
}
#endif
/***************************************************************************/
...@@ -28,6 +28,7 @@ ...@@ -28,6 +28,7 @@
class Field; class Field;
class Column_definition; class Column_definition;
class Column_definition_attributes;
class Item; class Item;
class Item_param; class Item_param;
class Item_cache; class Item_cache;
...@@ -1179,6 +1180,23 @@ class Type_handler ...@@ -1179,6 +1180,23 @@ class Type_handler
const Record_addr &addr, const Record_addr &addr,
const Type_all_attributes &attr, const Type_all_attributes &attr,
TABLE *table) const; TABLE *table) const;
virtual Field *
make_table_field_from_def(TABLE_SHARE *share,
MEM_ROOT *mem_root,
const LEX_CSTRING *name,
const Record_addr &addr,
const Bit_addr &bit,
const Column_definition_attributes *attr,
uint32 flags) const= 0;
virtual void
Column_definition_attributes_frm_pack(const Column_definition_attributes *at,
uchar *buff) const;
virtual bool
Column_definition_attributes_frm_unpack(Column_definition_attributes *attr,
TABLE_SHARE *share,
const uchar *buffer,
LEX_CUSTRING *gis_options) const;
virtual void make_sort_key(uchar *to, Item *item, virtual void make_sort_key(uchar *to, Item *item,
const SORT_FIELD_ATTR *sort_field, const SORT_FIELD_ATTR *sort_field,
Sort_param *param) const= 0; Sort_param *param) const= 0;
...@@ -1465,6 +1483,13 @@ class Type_handler_row: public Type_handler ...@@ -1465,6 +1483,13 @@ class Type_handler_row: public Type_handler
DBUG_ASSERT(0); DBUG_ASSERT(0);
return NULL; return NULL;
} }
Field *make_table_field_from_def(TABLE_SHARE *share,
MEM_ROOT *mem_root,
const LEX_CSTRING *name,
const Record_addr &addr,
const Bit_addr &bit,
const Column_definition_attributes *attr,
uint32 flags) const;
void make_sort_key(uchar *to, Item *item, void make_sort_key(uchar *to, Item *item,
const SORT_FIELD_ATTR *sort_field, const SORT_FIELD_ATTR *sort_field,
Sort_param *param) const Sort_param *param) const
...@@ -2189,6 +2214,13 @@ class Type_handler_tiny: public Type_handler_general_purpose_int ...@@ -2189,6 +2214,13 @@ class Type_handler_tiny: public Type_handler_general_purpose_int
const Record_addr &addr, const Record_addr &addr,
const Type_all_attributes &attr, const Type_all_attributes &attr,
TABLE *table) const; TABLE *table) const;
Field *make_table_field_from_def(TABLE_SHARE *share,
MEM_ROOT *mem_root,
const LEX_CSTRING *name,
const Record_addr &addr,
const Bit_addr &bit,
const Column_definition_attributes *attr,
uint32 flags) const;
void Item_param_set_param_func(Item_param *param, void Item_param_set_param_func(Item_param *param,
uchar **pos, ulong len) const; uchar **pos, ulong len) const;
}; };
...@@ -2218,6 +2250,13 @@ class Type_handler_short: public Type_handler_general_purpose_int ...@@ -2218,6 +2250,13 @@ class Type_handler_short: public Type_handler_general_purpose_int
const Record_addr &addr, const Record_addr &addr,
const Type_all_attributes &attr, const Type_all_attributes &attr,
TABLE *table) const; TABLE *table) const;
Field *make_table_field_from_def(TABLE_SHARE *share,
MEM_ROOT *mem_root,
const LEX_CSTRING *name,
const Record_addr &addr,
const Bit_addr &bit,
const Column_definition_attributes *attr,
uint32 flags) const;
void Item_param_set_param_func(Item_param *param, void Item_param_set_param_func(Item_param *param,
uchar **pos, ulong len) const; uchar **pos, ulong len) const;
}; };
...@@ -2250,6 +2289,13 @@ class Type_handler_long: public Type_handler_general_purpose_int ...@@ -2250,6 +2289,13 @@ class Type_handler_long: public Type_handler_general_purpose_int
const Record_addr &addr, const Record_addr &addr,
const Type_all_attributes &attr, const Type_all_attributes &attr,
TABLE *table) const; TABLE *table) const;
Field *make_table_field_from_def(TABLE_SHARE *share,
MEM_ROOT *mem_root,
const LEX_CSTRING *name,
const Record_addr &addr,
const Bit_addr &bit,
const Column_definition_attributes *attr,
uint32 flags) const;
void Item_param_set_param_func(Item_param *param, void Item_param_set_param_func(Item_param *param,
uchar **pos, ulong len) const; uchar **pos, ulong len) const;
}; };
...@@ -2283,6 +2329,13 @@ class Type_handler_longlong: public Type_handler_general_purpose_int ...@@ -2283,6 +2329,13 @@ class Type_handler_longlong: public Type_handler_general_purpose_int
const Record_addr &addr, const Record_addr &addr,
const Type_all_attributes &attr, const Type_all_attributes &attr,
TABLE *table) const; TABLE *table) const;
Field *make_table_field_from_def(TABLE_SHARE *share,
MEM_ROOT *mem_root,
const LEX_CSTRING *name,
const Record_addr &addr,
const Bit_addr &bit,
const Column_definition_attributes *attr,
uint32 flags) const;
void Item_param_set_param_func(Item_param *param, void Item_param_set_param_func(Item_param *param,
uchar **pos, ulong len) const; uchar **pos, ulong len) const;
}; };
...@@ -2323,6 +2376,13 @@ class Type_handler_int24: public Type_handler_general_purpose_int ...@@ -2323,6 +2376,13 @@ class Type_handler_int24: public Type_handler_general_purpose_int
const Record_addr &addr, const Record_addr &addr,
const Type_all_attributes &attr, const Type_all_attributes &attr,
TABLE *table) const; TABLE *table) const;
Field *make_table_field_from_def(TABLE_SHARE *share,
MEM_ROOT *mem_root,
const LEX_CSTRING *name,
const Record_addr &addr,
const Bit_addr &bit,
const Column_definition_attributes *attr,
uint32 flags) const;
}; };
...@@ -2350,6 +2410,13 @@ class Type_handler_year: public Type_handler_int_result ...@@ -2350,6 +2410,13 @@ class Type_handler_year: public Type_handler_int_result
const Record_addr &addr, const Record_addr &addr,
const Type_all_attributes &attr, const Type_all_attributes &attr,
TABLE *table) const; TABLE *table) const;
Field *make_table_field_from_def(TABLE_SHARE *share,
MEM_ROOT *mem_root,
const LEX_CSTRING *name,
const Record_addr &addr,
const Bit_addr &bit,
const Column_definition_attributes *attr,
uint32 flags) const;
Item_cache *Item_get_cache(THD *thd, const Item *item) const; Item_cache *Item_get_cache(THD *thd, const Item *item) const;
bool Item_get_date(Item *item, MYSQL_TIME *ltime, ulonglong fuzzydate) const; bool Item_get_date(Item *item, MYSQL_TIME *ltime, ulonglong fuzzydate) const;
}; };
...@@ -2392,6 +2459,13 @@ class Type_handler_bit: public Type_handler_int_result ...@@ -2392,6 +2459,13 @@ class Type_handler_bit: public Type_handler_int_result
const Record_addr &addr, const Record_addr &addr,
const Type_all_attributes &attr, const Type_all_attributes &attr,
TABLE *table) const; TABLE *table) const;
Field *make_table_field_from_def(TABLE_SHARE *share,
MEM_ROOT *mem_root,
const LEX_CSTRING *name,
const Record_addr &addr,
const Bit_addr &bit,
const Column_definition_attributes *attr,
uint32 flags) const;
}; };
...@@ -2421,6 +2495,13 @@ class Type_handler_float: public Type_handler_real_result ...@@ -2421,6 +2495,13 @@ class Type_handler_float: public Type_handler_real_result
const Record_addr &addr, const Record_addr &addr,
const Type_all_attributes &attr, const Type_all_attributes &attr,
TABLE *table) const; TABLE *table) const;
Field *make_table_field_from_def(TABLE_SHARE *share,
MEM_ROOT *mem_root,
const LEX_CSTRING *name,
const Record_addr &addr,
const Bit_addr &bit,
const Column_definition_attributes *attr,
uint32 flags) const;
void Item_param_set_param_func(Item_param *param, void Item_param_set_param_func(Item_param *param,
uchar **pos, ulong len) const; uchar **pos, ulong len) const;
}; };
...@@ -2453,6 +2534,13 @@ class Type_handler_double: public Type_handler_real_result ...@@ -2453,6 +2534,13 @@ class Type_handler_double: public Type_handler_real_result
const Record_addr &addr, const Record_addr &addr,
const Type_all_attributes &attr, const Type_all_attributes &attr,
TABLE *table) const; TABLE *table) const;
Field *make_table_field_from_def(TABLE_SHARE *share,
MEM_ROOT *mem_root,
const LEX_CSTRING *name,
const Record_addr &addr,
const Bit_addr &bit,
const Column_definition_attributes *attr,
uint32 flags) const;
void Item_param_set_param_func(Item_param *param, void Item_param_set_param_func(Item_param *param,
uchar **pos, ulong len) const; uchar **pos, ulong len) const;
}; };
...@@ -2536,6 +2624,13 @@ class Type_handler_time: public Type_handler_time_common ...@@ -2536,6 +2624,13 @@ class Type_handler_time: public Type_handler_time_common
const Record_addr &addr, const Record_addr &addr,
const Type_all_attributes &attr, const Type_all_attributes &attr,
TABLE *table) const; TABLE *table) const;
Field *make_table_field_from_def(TABLE_SHARE *share,
MEM_ROOT *mem_root,
const LEX_CSTRING *name,
const Record_addr &addr,
const Bit_addr &bit,
const Column_definition_attributes *attr,
uint32 flags) const;
}; };
...@@ -2555,6 +2650,13 @@ class Type_handler_time2: public Type_handler_time_common ...@@ -2555,6 +2650,13 @@ class Type_handler_time2: public Type_handler_time_common
const Record_addr &addr, const Record_addr &addr,
const Type_all_attributes &attr, const Type_all_attributes &attr,
TABLE *table) const; TABLE *table) const;
Field *make_table_field_from_def(TABLE_SHARE *share,
MEM_ROOT *mem_root,
const LEX_CSTRING *name,
const Record_addr &addr,
const Bit_addr &bit,
const Column_definition_attributes *attr,
uint32 flags) const;
}; };
...@@ -2617,6 +2719,13 @@ class Type_handler_date: public Type_handler_date_common ...@@ -2617,6 +2719,13 @@ class Type_handler_date: public Type_handler_date_common
const Record_addr &addr, const Record_addr &addr,
const Type_all_attributes &attr, const Type_all_attributes &attr,
TABLE *table) const; TABLE *table) const;
Field *make_table_field_from_def(TABLE_SHARE *share,
MEM_ROOT *mem_root,
const LEX_CSTRING *name,
const Record_addr &addr,
const Bit_addr &bit,
const Column_definition_attributes *attr,
uint32 flags) const;
}; };
...@@ -2636,6 +2745,13 @@ class Type_handler_newdate: public Type_handler_date_common ...@@ -2636,6 +2745,13 @@ class Type_handler_newdate: public Type_handler_date_common
const Record_addr &addr, const Record_addr &addr,
const Type_all_attributes &attr, const Type_all_attributes &attr,
TABLE *table) const; TABLE *table) const;
Field *make_table_field_from_def(TABLE_SHARE *share,
MEM_ROOT *mem_root,
const LEX_CSTRING *name,
const Record_addr &addr,
const Bit_addr &bit,
const Column_definition_attributes *attr,
uint32 flags) const;
}; };
...@@ -2697,6 +2813,13 @@ class Type_handler_datetime: public Type_handler_datetime_common ...@@ -2697,6 +2813,13 @@ class Type_handler_datetime: public Type_handler_datetime_common
const Record_addr &addr, const Record_addr &addr,
const Type_all_attributes &attr, const Type_all_attributes &attr,
TABLE *table) const; TABLE *table) const;
Field *make_table_field_from_def(TABLE_SHARE *share,
MEM_ROOT *mem_root,
const LEX_CSTRING *name,
const Record_addr &addr,
const Bit_addr &bit,
const Column_definition_attributes *attr,
uint32 flags) const;
}; };
...@@ -2716,6 +2839,13 @@ class Type_handler_datetime2: public Type_handler_datetime_common ...@@ -2716,6 +2839,13 @@ class Type_handler_datetime2: public Type_handler_datetime_common
const Record_addr &addr, const Record_addr &addr,
const Type_all_attributes &attr, const Type_all_attributes &attr,
TABLE *table) const; TABLE *table) const;
Field *make_table_field_from_def(TABLE_SHARE *share,
MEM_ROOT *mem_root,
const LEX_CSTRING *name,
const Record_addr &addr,
const Bit_addr &bit,
const Column_definition_attributes *attr,
uint32 flags) const;
}; };
...@@ -2779,6 +2909,13 @@ class Type_handler_timestamp: public Type_handler_timestamp_common ...@@ -2779,6 +2909,13 @@ class Type_handler_timestamp: public Type_handler_timestamp_common
const Record_addr &addr, const Record_addr &addr,
const Type_all_attributes &attr, const Type_all_attributes &attr,
TABLE *table) const; TABLE *table) const;
Field *make_table_field_from_def(TABLE_SHARE *share,
MEM_ROOT *mem_root,
const LEX_CSTRING *name,
const Record_addr &addr,
const Bit_addr &bit,
const Column_definition_attributes *attr,
uint32 flags) const;
}; };
...@@ -2800,6 +2937,13 @@ class Type_handler_timestamp2: public Type_handler_timestamp_common ...@@ -2800,6 +2937,13 @@ class Type_handler_timestamp2: public Type_handler_timestamp_common
const Record_addr &addr, const Record_addr &addr,
const Type_all_attributes &attr, const Type_all_attributes &attr,
TABLE *table) const; TABLE *table) const;
Field *make_table_field_from_def(TABLE_SHARE *share,
MEM_ROOT *mem_root,
const LEX_CSTRING *name,
const Record_addr &addr,
const Bit_addr &bit,
const Column_definition_attributes *attr,
uint32 flags) const;
}; };
...@@ -2824,6 +2968,13 @@ class Type_handler_olddecimal: public Type_handler_decimal_result ...@@ -2824,6 +2968,13 @@ class Type_handler_olddecimal: public Type_handler_decimal_result
const Record_addr &addr, const Record_addr &addr,
const Type_all_attributes &attr, const Type_all_attributes &attr,
TABLE *table) const; TABLE *table) const;
Field *make_table_field_from_def(TABLE_SHARE *share,
MEM_ROOT *mem_root,
const LEX_CSTRING *name,
const Record_addr &addr,
const Bit_addr &bit,
const Column_definition_attributes *attr,
uint32 flags) const;
}; };
...@@ -2855,6 +3006,13 @@ class Type_handler_newdecimal: public Type_handler_decimal_result ...@@ -2855,6 +3006,13 @@ class Type_handler_newdecimal: public Type_handler_decimal_result
const Record_addr &addr, const Record_addr &addr,
const Type_all_attributes &attr, const Type_all_attributes &attr,
TABLE *table) const; TABLE *table) const;
Field *make_table_field_from_def(TABLE_SHARE *share,
MEM_ROOT *mem_root,
const LEX_CSTRING *name,
const Record_addr &addr,
const Bit_addr &bit,
const Column_definition_attributes *attr,
uint32 flags) const;
}; };
...@@ -2893,6 +3051,13 @@ class Type_handler_null: public Type_handler_general_purpose_string ...@@ -2893,6 +3051,13 @@ class Type_handler_null: public Type_handler_general_purpose_string
const Record_addr &addr, const Record_addr &addr,
const Type_all_attributes &attr, const Type_all_attributes &attr,
TABLE *table) const; TABLE *table) const;
Field *make_table_field_from_def(TABLE_SHARE *share,
MEM_ROOT *mem_root,
const LEX_CSTRING *name,
const Record_addr &addr,
const Bit_addr &bit,
const Column_definition_attributes *attr,
uint32 flags) const;
}; };
...@@ -2929,6 +3094,13 @@ class Type_handler_string: public Type_handler_longstr ...@@ -2929,6 +3094,13 @@ class Type_handler_string: public Type_handler_longstr
const Record_addr &addr, const Record_addr &addr,
const Type_all_attributes &attr, const Type_all_attributes &attr,
TABLE *table) const; TABLE *table) const;
Field *make_table_field_from_def(TABLE_SHARE *share,
MEM_ROOT *mem_root,
const LEX_CSTRING *name,
const Record_addr &addr,
const Bit_addr &bit,
const Column_definition_attributes *attr,
uint32 flags) const;
}; };
...@@ -2987,6 +3159,13 @@ class Type_handler_varchar: public Type_handler_longstr ...@@ -2987,6 +3159,13 @@ class Type_handler_varchar: public Type_handler_longstr
const Record_addr &addr, const Record_addr &addr,
const Type_all_attributes &attr, const Type_all_attributes &attr,
TABLE *table) const; TABLE *table) const;
Field *make_table_field_from_def(TABLE_SHARE *share,
MEM_ROOT *mem_root,
const LEX_CSTRING *name,
const Record_addr &addr,
const Bit_addr &bit,
const Column_definition_attributes *attr,
uint32 flags) const;
bool adjust_spparam_type(Spvar_definition *def, Item *from) const; bool adjust_spparam_type(Spvar_definition *def, Item *from) const;
}; };
...@@ -3030,6 +3209,13 @@ class Type_handler_blob_common: public Type_handler_longstr ...@@ -3030,6 +3209,13 @@ class Type_handler_blob_common: public Type_handler_longstr
Item **items, uint nitems) const; Item **items, uint nitems) const;
void Item_param_setup_conversion(THD *thd, Item_param *) const; void Item_param_setup_conversion(THD *thd, Item_param *) const;
Field *make_table_field_from_def(TABLE_SHARE *share,
MEM_ROOT *mem_root,
const LEX_CSTRING *name,
const Record_addr &addr,
const Bit_addr &bit,
const Column_definition_attributes *attr,
uint32 flags) const;
}; };
...@@ -3131,6 +3317,14 @@ class Type_handler_geometry: public Type_handler_string_result ...@@ -3131,6 +3317,14 @@ class Type_handler_geometry: public Type_handler_string_result
const st_value *value) const; const st_value *value) const;
Field *make_conversion_table_field(TABLE *, uint metadata, Field *make_conversion_table_field(TABLE *, uint metadata,
const Field *target) const; const Field *target) const;
void
Column_definition_attributes_frm_pack(const Column_definition_attributes *at,
uchar *buff) const;
bool
Column_definition_attributes_frm_unpack(Column_definition_attributes *attr,
TABLE_SHARE *share,
const uchar *buffer,
LEX_CUSTRING *gis_options) const;
bool Column_definition_fix_attributes(Column_definition *c) const; bool Column_definition_fix_attributes(Column_definition *c) const;
bool Column_definition_prepare_stage1(THD *thd, bool Column_definition_prepare_stage1(THD *thd,
MEM_ROOT *mem_root, MEM_ROOT *mem_root,
...@@ -3145,6 +3339,14 @@ class Type_handler_geometry: public Type_handler_string_result ...@@ -3145,6 +3339,14 @@ class Type_handler_geometry: public Type_handler_string_result
const Type_all_attributes &attr, const Type_all_attributes &attr,
TABLE *table) const; TABLE *table) const;
Field *make_table_field_from_def(TABLE_SHARE *share,
MEM_ROOT *mem_root,
const LEX_CSTRING *name,
const Record_addr &addr,
const Bit_addr &bit,
const Column_definition_attributes *attr,
uint32 flags) const;
bool can_return_int() const { return false; } bool can_return_int() const { return false; }
bool can_return_decimal() const { return false; } bool can_return_decimal() const { return false; }
bool can_return_real() const { return false; } bool can_return_real() const { return false; }
...@@ -3227,6 +3429,13 @@ class Type_handler_enum: public Type_handler_typelib ...@@ -3227,6 +3429,13 @@ class Type_handler_enum: public Type_handler_typelib
const Record_addr &addr, const Record_addr &addr,
const Type_all_attributes &attr, const Type_all_attributes &attr,
TABLE *table) const; TABLE *table) const;
Field *make_table_field_from_def(TABLE_SHARE *share,
MEM_ROOT *mem_root,
const LEX_CSTRING *name,
const Record_addr &addr,
const Bit_addr &bit,
const Column_definition_attributes *attr,
uint32 flags) const;
}; };
...@@ -3248,6 +3457,13 @@ class Type_handler_set: public Type_handler_typelib ...@@ -3248,6 +3457,13 @@ class Type_handler_set: public Type_handler_typelib
const Record_addr &addr, const Record_addr &addr,
const Type_all_attributes &attr, const Type_all_attributes &attr,
TABLE *table) const; TABLE *table) const;
Field *make_table_field_from_def(TABLE_SHARE *share,
MEM_ROOT *mem_root,
const LEX_CSTRING *name,
const Record_addr &addr,
const Bit_addr &bit,
const Column_definition_attributes *attr,
uint32 flags) const;
}; };
......
...@@ -915,6 +915,54 @@ static uint upgrade_collation(ulong mysql_version, uint cs_number) ...@@ -915,6 +915,54 @@ static uint upgrade_collation(ulong mysql_version, uint cs_number)
} }
void Column_definition_attributes::frm_pack_basic(uchar *buff) const
{
int2store(buff + 3, length);
int2store(buff + 8, pack_flag);
buff[10]= (uchar) unireg_check;
}
void Column_definition_attributes::frm_unpack_basic(const uchar *buff)
{
length= uint2korr(buff + 3);
pack_flag= uint2korr(buff + 8);
unireg_check= (Field::utype) MTYP_TYPENR((uint) buff[10]);
}
void Column_definition_attributes::frm_pack_charset(uchar *buff) const
{
buff[11]= (uchar) (charset->number >> 8);
buff[14]= (uchar) charset->number;
}
bool Column_definition_attributes::frm_unpack_charset(TABLE_SHARE *share,
const uchar *buff)
{
uint cs_org= buff[14] + (((uint) buff[11]) << 8);
uint cs_new= upgrade_collation(share->mysql_version, cs_org);
if (cs_org != cs_new)
share->incompatible_version|= HA_CREATE_USED_CHARSET;
if (cs_new && !(charset= get_charset(cs_new, MYF(0))))
{
const char *csname= get_charset_name((uint) cs_new);
char tmp[10];
if (!csname || csname[0] =='?')
{
my_snprintf(tmp, sizeof(tmp), "#%u", cs_new);
csname= tmp;
}
my_printf_error(ER_UNKNOWN_COLLATION,
"Unknown collation '%s' in table '%-.64s' definition",
MYF(0), csname, share->table_name.str);
return true;
}
return false;
}
/* /*
In MySQL 5.7 the null bits for not stored virtual fields are last. In MySQL 5.7 the null bits for not stored virtual fields are last.
Calculate the position for these bits Calculate the position for these bits
...@@ -1145,6 +1193,38 @@ bool parse_vcol_defs(THD *thd, MEM_ROOT *mem_root, TABLE *table, ...@@ -1145,6 +1193,38 @@ bool parse_vcol_defs(THD *thd, MEM_ROOT *mem_root, TABLE *table,
DBUG_RETURN(res); DBUG_RETURN(res);
} }
static const Type_handler *old_frm_type_handler(uint pack_flag,
uint interval_nr)
{
enum_field_types field_type= (enum_field_types) f_packtype(pack_flag);
DBUG_ASSERT(field_type < 16);
if (!f_is_alpha(pack_flag))
return Type_handler::get_handler_by_real_type(field_type);
if (!f_is_packed(pack_flag))
{
if (field_type == MYSQL_TYPE_DECIMAL) // 3.23 or 4.0 string
return &type_handler_string;
if (field_type == MYSQL_TYPE_VARCHAR) // Since mysql-5.0
return &type_handler_varchar;
return NULL; // Error (bad frm?)
}
if (f_is_blob(pack_flag))
return &type_handler_blob; // QQ: exact type??
if (interval_nr)
{
if (f_is_enum(pack_flag))
return &type_handler_enum;
return &type_handler_set;
}
return Type_handler::get_handler_by_real_type(field_type);
}
/** /**
Read data from a binary .frm file image into a TABLE_SHARE Read data from a binary .frm file image into a TABLE_SHARE
...@@ -1191,8 +1271,7 @@ int TABLE_SHARE::init_from_binary_frm_image(THD *thd, bool write, ...@@ -1191,8 +1271,7 @@ int TABLE_SHARE::init_from_binary_frm_image(THD *thd, bool write,
size_t UNINIT_VAR(options_len); size_t UNINIT_VAR(options_len);
uchar *vcol_screen_pos; uchar *vcol_screen_pos;
const uchar *options= 0; const uchar *options= 0;
size_t UNINIT_VAR(gis_options_len); LEX_CUSTRING gis_options= { NULL, 0};
const uchar *gis_options= 0;
KEY first_keyinfo; KEY first_keyinfo;
uint len; uint len;
uint ext_key_parts= 0; uint ext_key_parts= 0;
...@@ -1288,10 +1367,10 @@ int TABLE_SHARE::init_from_binary_frm_image(THD *thd, bool write, ...@@ -1288,10 +1367,10 @@ int TABLE_SHARE::init_from_binary_frm_image(THD *thd, bool write,
case EXTRA2_GIS: case EXTRA2_GIS:
#ifdef HAVE_SPATIAL #ifdef HAVE_SPATIAL
{ {
if (gis_options) if (gis_options.str)
goto err; goto err;
gis_options= extra2; gis_options.str= extra2;
gis_options_len= length; gis_options.length= length;
} }
#endif /*HAVE_SPATIAL*/ #endif /*HAVE_SPATIAL*/
break; break;
...@@ -1781,82 +1860,19 @@ int TABLE_SHARE::init_from_binary_frm_image(THD *thd, bool write, ...@@ -1781,82 +1860,19 @@ int TABLE_SHARE::init_from_binary_frm_image(THD *thd, bool write,
for (i=0 ; i < share->fields; i++, strpos+=field_pack_length, field_ptr++) for (i=0 ; i < share->fields; i++, strpos+=field_pack_length, field_ptr++)
{ {
uint pack_flag, interval_nr, unireg_type, recpos, field_length; uint interval_nr= 0, recpos;
uint vcol_info_length=0;
uint vcol_expr_length=0;
enum_field_types field_type;
CHARSET_INFO *charset=NULL;
Field::geometry_type geom_type= Field::GEOM_GEOMETRY;
LEX_CSTRING comment; LEX_CSTRING comment;
LEX_CSTRING name; LEX_CSTRING name;
Virtual_column_info *vcol_info= 0; Virtual_column_info *vcol_info= 0;
uint gis_length, gis_decimals, srid= 0;
Field::utype unireg_check;
const Type_handler *handler; const Type_handler *handler;
uint32 flags= 0; uint32 flags= 0;
Column_definition_attributes attr;
if (new_frm_ver >= 3) if (new_frm_ver >= 3)
{ {
/* new frm file in 4.1 */ /* new frm file in 4.1 */
field_length= uint2korr(strpos+3);
recpos= uint3korr(strpos+5); recpos= uint3korr(strpos+5);
pack_flag= uint2korr(strpos+8);
unireg_type= (uint) strpos[10];
interval_nr= (uint) strpos[12];
uint comment_length=uint2korr(strpos+15); uint comment_length=uint2korr(strpos+15);
field_type=(enum_field_types) (uint) strpos[13];
/* charset and geometry_type share the same byte in frm */
if (field_type == MYSQL_TYPE_GEOMETRY)
{
#ifdef HAVE_SPATIAL
uint gis_opt_read;
Field_geom::storage_type st_type;
geom_type= (Field::geometry_type) strpos[14];
charset= &my_charset_bin;
gis_opt_read= gis_field_options_read(gis_options, gis_options_len,
&st_type, &gis_length, &gis_decimals, &srid);
gis_options+= gis_opt_read;
gis_options_len-= gis_opt_read;
#else
goto err;
#endif
}
else
{
uint cs_org= strpos[14] + (((uint) strpos[11]) << 8);
uint cs_new= upgrade_collation(share->mysql_version, cs_org);
if (cs_org != cs_new)
share->incompatible_version|= HA_CREATE_USED_CHARSET;
if (!cs_new)
charset= &my_charset_bin;
else if (!(charset= get_charset(cs_new, MYF(0))))
{
const char *csname= get_charset_name((uint) cs_new);
char tmp[10];
if (!csname || csname[0] =='?')
{
my_snprintf(tmp, sizeof(tmp), "#%u", cs_new);
csname= tmp;
}
my_printf_error(ER_UNKNOWN_COLLATION,
"Unknown collation '%s' in table '%-.64s' definition",
MYF(0), csname, share->table_name.str);
goto err;
}
}
if ((uchar)field_type == (uchar)MYSQL_TYPE_VIRTUAL)
{
DBUG_ASSERT(interval_nr); // Expect non-null expression
/*
MariaDB version 10.0 version.
The interval_id byte in the .frm file stores the length of the
expression statement for a virtual column.
*/
vcol_info_length= interval_nr;
interval_nr= 0;
}
if (!comment_length) if (!comment_length)
{ {
...@@ -1870,32 +1886,20 @@ int TABLE_SHARE::init_from_binary_frm_image(THD *thd, bool write, ...@@ -1870,32 +1886,20 @@ int TABLE_SHARE::init_from_binary_frm_image(THD *thd, bool write,
comment_pos+= comment_length; comment_pos+= comment_length;
} }
if (unireg_type & MYSQL57_GENERATED_FIELD) if ((uchar) strpos[13] == (uchar) MYSQL_TYPE_VIRTUAL)
{ {
unireg_type&= MYSQL57_GENERATED_FIELD;
/* /*
MySQL 5.7 generated fields MariaDB version 10.0 version.
The interval_id byte in the .frm file stores the length of the
byte 1 = 1 expression statement for a virtual column.
byte 2,3 = expr length
byte 4 = stored_in_db
byte 5.. = expr
*/ */
if ((uint)(vcol_screen_pos)[0] != 1) uint vcol_info_length= (uint) strpos[12];
goto err;
vcol_info= new (&share->mem_root) Virtual_column_info();
vcol_info_length= uint2korr(vcol_screen_pos + 1);
DBUG_ASSERT(vcol_info_length);
vcol_info->stored_in_db= vcol_screen_pos[3];
vcol_info->utf8= 0;
vcol_screen_pos+= vcol_info_length + MYSQL57_GCOL_HEADER_SIZE;;
share->virtual_fields++;
vcol_info_length= 0;
}
if (vcol_info_length) DBUG_ASSERT(vcol_info_length); // Expect non-null expression
{
attr.frm_unpack_basic(strpos);
if (attr.frm_unpack_charset(share, strpos))
goto err;
/* /*
Old virtual field information before 10.2 Old virtual field information before 10.2
...@@ -1909,7 +1913,9 @@ int TABLE_SHARE::init_from_binary_frm_image(THD *thd, bool write, ...@@ -1909,7 +1913,9 @@ int TABLE_SHARE::init_from_binary_frm_image(THD *thd, bool write,
vcol_info= new (&share->mem_root) Virtual_column_info(); vcol_info= new (&share->mem_root) Virtual_column_info();
bool opt_interval_id= (uint)vcol_screen_pos[0] == 2; bool opt_interval_id= (uint)vcol_screen_pos[0] == 2;
field_type= (enum_field_types) (uchar) vcol_screen_pos[1]; enum_field_types ftype= (enum_field_types) (uchar) vcol_screen_pos[1];
if (!(handler= Type_handler::get_handler_by_real_type(ftype)))
goto err;
if (opt_interval_id) if (opt_interval_id)
interval_nr= (uint)vcol_screen_pos[3]; interval_nr= (uint)vcol_screen_pos[3];
else if ((uint)vcol_screen_pos[0] != 1) else if ((uint)vcol_screen_pos[0] != 1)
...@@ -1917,26 +1923,63 @@ int TABLE_SHARE::init_from_binary_frm_image(THD *thd, bool write, ...@@ -1917,26 +1923,63 @@ int TABLE_SHARE::init_from_binary_frm_image(THD *thd, bool write,
bool stored= vcol_screen_pos[2] & 1; bool stored= vcol_screen_pos[2] & 1;
vcol_info->stored_in_db= stored; vcol_info->stored_in_db= stored;
vcol_info->set_vcol_type(stored ? VCOL_GENERATED_STORED : VCOL_GENERATED_VIRTUAL); vcol_info->set_vcol_type(stored ? VCOL_GENERATED_STORED : VCOL_GENERATED_VIRTUAL);
vcol_expr_length= vcol_info_length - uint vcol_expr_length= vcol_info_length -
(uint)(FRM_VCOL_OLD_HEADER_SIZE(opt_interval_id)); (uint)(FRM_VCOL_OLD_HEADER_SIZE(opt_interval_id));
vcol_info->utf8= 0; // before 10.2.1 the charset was unknown vcol_info->utf8= 0; // before 10.2.1 the charset was unknown
int2store(vcol_screen_pos+1, vcol_expr_length); // for parse_vcol_defs() int2store(vcol_screen_pos+1, vcol_expr_length); // for parse_vcol_defs()
vcol_screen_pos+= vcol_info_length; vcol_screen_pos+= vcol_info_length;
share->virtual_fields++; share->virtual_fields++;
} }
else
{
interval_nr= (uint) strpos[12];
enum_field_types field_type= (enum_field_types) strpos[13];
if (!(handler= Type_handler::get_handler_by_real_type(field_type)))
goto err; // Not supported field type
if (handler->Column_definition_attributes_frm_unpack(&attr, share,
strpos,
&gis_options))
goto err;
}
if (((uint) strpos[10]) & MYSQL57_GENERATED_FIELD)
{
attr.unireg_check= Field::NONE;
/*
MySQL 5.7 generated fields
byte 1 = 1
byte 2,3 = expr length
byte 4 = stored_in_db
byte 5.. = expr
*/
if ((uint)(vcol_screen_pos)[0] != 1)
goto err;
vcol_info= new (&share->mem_root) Virtual_column_info();
uint vcol_info_length= uint2korr(vcol_screen_pos + 1);
DBUG_ASSERT(vcol_info_length);
vcol_info->stored_in_db= vcol_screen_pos[3];
vcol_info->utf8= 0;
vcol_screen_pos+= vcol_info_length + MYSQL57_GCOL_HEADER_SIZE;;
share->virtual_fields++;
}
} }
else else
{ {
field_length= (uint) strpos[3]; attr.length= (uint) strpos[3];
recpos= uint2korr(strpos+4), recpos= uint2korr(strpos+4),
pack_flag= uint2korr(strpos+6); attr.pack_flag= uint2korr(strpos+6);
pack_flag&= ~FIELDFLAG_NO_DEFAULT; // Safety for old files attr.pack_flag&= ~FIELDFLAG_NO_DEFAULT; // Safety for old files
unireg_type= (uint) strpos[8]; attr.unireg_check= (Field::utype) MTYP_TYPENR((uint) strpos[8]);
interval_nr= (uint) strpos[10]; interval_nr= (uint) strpos[10];
/* old frm file */ /* old frm file */
field_type= (enum_field_types) f_packtype(pack_flag); enum_field_types ftype= (enum_field_types) f_packtype(attr.pack_flag);
if (f_is_binary(pack_flag)) if (!(handler= Type_handler::get_handler_by_real_type(ftype)))
goto err; // Not supported field type
if (f_is_binary(attr.pack_flag))
{ {
/* /*
Try to choose the best 4.1 type: Try to choose the best 4.1 type:
...@@ -1944,26 +1987,26 @@ int TABLE_SHARE::init_from_binary_frm_image(THD *thd, bool write, ...@@ -1944,26 +1987,26 @@ int TABLE_SHARE::init_from_binary_frm_image(THD *thd, bool write,
try to find a binary collation for character set. try to find a binary collation for character set.
- for other types (e.g. BLOB) just use my_charset_bin. - for other types (e.g. BLOB) just use my_charset_bin.
*/ */
if (!f_is_blob(pack_flag)) if (!f_is_blob(attr.pack_flag))
{ {
// 3.23 or 4.0 string // 3.23 or 4.0 string
if (!(charset= get_charset_by_csname(share->table_charset->csname, if (!(attr.charset= get_charset_by_csname(share->table_charset->csname,
MY_CS_BINSORT, MYF(0)))) MY_CS_BINSORT, MYF(0))))
charset= &my_charset_bin; attr.charset= &my_charset_bin;
} }
else
charset= &my_charset_bin;
} }
else else
charset= share->table_charset; attr.charset= share->table_charset;
bzero((char*) &comment, sizeof(comment)); bzero((char*) &comment, sizeof(comment));
if ((!(handler= old_frm_type_handler(attr.pack_flag, interval_nr))))
goto err; // Not supported field type
} }
/* Remove >32 decimals from old files */ /* Remove >32 decimals from old files */
if (share->mysql_version < 100200) if (share->mysql_version < 100200)
pack_flag&= ~FIELDFLAG_LONG_DECIMAL; attr.pack_flag&= ~FIELDFLAG_LONG_DECIMAL;
if (interval_nr && charset->mbminlen > 1) if (interval_nr && attr.charset->mbminlen > 1)
{ {
/* Unescape UCS2 intervals from HEX notation */ /* Unescape UCS2 intervals from HEX notation */
TYPELIB *interval= share->intervals + interval_nr - 1; TYPELIB *interval= share->intervals + interval_nr - 1;
...@@ -1971,17 +2014,18 @@ int TABLE_SHARE::init_from_binary_frm_image(THD *thd, bool write, ...@@ -1971,17 +2014,18 @@ int TABLE_SHARE::init_from_binary_frm_image(THD *thd, bool write,
} }
#ifndef TO_BE_DELETED_ON_PRODUCTION #ifndef TO_BE_DELETED_ON_PRODUCTION
if (field_type == MYSQL_TYPE_NEWDECIMAL && !share->mysql_version) if (handler->real_field_type() == MYSQL_TYPE_NEWDECIMAL &&
!share->mysql_version)
{ {
/* /*
Fix pack length of old decimal values from 5.0.3 -> 5.0.4 Fix pack length of old decimal values from 5.0.3 -> 5.0.4
The difference is that in the old version we stored precision The difference is that in the old version we stored precision
in the .frm table while we now store the display_length in the .frm table while we now store the display_length
*/ */
uint decimals= f_decimals(pack_flag); uint decimals= f_decimals(attr.pack_flag);
field_length= my_decimal_precision_to_length(field_length, attr.length=
decimals, my_decimal_precision_to_length((uint) attr.length, decimals,
f_is_dec(pack_flag) == 0); f_is_dec(attr.pack_flag) == 0);
sql_print_error("Found incompatible DECIMAL field '%s' in %s; " sql_print_error("Found incompatible DECIMAL field '%s' in %s; "
"Please do \"ALTER TABLE '%s' FORCE\" to fix it!", "Please do \"ALTER TABLE '%s' FORCE\" to fix it!",
share->fieldnames.type_names[i], share->table_name.str, share->fieldnames.type_names[i], share->table_name.str,
...@@ -2012,7 +2056,7 @@ int TABLE_SHARE::init_from_binary_frm_image(THD *thd, bool write, ...@@ -2012,7 +2056,7 @@ int TABLE_SHARE::init_from_binary_frm_image(THD *thd, bool write,
if (flags & VERS_SYSTEM_FIELD) if (flags & VERS_SYSTEM_FIELD)
{ {
switch (field_type) switch (handler->real_field_type())
{ {
case MYSQL_TYPE_TIMESTAMP2: case MYSQL_TYPE_TIMESTAMP2:
case MYSQL_TYPE_DATETIME2: case MYSQL_TYPE_DATETIME2:
...@@ -2034,23 +2078,17 @@ int TABLE_SHARE::init_from_binary_frm_image(THD *thd, bool write, ...@@ -2034,23 +2078,17 @@ int TABLE_SHARE::init_from_binary_frm_image(THD *thd, bool write,
} }
/* Convert pre-10.2.2 timestamps to use Field::default_value */ /* Convert pre-10.2.2 timestamps to use Field::default_value */
unireg_check= (Field::utype) MTYP_TYPENR(unireg_type);
name.str= fieldnames.type_names[i]; name.str= fieldnames.type_names[i];
name.length= strlen(name.str); name.length= strlen(name.str);
if (!(handler= Type_handler::get_handler_by_real_type(field_type))) attr.interval= interval_nr ? share->intervals + interval_nr - 1 : NULL;
goto err; // Not supported field type
Record_addr addr(record + recpos, null_pos, null_bit_pos); Record_addr addr(record + recpos, null_pos, null_bit_pos);
*field_ptr= reg_field= *field_ptr= reg_field=
make_field(share, &share->mem_root, &addr, attr.make_field(share, &share->mem_root, &addr, handler, &name, flags);
(uint32) field_length, pack_flag, handler, charset,
geom_type, srid, unireg_check,
(interval_nr ? share->intervals + interval_nr - 1 : NULL),
&name, flags);
if (!reg_field) // Not supported field type if (!reg_field) // Not supported field type
goto err; goto err;
if (unireg_check == Field::TIMESTAMP_DNUN_FIELD || if (attr.unireg_check == Field::TIMESTAMP_DNUN_FIELD ||
unireg_check == Field::TIMESTAMP_DN_FIELD) attr.unireg_check == Field::TIMESTAMP_DN_FIELD)
{ {
reg_field->default_value= new (&share->mem_root) Virtual_column_info(); reg_field->default_value= new (&share->mem_root) Virtual_column_info();
reg_field->default_value->set_vcol_type(VCOL_DEFAULT); reg_field->default_value->set_vcol_type(VCOL_DEFAULT);
...@@ -2074,10 +2112,11 @@ int TABLE_SHARE::init_from_binary_frm_image(THD *thd, bool write, ...@@ -2074,10 +2112,11 @@ int TABLE_SHARE::init_from_binary_frm_image(THD *thd, bool write,
status_var_increment(thd->status_var.feature_invisible_columns); status_var_increment(thd->status_var.feature_invisible_columns);
if (!reg_field->invisible) if (!reg_field->invisible)
share->visible_fields++; share->visible_fields++;
if (field_type == MYSQL_TYPE_BIT && !f_bit_as_char(pack_flag)) if (handler->real_field_type() == MYSQL_TYPE_BIT &&
!f_bit_as_char(attr.pack_flag))
{ {
null_bits_are_used= 1; null_bits_are_used= 1;
if ((null_bit_pos+= field_length & 7) > 7) if ((null_bit_pos+= (uint) (attr.length & 7)) > 7)
{ {
null_pos++; null_pos++;
null_bit_pos-= 8; null_bit_pos-= 8;
...@@ -2100,7 +2139,7 @@ int TABLE_SHARE::init_from_binary_frm_image(THD *thd, bool write, ...@@ -2100,7 +2139,7 @@ int TABLE_SHARE::init_from_binary_frm_image(THD *thd, bool write,
} }
} }
if (f_no_default(pack_flag)) if (f_no_default(attr.pack_flag))
reg_field->flags|= NO_DEFAULT_VALUE_FLAG; reg_field->flags|= NO_DEFAULT_VALUE_FLAG;
if (reg_field->unireg_check == Field::NEXT_NUMBER) if (reg_field->unireg_check == Field::NEXT_NUMBER)
......
...@@ -897,32 +897,12 @@ static bool pack_fields(uchar **buff_arg, List<Create_field> &create_fields, ...@@ -897,32 +897,12 @@ static bool pack_fields(uchar **buff_arg, List<Create_field> &create_fields,
while ((field=it++)) while ((field=it++))
{ {
uint recpos; uint recpos;
int2store(buff+3, field->length);
/* The +1 is here becasue the col offset in .frm file have offset 1 */ /* The +1 is here becasue the col offset in .frm file have offset 1 */
recpos= field->offset+1 + (uint) data_offset; recpos= field->offset+1 + (uint) data_offset;
int3store(buff+5,recpos); int3store(buff+5,recpos);
int2store(buff+8,field->pack_flag);
buff[10]= (uchar) field->unireg_check;
buff[12]= (uchar) field->interval_id; buff[12]= (uchar) field->interval_id;
buff[13]= (uchar) field->real_field_type(); buff[13]= (uchar) field->type_handler()->real_field_type();
if (field->real_field_type() == MYSQL_TYPE_GEOMETRY) field->type_handler()->Column_definition_attributes_frm_pack(field, buff);
{
buff[11]= 0;
buff[14]= (uchar) field->geom_type;
#ifndef HAVE_SPATIAL
DBUG_ASSERT(0); // Should newer happen
#endif
}
else if (field->charset)
{
buff[11]= (uchar) (field->charset->number >> 8);
buff[14]= (uchar) field->charset->number;
}
else
{
buff[11]= buff[14]= 0; // Numerical
}
int2store(buff+15, field->comment.length); int2store(buff+15, field->comment.length);
comment_length+= field->comment.length; comment_length+= field->comment.length;
set_if_bigger(int_count,field->interval_id); set_if_bigger(int_count,field->interval_id);
...@@ -1045,18 +1025,14 @@ static bool make_empty_rec(THD *thd, uchar *buff, uint table_options, ...@@ -1045,18 +1025,14 @@ static bool make_empty_rec(THD *thd, uchar *buff, uint table_options,
{ {
Record_addr addr(buff + field->offset + data_offset, Record_addr addr(buff + field->offset + data_offset,
null_pos + null_count / 8, null_count & 7); null_pos + null_count / 8, null_count & 7);
Column_definition_attributes tmp(*field);
tmp.interval= field->save_interval ?
field->save_interval : field->interval;
/* regfield don't have to be deleted as it's allocated on THD::mem_root */ /* regfield don't have to be deleted as it's allocated on THD::mem_root */
Field *regfield= make_field(&share, thd->mem_root, &addr, Field *regfield= tmp.make_field(&share, thd->mem_root, &addr,
(uint32) field->length, field->type_handler(),
field->pack_flag, &field->field_name,
field->type_handler(), field->flags);
field->charset,
field->geom_type, field->srid,
field->unireg_check,
field->save_interval ? field->save_interval
: field->interval,
&field->field_name,
field->flags);
if (!regfield) if (!regfield)
{ {
error= 1; error= 1;
......
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