1
0
mirror of https://github.com/MariaDB/server.git synced 2025-07-29 05:21:33 +03:00

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

This commit is contained in:
Alexander Barkov
2018-05-24 14:47:04 +04:00
parent dc5802255d
commit f584557406
6 changed files with 972 additions and 465 deletions

View File

@ -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
{
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, MEM_ROOT *mem_root,
const Record_addr *rec, const Record_addr *rec,
uint32 field_length,
uint pack_flag,
const Type_handler *handler, 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, const LEX_CSTRING *field_name,
uint32 flags) 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,262 +10563,17 @@ 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));
return new (mem_root) Field_row(addr.ptr(), field_name);
}
if (f_is_alpha(pack_flag))
{
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()); Bit_addr bit(rec->null());
if (!f_bit_as_char(pack_flag) && f_maybe_null(pack_flag)) if (f_maybe_null(pack_flag))
bit.inc(); bit.inc();
return (f_bit_as_char(pack_flag) ? return handler->make_table_field_from_def(share, mem_root, field_name,
new (mem_root) addr, bit, this, flags);
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
{ {
@ -10815,25 +10581,33 @@ bool Field_vers_trx_id::test_if_equality_guarantees_uniqueness(const Item* 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;

View File

@ -4072,21 +4072,53 @@ public:
extern const LEX_CSTRING null_clex_str; extern const LEX_CSTRING null_clex_str;
class Column_definition_attributes
{
public:
/*
At various stages in execution this can be length of field in bytes or
max number of characters.
*/
ulonglong length;
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, Field *make_field(TABLE_SHARE *share, MEM_ROOT *mem_root,
const Record_addr *rec, const Record_addr *rec,
uint32 field_length, const Type_handler *handler,
uint pack_flag, const Type_handler *handler, const LEX_CSTRING *field_name,
CHARSET_INFO *cs, uint32 flags) const;
Field::geometry_type geom_type, uint srid, uint temporal_dec(uint intlen) const
Field::utype unireg_check, {
TYPELIB *interval, const LEX_CSTRING *field_name, return (uint) (length > intlen ? length - intlen - 1 : 0);
uint32 flags); }
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 @@ public:
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 @@ public:
*/ */
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 @@ public:
: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,9 +4335,8 @@ public:
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,
@ -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)

View File

@ -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
/***************************************************************************/

View File

@ -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 @@ public:
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 @@ public:
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 @@ public:
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 @@ public:
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 @@ public:
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 @@ public:
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 @@ public:
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 @@ public:
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 @@ public:
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 @@ public:
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 @@ public:
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 @@ public:
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 @@ public:
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 @@ public:
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 @@ public:
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 @@ public:
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 @@ public:
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 @@ public:
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 @@ public:
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 @@ public:
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 @@ public:
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 @@ public:
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 @@ public:
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 @@ public:
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 @@ public:
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 @@ public:
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 @@ public:
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 @@ public:
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 @@ public:
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;
}; };

View File

@ -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 @@ end:
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,
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,
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,
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,
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,
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,
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,
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 else
charset= &my_charset_bin; attr.charset= share->table_charset;
}
else
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,
} }
#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,
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,
} }
/* 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,
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,
} }
} }
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)

View File

@ -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,16 +1025,12 @@ 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->pack_flag,
field->type_handler(), field->type_handler(),
field->charset,
field->geom_type, field->srid,
field->unireg_check,
field->save_interval ? field->save_interval
: field->interval,
&field->field_name, &field->field_name,
field->flags); field->flags);
if (!regfield) if (!regfield)