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:
304
sql/field.cc
304
sql/field.cc
@ -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,
|
||||
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)
|
||||
const
|
||||
{
|
||||
DBUG_ASSERT(length <= UINT_MAX32);
|
||||
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_INTERVAL),
|
||||
FLAGSTR(pack_flag, FIELDFLAG_NUMBER),
|
||||
@ -10552,288 +10563,51 @@ Field *make_field(TABLE_SHARE *share,
|
||||
|
||||
Record_addr addr(rec->ptr(), f_maybe_null(pack_flag) ? rec->null() :
|
||||
Bit_addr());
|
||||
|
||||
if (handler == &type_handler_row)
|
||||
{
|
||||
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:
|
||||
{
|
||||
/*
|
||||
Special code for the BIT-alike data types
|
||||
who store data bits together with NULL-bits.
|
||||
*/
|
||||
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();
|
||||
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;
|
||||
return handler->make_table_field_from_def(share, mem_root, field_name,
|
||||
addr, bit, this, flags);
|
||||
}
|
||||
|
||||
|
||||
bool Field_vers_trx_id::test_if_equality_guarantees_uniqueness(const Item* item) const
|
||||
{
|
||||
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. */
|
||||
|
||||
Column_definition::Column_definition(THD *thd, Field *old_field,
|
||||
Field *orig_field)
|
||||
:Column_definition_attributes(old_field)
|
||||
{
|
||||
on_update= NULL;
|
||||
field_name= old_field->field_name;
|
||||
length= old_field->field_length;
|
||||
flags= old_field->flags;
|
||||
unireg_check=old_field->unireg_check;
|
||||
pack_length=old_field->pack_length();
|
||||
key_length= old_field->key_length();
|
||||
set_handler(old_field->type_handler());
|
||||
charset= old_field->charset(); // May be NULL ptr
|
||||
comment= old_field->comment;
|
||||
decimals= old_field->decimals();
|
||||
vcol_info= old_field->vcol_info;
|
||||
option_list= old_field->option_list;
|
||||
pack_flag= 0;
|
||||
compression_method_ptr= 0;
|
||||
versioning= VERSIONING_NOT_SET;
|
||||
invisible= old_field->invisible;
|
||||
|
76
sql/field.h
76
sql/field.h
@ -4072,21 +4072,53 @@ public:
|
||||
|
||||
extern const LEX_CSTRING null_clex_str;
|
||||
|
||||
Field *make_field(TABLE_SHARE *share, MEM_ROOT *mem_root,
|
||||
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,
|
||||
const Record_addr *rec,
|
||||
uint32 field_length,
|
||||
uint pack_flag, const Type_handler *handler,
|
||||
CHARSET_INFO *cs,
|
||||
Field::geometry_type geom_type, uint srid,
|
||||
Field::utype unireg_check,
|
||||
TYPELIB *interval, const LEX_CSTRING *field_name,
|
||||
uint32 flags);
|
||||
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
|
||||
*/
|
||||
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".
|
||||
@ -4141,11 +4173,6 @@ public:
|
||||
WITHOUT_VERSIONING
|
||||
};
|
||||
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;
|
||||
/*
|
||||
The value of `length' as set by parser: is the number of characters
|
||||
@ -4153,15 +4180,9 @@ public:
|
||||
*/
|
||||
uint32 char_length;
|
||||
uint decimals, flags, pack_length, key_length;
|
||||
Field::utype unireg_check;
|
||||
TYPELIB *interval; // Which interval to use
|
||||
List<String> interval_list;
|
||||
CHARSET_INFO *charset;
|
||||
uint32 srid;
|
||||
Field::geometry_type geom_type;
|
||||
engine_option_value *option_list;
|
||||
|
||||
uint pack_flag;
|
||||
|
||||
/*
|
||||
This is additinal data provided for any computed(virtual) field.
|
||||
@ -4179,11 +4200,9 @@ public:
|
||||
:Type_handler_hybrid_field_type(&type_handler_null),
|
||||
compression_method_ptr(0),
|
||||
comment(null_clex_str),
|
||||
on_update(NULL), length(0), invisible(VISIBLE), decimals(0),
|
||||
flags(0), pack_length(0), key_length(0), unireg_check(Field::NONE),
|
||||
interval(0), charset(&my_charset_bin),
|
||||
srid(0), geom_type(Field::GEOM_GEOMETRY),
|
||||
option_list(NULL), pack_flag(0),
|
||||
on_update(NULL), invisible(VISIBLE), decimals(0),
|
||||
flags(0), pack_length(0), key_length(0),
|
||||
option_list(NULL),
|
||||
vcol_info(0), default_value(0), check_constraint(0),
|
||||
versioning(VERSIONING_NOT_SET)
|
||||
{
|
||||
@ -4316,9 +4335,8 @@ public:
|
||||
const Record_addr *addr,
|
||||
const LEX_CSTRING *field_name_arg) const
|
||||
{
|
||||
return ::make_field(share, mem_root, addr, (uint32) length,
|
||||
pack_flag, type_handler(), charset,
|
||||
geom_type, srid, unireg_check, interval,
|
||||
return Column_definition_attributes::make_field(share, mem_root, addr,
|
||||
type_handler(),
|
||||
field_name_arg, flags);
|
||||
}
|
||||
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_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_num(x) ((x) & FIELDFLAG_NUMBER)
|
||||
|
484
sql/sql_type.cc
484
sql/sql_type.cc
@ -5780,3 +5780,487 @@ void Type_handler_geometry::Item_param_set_param_func(Item_param *param,
|
||||
#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
|
||||
|
||||
/***************************************************************************/
|
||||
|
216
sql/sql_type.h
216
sql/sql_type.h
@ -28,6 +28,7 @@
|
||||
|
||||
class Field;
|
||||
class Column_definition;
|
||||
class Column_definition_attributes;
|
||||
class Item;
|
||||
class Item_param;
|
||||
class Item_cache;
|
||||
@ -1179,6 +1180,23 @@ public:
|
||||
const Record_addr &addr,
|
||||
const Type_all_attributes &attr,
|
||||
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,
|
||||
const SORT_FIELD_ATTR *sort_field,
|
||||
Sort_param *param) const= 0;
|
||||
@ -1465,6 +1483,13 @@ public:
|
||||
DBUG_ASSERT(0);
|
||||
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,
|
||||
const SORT_FIELD_ATTR *sort_field,
|
||||
Sort_param *param) const
|
||||
@ -2189,6 +2214,13 @@ public:
|
||||
const Record_addr &addr,
|
||||
const Type_all_attributes &attr,
|
||||
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,
|
||||
uchar **pos, ulong len) const;
|
||||
};
|
||||
@ -2218,6 +2250,13 @@ public:
|
||||
const Record_addr &addr,
|
||||
const Type_all_attributes &attr,
|
||||
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,
|
||||
uchar **pos, ulong len) const;
|
||||
};
|
||||
@ -2250,6 +2289,13 @@ public:
|
||||
const Record_addr &addr,
|
||||
const Type_all_attributes &attr,
|
||||
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,
|
||||
uchar **pos, ulong len) const;
|
||||
};
|
||||
@ -2283,6 +2329,13 @@ public:
|
||||
const Record_addr &addr,
|
||||
const Type_all_attributes &attr,
|
||||
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,
|
||||
uchar **pos, ulong len) const;
|
||||
};
|
||||
@ -2323,6 +2376,13 @@ public:
|
||||
const Record_addr &addr,
|
||||
const Type_all_attributes &attr,
|
||||
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 Type_all_attributes &attr,
|
||||
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;
|
||||
bool Item_get_date(Item *item, MYSQL_TIME *ltime, ulonglong fuzzydate) const;
|
||||
};
|
||||
@ -2392,6 +2459,13 @@ public:
|
||||
const Record_addr &addr,
|
||||
const Type_all_attributes &attr,
|
||||
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 Type_all_attributes &attr,
|
||||
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,
|
||||
uchar **pos, ulong len) const;
|
||||
};
|
||||
@ -2453,6 +2534,13 @@ public:
|
||||
const Record_addr &addr,
|
||||
const Type_all_attributes &attr,
|
||||
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,
|
||||
uchar **pos, ulong len) const;
|
||||
};
|
||||
@ -2536,6 +2624,13 @@ public:
|
||||
const Record_addr &addr,
|
||||
const Type_all_attributes &attr,
|
||||
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 Type_all_attributes &attr,
|
||||
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 Type_all_attributes &attr,
|
||||
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 Type_all_attributes &attr,
|
||||
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 Type_all_attributes &attr,
|
||||
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 Type_all_attributes &attr,
|
||||
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 Type_all_attributes &attr,
|
||||
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 Type_all_attributes &attr,
|
||||
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 Type_all_attributes &attr,
|
||||
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 Type_all_attributes &attr,
|
||||
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 Type_all_attributes &attr,
|
||||
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 Type_all_attributes &attr,
|
||||
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 Type_all_attributes &attr,
|
||||
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;
|
||||
};
|
||||
|
||||
@ -3030,6 +3209,13 @@ public:
|
||||
Item **items, uint nitems) 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;
|
||||
Field *make_conversion_table_field(TABLE *, uint metadata,
|
||||
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_prepare_stage1(THD *thd,
|
||||
MEM_ROOT *mem_root,
|
||||
@ -3145,6 +3339,14 @@ public:
|
||||
const Type_all_attributes &attr,
|
||||
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_decimal() const { return false; }
|
||||
bool can_return_real() const { return false; }
|
||||
@ -3227,6 +3429,13 @@ public:
|
||||
const Record_addr &addr,
|
||||
const Type_all_attributes &attr,
|
||||
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 Type_all_attributes &attr,
|
||||
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;
|
||||
};
|
||||
|
||||
|
||||
|
295
sql/table.cc
295
sql/table.cc
@ -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.
|
||||
Calculate the position for these bits
|
||||
@ -1145,6 +1193,38 @@ end:
|
||||
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
|
||||
|
||||
@ -1191,8 +1271,7 @@ int TABLE_SHARE::init_from_binary_frm_image(THD *thd, bool write,
|
||||
size_t UNINIT_VAR(options_len);
|
||||
uchar *vcol_screen_pos;
|
||||
const uchar *options= 0;
|
||||
size_t UNINIT_VAR(gis_options_len);
|
||||
const uchar *gis_options= 0;
|
||||
LEX_CUSTRING gis_options= { NULL, 0};
|
||||
KEY first_keyinfo;
|
||||
uint len;
|
||||
uint ext_key_parts= 0;
|
||||
@ -1288,10 +1367,10 @@ int TABLE_SHARE::init_from_binary_frm_image(THD *thd, bool write,
|
||||
case EXTRA2_GIS:
|
||||
#ifdef HAVE_SPATIAL
|
||||
{
|
||||
if (gis_options)
|
||||
if (gis_options.str)
|
||||
goto err;
|
||||
gis_options= extra2;
|
||||
gis_options_len= length;
|
||||
gis_options.str= extra2;
|
||||
gis_options.length= length;
|
||||
}
|
||||
#endif /*HAVE_SPATIAL*/
|
||||
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++)
|
||||
{
|
||||
uint pack_flag, interval_nr, unireg_type, recpos, field_length;
|
||||
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;
|
||||
uint interval_nr= 0, recpos;
|
||||
LEX_CSTRING comment;
|
||||
LEX_CSTRING name;
|
||||
Virtual_column_info *vcol_info= 0;
|
||||
uint gis_length, gis_decimals, srid= 0;
|
||||
Field::utype unireg_check;
|
||||
const Type_handler *handler;
|
||||
uint32 flags= 0;
|
||||
Column_definition_attributes attr;
|
||||
|
||||
if (new_frm_ver >= 3)
|
||||
{
|
||||
/* new frm file in 4.1 */
|
||||
field_length= uint2korr(strpos+3);
|
||||
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);
|
||||
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)
|
||||
{
|
||||
@ -1870,32 +1886,20 @@ int TABLE_SHARE::init_from_binary_frm_image(THD *thd, bool write,
|
||||
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
|
||||
|
||||
byte 1 = 1
|
||||
byte 2,3 = expr length
|
||||
byte 4 = stored_in_db
|
||||
byte 5.. = expr
|
||||
MariaDB version 10.0 version.
|
||||
The interval_id byte in the .frm file stores the length of the
|
||||
expression statement for a virtual column.
|
||||
*/
|
||||
if ((uint)(vcol_screen_pos)[0] != 1)
|
||||
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;
|
||||
}
|
||||
uint vcol_info_length= (uint) strpos[12];
|
||||
|
||||
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
|
||||
|
||||
@ -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();
|
||||
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)
|
||||
interval_nr= (uint)vcol_screen_pos[3];
|
||||
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;
|
||||
vcol_info->stored_in_db= stored;
|
||||
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));
|
||||
vcol_info->utf8= 0; // before 10.2.1 the charset was unknown
|
||||
int2store(vcol_screen_pos+1, vcol_expr_length); // for parse_vcol_defs()
|
||||
vcol_screen_pos+= vcol_info_length;
|
||||
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
|
||||
{
|
||||
field_length= (uint) strpos[3];
|
||||
attr.length= (uint) strpos[3];
|
||||
recpos= uint2korr(strpos+4),
|
||||
pack_flag= uint2korr(strpos+6);
|
||||
pack_flag&= ~FIELDFLAG_NO_DEFAULT; // Safety for old files
|
||||
unireg_type= (uint) strpos[8];
|
||||
attr.pack_flag= uint2korr(strpos+6);
|
||||
attr.pack_flag&= ~FIELDFLAG_NO_DEFAULT; // Safety for old files
|
||||
attr.unireg_check= (Field::utype) MTYP_TYPENR((uint) strpos[8]);
|
||||
interval_nr= (uint) strpos[10];
|
||||
|
||||
/* old frm file */
|
||||
field_type= (enum_field_types) f_packtype(pack_flag);
|
||||
if (f_is_binary(pack_flag))
|
||||
enum_field_types ftype= (enum_field_types) f_packtype(attr.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:
|
||||
@ -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.
|
||||
- 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
|
||||
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))))
|
||||
charset= &my_charset_bin;
|
||||
attr.charset= &my_charset_bin;
|
||||
}
|
||||
}
|
||||
else
|
||||
charset= &my_charset_bin;
|
||||
}
|
||||
else
|
||||
charset= share->table_charset;
|
||||
attr.charset= share->table_charset;
|
||||
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 */
|
||||
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 */
|
||||
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
|
||||
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
|
||||
The difference is that in the old version we stored precision
|
||||
in the .frm table while we now store the display_length
|
||||
*/
|
||||
uint decimals= f_decimals(pack_flag);
|
||||
field_length= my_decimal_precision_to_length(field_length,
|
||||
decimals,
|
||||
f_is_dec(pack_flag) == 0);
|
||||
uint decimals= f_decimals(attr.pack_flag);
|
||||
attr.length=
|
||||
my_decimal_precision_to_length((uint) attr.length, decimals,
|
||||
f_is_dec(attr.pack_flag) == 0);
|
||||
sql_print_error("Found incompatible DECIMAL field '%s' in %s; "
|
||||
"Please do \"ALTER TABLE '%s' FORCE\" to fix it!",
|
||||
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)
|
||||
{
|
||||
switch (field_type)
|
||||
switch (handler->real_field_type())
|
||||
{
|
||||
case MYSQL_TYPE_TIMESTAMP2:
|
||||
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 */
|
||||
unireg_check= (Field::utype) MTYP_TYPENR(unireg_type);
|
||||
name.str= fieldnames.type_names[i];
|
||||
name.length= strlen(name.str);
|
||||
if (!(handler= Type_handler::get_handler_by_real_type(field_type)))
|
||||
goto err; // Not supported field type
|
||||
attr.interval= interval_nr ? share->intervals + interval_nr - 1 : NULL;
|
||||
Record_addr addr(record + recpos, null_pos, null_bit_pos);
|
||||
*field_ptr= reg_field=
|
||||
make_field(share, &share->mem_root, &addr,
|
||||
(uint32) field_length, pack_flag, handler, charset,
|
||||
geom_type, srid, unireg_check,
|
||||
(interval_nr ? share->intervals + interval_nr - 1 : NULL),
|
||||
&name, flags);
|
||||
attr.make_field(share, &share->mem_root, &addr, handler, &name, flags);
|
||||
if (!reg_field) // Not supported field type
|
||||
goto err;
|
||||
|
||||
if (unireg_check == Field::TIMESTAMP_DNUN_FIELD ||
|
||||
unireg_check == Field::TIMESTAMP_DN_FIELD)
|
||||
if (attr.unireg_check == Field::TIMESTAMP_DNUN_FIELD ||
|
||||
attr.unireg_check == Field::TIMESTAMP_DN_FIELD)
|
||||
{
|
||||
reg_field->default_value= new (&share->mem_root) Virtual_column_info();
|
||||
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);
|
||||
if (!reg_field->invisible)
|
||||
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;
|
||||
if ((null_bit_pos+= field_length & 7) > 7)
|
||||
if ((null_bit_pos+= (uint) (attr.length & 7)) > 7)
|
||||
{
|
||||
null_pos++;
|
||||
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;
|
||||
|
||||
if (reg_field->unireg_check == Field::NEXT_NUMBER)
|
||||
|
@ -897,32 +897,12 @@ static bool pack_fields(uchar **buff_arg, List<Create_field> &create_fields,
|
||||
while ((field=it++))
|
||||
{
|
||||
uint recpos;
|
||||
int2store(buff+3, field->length);
|
||||
/* The +1 is here becasue the col offset in .frm file have offset 1 */
|
||||
recpos= field->offset+1 + (uint) data_offset;
|
||||
int3store(buff+5,recpos);
|
||||
int2store(buff+8,field->pack_flag);
|
||||
buff[10]= (uchar) field->unireg_check;
|
||||
buff[12]= (uchar) field->interval_id;
|
||||
buff[13]= (uchar) field->real_field_type();
|
||||
if (field->real_field_type() == MYSQL_TYPE_GEOMETRY)
|
||||
{
|
||||
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
|
||||
}
|
||||
|
||||
buff[13]= (uchar) field->type_handler()->real_field_type();
|
||||
field->type_handler()->Column_definition_attributes_frm_pack(field, buff);
|
||||
int2store(buff+15, field->comment.length);
|
||||
comment_length+= field->comment.length;
|
||||
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,
|
||||
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 */
|
||||
Field *regfield= make_field(&share, thd->mem_root, &addr,
|
||||
(uint32) field->length,
|
||||
field->pack_flag,
|
||||
Field *regfield= tmp.make_field(&share, thd->mem_root, &addr,
|
||||
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->flags);
|
||||
if (!regfield)
|
||||
|
Reference in New Issue
Block a user