MDEV-12695 Add Column_definition::type_handler()

This commit is contained in:
Alexander Barkov 2017-05-05 07:00:18 +04:00
parent 1ff79562b8
commit aacb4d57ca
20 changed files with 202 additions and 213 deletions

View File

@ -31,5 +31,5 @@ Pos Instruction
1 stmt 130 "SIGNAL foo SET MESSAGE_TEXT = "This i..." 1 stmt 130 "SIGNAL foo SET MESSAGE_TEXT = "This i..."
2 stmt 131 "RESIGNAL foo" 2 stmt 131 "RESIGNAL foo"
3 stmt 131 "RESIGNAL foo SET MESSAGE_TEXT = "This..." 3 stmt 131 "RESIGNAL foo SET MESSAGE_TEXT = "This..."
4 freturn 3 0 4 freturn int 0
drop function signal_func; drop function signal_func;

View File

@ -11,7 +11,7 @@ returns int
return 0; return 0;
show function code almost_empty; show function code almost_empty;
Pos Instruction Pos Instruction
0 freturn 3 0 0 freturn int 0
drop function almost_empty; drop function almost_empty;
create procedure code_sample(x int, out err int, out nulls int) create procedure code_sample(x int, out err int, out nulls int)
begin begin
@ -957,10 +957,10 @@ END
$ $
SHOW FUNCTION CODE testf_bug11763507; SHOW FUNCTION CODE testf_bug11763507;
Pos Instruction Pos Instruction
0 freturn 3 0 0 freturn int 0
SHOW FUNCTION CODE TESTF_bug11763507; SHOW FUNCTION CODE TESTF_bug11763507;
Pos Instruction Pos Instruction
0 freturn 3 0 0 freturn int 0
SHOW PROCEDURE CODE testp_bug11763507; SHOW PROCEDURE CODE testp_bug11763507;
Pos Instruction Pos Instruction
0 stmt 0 "SELECT "PROCEDURE testp_bug11763507"" 0 stmt 0 "SELECT "PROCEDURE testp_bug11763507""

View File

@ -11,7 +11,7 @@ END;
/ /
SHOW FUNCTION CODE f1; SHOW FUNCTION CODE f1;
Pos Instruction Pos Instruction
0 freturn 3 10 0 freturn int 10
SELECT f1(); SELECT f1();
f1() f1()
10 10
@ -418,7 +418,7 @@ Pos Instruction
1 set i@0 i@0 + 1 1 set i@0 i@0 + 1
2 jump_if_not 1(1) i@0 >= 5 2 jump_if_not 1(1) i@0 >= 5
3 jump 4 3 jump 4
4 freturn 3 i@0 4 freturn int i@0
SELECT f1() FROM DUAL; SELECT f1() FROM DUAL;
f1() f1()
5 5
@ -440,7 +440,7 @@ Pos Instruction
1 set i@0 i@0 + 1 1 set i@0 i@0 + 1
2 jump_if_not 1(0) i@0 >= 5 2 jump_if_not 1(0) i@0 >= 5
3 jump 4 3 jump 4
4 freturn 3 i@0 4 freturn int i@0
SELECT f1() FROM DUAL; SELECT f1() FROM DUAL;
f1() f1()
5 5
@ -474,7 +474,7 @@ Pos Instruction
7 hreturn 0 8 7 hreturn 0 8
8 hpop 1 8 hpop 1
9 jump 5 9 jump 5
10 freturn 3 i@0 10 freturn int i@0
SELECT f1() FROM DUAL; SELECT f1() FROM DUAL;
f1() f1()
5 5
@ -586,7 +586,7 @@ Pos Instruction
6 jump 9 6 jump 9
7 set i@3 i@3 + 1 7 set i@3 i@3 + 1
8 jump 3 8 jump 3
9 freturn 3 total@2 9 freturn int total@2
SELECT f1(3, 100) FROM DUAL; SELECT f1(3, 100) FROM DUAL;
f1(3, 100) f1(3, 100)
6 6
@ -619,7 +619,7 @@ Pos Instruction
6 jump 9 6 jump 9
7 set i@3 i@3 + -1 7 set i@3 i@3 + -1
8 jump 3 8 jump 3
9 freturn 3 total@2 9 freturn int total@2
SELECT f1(3, 100) FROM DUAL; SELECT f1(3, 100) FROM DUAL;
f1(3, 100) f1(3, 100)
6 6
@ -666,7 +666,7 @@ Pos Instruction
14 jump 7 14 jump 7
15 set ia@5 ia@5 + 1 15 set ia@5 ia@5 + 1
16 jump 3 16 jump 3
17 freturn 3 total@4 17 freturn int total@4
SELECT f1(2, 1, 2, 2) FROM DUAL; SELECT f1(2, 1, 2, 2) FROM DUAL;
f1(2, 1, 2, 2) f1(2, 1, 2, 2)
1001 1001
@ -707,7 +707,7 @@ Pos Instruction
8 set total@1 total@1 + 1 8 set total@1 total@1 + 1
9 set i@2 i@2 + 1 9 set i@2 i@2 + 1
10 jump 3 10 jump 3
11 freturn 3 total@1 11 freturn int total@1
SELECT f1(3), f1(4), f1(5), f1(6) FROM DUAL; SELECT f1(3), f1(4), f1(5), f1(6) FROM DUAL;
f1(3) f1(4) f1(5) f1(6) f1(3) f1(4) f1(5) f1(6)
3003 4004 5004 6005 3003 4004 5004 6005
@ -749,7 +749,7 @@ Pos Instruction
13 jump 6 13 jump 6
14 set i@2 i@2 + 1 14 set i@2 i@2 + 1
15 jump 3 15 jump 3
16 freturn 3 total@1 16 freturn int total@1
SELECT f1(3), f1(4), f1(5), f1(6) FROM DUAL; SELECT f1(3), f1(4), f1(5), f1(6) FROM DUAL;
f1(3) f1(4) f1(5) f1(6) f1(3) f1(4) f1(5) f1(6)
6006 8008 9008 11010 6006 8008 9008 11010
@ -792,7 +792,7 @@ Pos Instruction
13 jump 6 13 jump 6
14 set j@2 j@2 + 1 14 set j@2 j@2 + 1
15 jump 3 15 jump 3
16 freturn 3 total@1 16 freturn int total@1
SELECT f1(3), f1(4), f1(5), f1(6) FROM DUAL; SELECT f1(3), f1(4), f1(5), f1(6) FROM DUAL;
f1(3) f1(4) f1(5) f1(6) f1(3) f1(4) f1(5) f1(6)
6006 8008 10008 12010 6006 8008 10008 12010
@ -822,7 +822,7 @@ Pos Instruction
7 set total@1 total@1 + 1 7 set total@1 total@1 + 1
8 set i@2 i@2 + 1 8 set i@2 i@2 + 1
9 jump 3 9 jump 3
10 freturn 3 total@1 10 freturn int total@1
SELECT f1(3), f1(4), f1(5), f1(6) FROM DUAL; SELECT f1(3), f1(4), f1(5), f1(6) FROM DUAL;
f1(3) f1(4) f1(5) f1(6) f1(3) f1(4) f1(5) f1(6)
3 4 4 5 3 4 4 5
@ -902,7 +902,7 @@ SHOW FUNCTION CODE f1;
Pos Instruction Pos Instruction
0 set a@0 NULL 0 set a@0 NULL
1 set a.b@0[1] 200 1 set a.b@0[1] 200
2 freturn 3 a.b@0[1] 2 freturn int a.b@0[1]
SELECT f1(); SELECT f1();
f1() f1()
200 200

View File

@ -999,37 +999,6 @@ CPP_UNNAMED_NS_END
Static help functions Static help functions
*****************************************************************************/ *****************************************************************************/
/**
Check whether a field type can be partially indexed by a key.
This is a static method, rather than a virtual function, because we need
to check the type of a non-Field in mysql_alter_table().
@param type field type
@retval
TRUE Type can have a prefixed key
@retval
FALSE Type can not have a prefixed key
*/
bool Field::type_can_have_key_part(enum enum_field_types type)
{
switch (type) {
case MYSQL_TYPE_VARCHAR:
case MYSQL_TYPE_TINY_BLOB:
case MYSQL_TYPE_MEDIUM_BLOB:
case MYSQL_TYPE_LONG_BLOB:
case MYSQL_TYPE_BLOB:
case MYSQL_TYPE_VAR_STRING:
case MYSQL_TYPE_STRING:
case MYSQL_TYPE_GEOMETRY:
return TRUE;
default:
return FALSE;
}
}
void Field::make_sort_key(uchar *buff,uint length) void Field::make_sort_key(uchar *buff,uint length)
{ {
@ -3294,7 +3263,7 @@ bool Field_new_decimal::compatible_field_size(uint field_metadata,
uint Field_new_decimal::is_equal(Create_field *new_field) uint Field_new_decimal::is_equal(Create_field *new_field)
{ {
return ((new_field->sql_type == real_type()) && return ((new_field->type_handler() == type_handler()) &&
((new_field->flags & UNSIGNED_FLAG) == ((new_field->flags & UNSIGNED_FLAG) ==
(uint) (flags & UNSIGNED_FLAG)) && (uint) (flags & UNSIGNED_FLAG)) &&
((new_field->flags & AUTO_INCREMENT_FLAG) == ((new_field->flags & AUTO_INCREMENT_FLAG) ==
@ -5378,7 +5347,7 @@ my_time_t Field_timestampf::get_timestamp(const uchar *pos,
/*************************************************************/ /*************************************************************/
uint Field_temporal::is_equal(Create_field *new_field) uint Field_temporal::is_equal(Create_field *new_field)
{ {
return new_field->sql_type == real_type() && return new_field->type_handler() == type_handler() &&
new_field->length == max_display_length(); new_field->length == max_display_length();
} }
@ -6851,15 +6820,15 @@ int Field_str::store(double nr)
uint Field::is_equal(Create_field *new_field) uint Field::is_equal(Create_field *new_field)
{ {
return (new_field->sql_type == real_type()); return new_field->type_handler() == type_handler();
} }
uint Field_str::is_equal(Create_field *new_field) uint Field_str::is_equal(Create_field *new_field)
{ {
return ((new_field->sql_type == real_type()) && return new_field->type_handler() == type_handler() &&
new_field->charset == field_charset && new_field->charset == field_charset &&
new_field->length == max_display_length()); new_field->length == max_display_length();
} }
@ -7717,7 +7686,7 @@ Field *Field_varstring::new_key_field(MEM_ROOT *root, TABLE *new_table,
uint Field_varstring::is_equal(Create_field *new_field) uint Field_varstring::is_equal(Create_field *new_field)
{ {
if (new_field->sql_type == real_type() && if (new_field->type_handler() == type_handler() &&
new_field->charset == field_charset) new_field->charset == field_charset)
{ {
if (new_field->length == max_display_length()) if (new_field->length == max_display_length())
@ -8292,9 +8261,9 @@ uint Field_blob::max_packed_col_length(uint max_length)
uint Field_blob::is_equal(Create_field *new_field) uint Field_blob::is_equal(Create_field *new_field)
{ {
return ((new_field->sql_type == get_blob_type_from_length(max_data_length())) return new_field->type_handler() == type_handler() &&
&& new_field->charset == field_charset && new_field->charset == field_charset &&
new_field->pack_length == pack_length()); new_field->pack_length == pack_length();
} }
@ -8321,7 +8290,7 @@ uint gis_field_options_image(uchar *buff, List<Create_field> &create_fields)
Create_field *field; Create_field *field;
while ((field= it++)) while ((field= it++))
{ {
if (field->sql_type != MYSQL_TYPE_GEOMETRY) if (field->real_field_type() != MYSQL_TYPE_GEOMETRY)
continue; continue;
if (buff) if (buff)
{ {
@ -8514,7 +8483,7 @@ Field::geometry_type Field_geom::geometry_type_merge(geometry_type a,
uint Field_geom::is_equal(Create_field *new_field) uint Field_geom::is_equal(Create_field *new_field)
{ {
return new_field->sql_type == MYSQL_TYPE_GEOMETRY && return new_field->type_handler() == type_handler() &&
/* /*
- Allow ALTER..INPLACE to supertype (GEOMETRY), - Allow ALTER..INPLACE to supertype (GEOMETRY),
e.g. POINT to GEOMETRY or POLYGON to GEOMETRY. e.g. POINT to GEOMETRY or POLYGON to GEOMETRY.
@ -8941,7 +8910,7 @@ uint Field_enum::is_equal(Create_field *new_field)
The fields are compatible if they have the same flags, The fields are compatible if they have the same flags,
type, charset and have the same underlying length. type, charset and have the same underlying length.
*/ */
if (new_field->sql_type != real_type() || if (new_field->type_handler() != type_handler() ||
new_field->charset != field_charset || new_field->charset != field_charset ||
new_field->pack_length != pack_length()) new_field->pack_length != pack_length())
return IS_EQUAL_NO; return IS_EQUAL_NO;
@ -9006,7 +8975,7 @@ bool Field_num::eq_def(const Field *field) const
uint Field_num::is_equal(Create_field *new_field) uint Field_num::is_equal(Create_field *new_field)
{ {
return ((new_field->sql_type == real_type()) && return ((new_field->type_handler() == type_handler()) &&
((new_field->flags & UNSIGNED_FLAG) == ((new_field->flags & UNSIGNED_FLAG) ==
(uint) (flags & UNSIGNED_FLAG)) && (uint) (flags & UNSIGNED_FLAG)) &&
((new_field->flags & AUTO_INCREMENT_FLAG) == ((new_field->flags & AUTO_INCREMENT_FLAG) ==
@ -9160,8 +9129,8 @@ Field *Field_bit::new_key_field(MEM_ROOT *root, TABLE *new_table,
uint Field_bit::is_equal(Create_field *new_field) uint Field_bit::is_equal(Create_field *new_field)
{ {
return (new_field->sql_type == real_type() && return new_field->type_handler() == type_handler() &&
new_field->length == max_display_length()); new_field->length == max_display_length();
} }
@ -9699,7 +9668,7 @@ bool Column_definition::create_interval_from_interval_list(MEM_ROOT *mem_root,
value.length= charset->cset->lengthsp(charset, value.str, value.length); value.length= charset->cset->lengthsp(charset, value.str, value.length);
((char*) value.str)[value.length]= '\0'; ((char*) value.str)[value.length]= '\0';
if (sql_type == MYSQL_TYPE_SET) if (real_field_type() == MYSQL_TYPE_SET)
{ {
if (charset->coll->instr(charset, value.str, value.length, if (charset->coll->instr(charset, value.str, value.length,
comma_buf, comma_length, NULL, 0)) comma_buf, comma_length, NULL, 0))
@ -9726,7 +9695,8 @@ bool Column_definition::prepare_interval_field(MEM_ROOT *mem_root,
bool reuse_interval_list_values) bool reuse_interval_list_values)
{ {
DBUG_ENTER("Column_definition::prepare_interval_field"); DBUG_ENTER("Column_definition::prepare_interval_field");
DBUG_ASSERT(sql_type == MYSQL_TYPE_ENUM || sql_type == MYSQL_TYPE_SET); DBUG_ASSERT(real_field_type() == MYSQL_TYPE_ENUM ||
real_field_type() == MYSQL_TYPE_SET);
/* /*
Interval values are either in "interval" or in "interval_list", Interval values are either in "interval" or in "interval_list",
but not in both at the same time, and are not empty at the same time. but not in both at the same time, and are not empty at the same time.
@ -9779,12 +9749,12 @@ bool Column_definition::prepare_interval_field(MEM_ROOT *mem_root,
void Column_definition::set_attributes(const Lex_field_type_st &type, void Column_definition::set_attributes(const Lex_field_type_st &type,
CHARSET_INFO *cs) CHARSET_INFO *cs)
{ {
DBUG_ASSERT(sql_type == MYSQL_TYPE_NULL); DBUG_ASSERT(type_handler() == &type_handler_null);
DBUG_ASSERT(charset == &my_charset_bin || charset == NULL); DBUG_ASSERT(charset == &my_charset_bin || charset == NULL);
DBUG_ASSERT(length == 0); DBUG_ASSERT(length == 0);
DBUG_ASSERT(decimals == 0); DBUG_ASSERT(decimals == 0);
sql_type= type.field_type(); set_handler_by_real_type(type.field_type());
charset= cs; charset= cs;
if (type.length()) if (type.length())
@ -9806,7 +9776,7 @@ void Column_definition::set_attributes(const Lex_field_type_st &type,
void Column_definition::create_length_to_internal_length(void) void Column_definition::create_length_to_internal_length(void)
{ {
switch (sql_type) { switch (real_field_type()) {
case MYSQL_TYPE_TINY_BLOB: case MYSQL_TYPE_TINY_BLOB:
case MYSQL_TYPE_MEDIUM_BLOB: case MYSQL_TYPE_MEDIUM_BLOB:
case MYSQL_TYPE_LONG_BLOB: case MYSQL_TYPE_LONG_BLOB:
@ -9817,7 +9787,7 @@ void Column_definition::create_length_to_internal_length(void)
case MYSQL_TYPE_VARCHAR: case MYSQL_TYPE_VARCHAR:
length*= charset->mbmaxlen; length*= charset->mbmaxlen;
key_length= length; key_length= length;
pack_length= calc_pack_length(sql_type, length); pack_length= calc_pack_length(real_field_type(), length);
break; break;
case MYSQL_TYPE_ENUM: case MYSQL_TYPE_ENUM:
case MYSQL_TYPE_SET: case MYSQL_TYPE_SET:
@ -9846,7 +9816,7 @@ void Column_definition::create_length_to_internal_length(void)
decimals); decimals);
break; break;
default: default:
key_length= pack_length= calc_pack_length(sql_type, length); key_length= pack_length= calc_pack_length(real_field_type(), length);
break; break;
} }
} }
@ -9901,7 +9871,7 @@ bool Column_definition::check(THD *thd)
if (vcol_info) if (vcol_info)
{ {
DBUG_ASSERT(vcol_info->expr); DBUG_ASSERT(vcol_info->expr);
vcol_info->set_field_type(sql_type); vcol_info->set_field_type(real_field_type());
if (check_expression(vcol_info, &field_name, vcol_info->stored_in_db if (check_expression(vcol_info, &field_name, vcol_info->stored_in_db
? VCOL_GENERATED_STORED : VCOL_GENERATED_VIRTUAL)) ? VCOL_GENERATED_STORED : VCOL_GENERATED_VIRTUAL))
DBUG_RETURN(TRUE); DBUG_RETURN(TRUE);
@ -9939,7 +9909,7 @@ bool Column_definition::check(THD *thd)
} }
if (default_value && !default_value->expr->basic_const_item() && if (default_value && !default_value->expr->basic_const_item() &&
mysql_type_to_time_type(sql_type) == MYSQL_TIMESTAMP_DATETIME && mysql_timestamp_type() == MYSQL_TIMESTAMP_DATETIME &&
default_value->expr->type() == Item::FUNC_ITEM) default_value->expr->type() == Item::FUNC_ITEM)
{ {
/* /*
@ -9957,7 +9927,7 @@ bool Column_definition::check(THD *thd)
if (on_update) if (on_update)
{ {
if (mysql_type_to_time_type(sql_type) != MYSQL_TIMESTAMP_DATETIME || if (mysql_timestamp_type() != MYSQL_TIMESTAMP_DATETIME ||
on_update->decimals < length) on_update->decimals < length)
{ {
my_error(ER_INVALID_ON_UPDATE, MYF(0), field_name.str); my_error(ER_INVALID_ON_UPDATE, MYF(0), field_name.str);
@ -9971,7 +9941,7 @@ bool Column_definition::check(THD *thd)
sign_len= flags & UNSIGNED_FLAG ? 0 : 1; sign_len= flags & UNSIGNED_FLAG ? 0 : 1;
switch (sql_type) { switch (real_field_type()) {
case MYSQL_TYPE_TINY: case MYSQL_TYPE_TINY:
if (!length) if (!length)
length= MAX_TINYINT_WIDTH+sign_len; length= MAX_TINYINT_WIDTH+sign_len;
@ -10098,7 +10068,7 @@ bool Column_definition::check(THD *thd)
break; break;
case MYSQL_TYPE_DATE: case MYSQL_TYPE_DATE:
/* We don't support creation of MYSQL_TYPE_DATE anymore */ /* We don't support creation of MYSQL_TYPE_DATE anymore */
sql_type= MYSQL_TYPE_NEWDATE; set_handler(&type_handler_newdate);
/* fall trough */ /* fall trough */
case MYSQL_TYPE_NEWDATE: case MYSQL_TYPE_NEWDATE:
length= MAX_DATE_WIDTH; length= MAX_DATE_WIDTH;
@ -10165,12 +10135,13 @@ bool Column_definition::check(THD *thd)
explicit_defaults_for_timestamp is not set. explicit_defaults_for_timestamp is not set.
*/ */
if (opt_explicit_defaults_for_timestamp || if (opt_explicit_defaults_for_timestamp ||
!is_timestamp_type(sql_type)) !is_timestamp_type())
{ {
flags|= NO_DEFAULT_VALUE_FLAG; flags|= NO_DEFAULT_VALUE_FLAG;
} }
} }
enum_field_types sql_type= real_field_type();
if (!(flags & BLOB_FLAG) && if (!(flags & BLOB_FLAG) &&
((length > max_field_charlength && ((length > max_field_charlength &&
sql_type != MYSQL_TYPE_VARCHAR) || sql_type != MYSQL_TYPE_VARCHAR) ||
@ -10295,7 +10266,7 @@ Field *make_field(TABLE_SHARE *share,
uchar *ptr, uint32 field_length, uchar *ptr, uint32 field_length,
uchar *null_pos, uchar null_bit, uchar *null_pos, uchar null_bit,
uint pack_flag, uint pack_flag,
enum_field_types field_type, const Type_handler *handler,
CHARSET_INFO *field_charset, CHARSET_INFO *field_charset,
Field::geometry_type geom_type, uint srid, Field::geometry_type geom_type, uint srid,
Field::utype unireg_check, Field::utype unireg_check,
@ -10305,7 +10276,7 @@ Field *make_field(TABLE_SHARE *share,
uchar *UNINIT_VAR(bit_ptr); uchar *UNINIT_VAR(bit_ptr);
uchar UNINIT_VAR(bit_offset); uchar UNINIT_VAR(bit_offset);
if (field_type == MYSQL_TYPE_BIT && !f_bit_as_char(pack_flag)) if (handler->real_field_type() == MYSQL_TYPE_BIT && !f_bit_as_char(pack_flag))
{ {
bit_ptr= null_pos; bit_ptr= null_pos;
bit_offset= null_bit; bit_offset= null_bit;
@ -10326,8 +10297,8 @@ Field *make_field(TABLE_SHARE *share,
null_bit= ((uchar) 1) << null_bit; null_bit= ((uchar) 1) << null_bit;
} }
DBUG_PRINT("debug", ("field_type: %d, 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",
field_type, field_length, interval, handler->name().ptr(), field_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),
@ -10338,6 +10309,7 @@ Field *make_field(TABLE_SHARE *share,
{ {
if (!f_is_packed(pack_flag)) if (!f_is_packed(pack_flag))
{ {
enum_field_types field_type= handler->real_field_type();
if (field_type == MYSQL_TYPE_STRING || if (field_type == MYSQL_TYPE_STRING ||
field_type == MYSQL_TYPE_DECIMAL || // 3.23 or 4.0 string field_type == MYSQL_TYPE_DECIMAL || // 3.23 or 4.0 string
field_type == MYSQL_TYPE_VAR_STRING) field_type == MYSQL_TYPE_VAR_STRING)
@ -10390,7 +10362,7 @@ Field *make_field(TABLE_SHARE *share,
} }
} }
switch (field_type) { switch (handler->real_field_type()) {
case MYSQL_TYPE_DECIMAL: case MYSQL_TYPE_DECIMAL:
return new (mem_root) return new (mem_root)
Field_decimal(ptr,field_length,null_pos,null_bit, Field_decimal(ptr,field_length,null_pos,null_bit,
@ -10548,7 +10520,7 @@ Column_definition::Column_definition(THD *thd, Field *old_field,
unireg_check=old_field->unireg_check; 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();
sql_type= old_field->real_type(); set_handler(old_field->type_handler());
charset= old_field->charset(); // May be NULL ptr charset= old_field->charset(); // May be NULL ptr
comment= old_field->comment; comment= old_field->comment;
decimals= old_field->decimals(); decimals= old_field->decimals();
@ -10558,21 +10530,18 @@ Column_definition::Column_definition(THD *thd, Field *old_field,
option_list= old_field->option_list; option_list= old_field->option_list;
pack_flag= 0; pack_flag= 0;
switch (sql_type) { switch (real_field_type()) {
case MYSQL_TYPE_TINY_BLOB:
case MYSQL_TYPE_BLOB: case MYSQL_TYPE_BLOB:
switch (pack_length - portable_sizeof_char_ptr) { case MYSQL_TYPE_MEDIUM_BLOB:
case 1: sql_type= MYSQL_TYPE_TINY_BLOB; break; case MYSQL_TYPE_LONG_BLOB:
case 2: sql_type= MYSQL_TYPE_BLOB; break;
case 3: sql_type= MYSQL_TYPE_MEDIUM_BLOB; break;
default: sql_type= MYSQL_TYPE_LONG_BLOB; break;
}
length/= charset->mbmaxlen; length/= charset->mbmaxlen;
key_length/= charset->mbmaxlen; key_length/= charset->mbmaxlen;
break; break;
case MYSQL_TYPE_STRING: case MYSQL_TYPE_STRING:
/* Change CHAR -> VARCHAR if dynamic record length */ /* Change CHAR -> VARCHAR if dynamic record length */
if (old_field->type() == MYSQL_TYPE_VAR_STRING) if (old_field->type() == MYSQL_TYPE_VAR_STRING)
sql_type= MYSQL_TYPE_VARCHAR; set_handler(&type_handler_varchar);
/* fall through */ /* fall through */
case MYSQL_TYPE_ENUM: case MYSQL_TYPE_ENUM:

View File

@ -459,16 +459,6 @@ inline bool is_temporal_type_with_date(enum_field_types type)
} }
/**
Recognizer for concrete data type (called real_type for some reason),
returning true if it is one of the TIMESTAMP types.
*/
inline bool is_timestamp_type(enum_field_types type)
{
return type == MYSQL_TYPE_TIMESTAMP || type == MYSQL_TYPE_TIMESTAMP2;
}
/** /**
Convert temporal real types as retuned by field->real_type() Convert temporal real types as retuned by field->real_type()
to field type as returned by field->type(). to field type as returned by field->type().
@ -838,7 +828,6 @@ public:
{ {
return type_handler()->cmp_type(); return type_handler()->cmp_type();
} }
static bool type_can_have_key_part(enum_field_types);
static enum_field_types field_type_merge(enum_field_types, enum_field_types); static enum_field_types field_type_merge(enum_field_types, enum_field_types);
virtual bool eq(Field *field) virtual bool eq(Field *field)
{ {
@ -3765,7 +3754,7 @@ extern const LEX_CSTRING null_clex_str;
Field *make_field(TABLE_SHARE *share, MEM_ROOT *mem_root, Field *make_field(TABLE_SHARE *share, MEM_ROOT *mem_root,
uchar *ptr, uint32 field_length, uchar *ptr, uint32 field_length,
uchar *null_pos, uchar null_bit, uchar *null_pos, uchar null_bit,
uint pack_flag, enum_field_types field_type, uint pack_flag, const Type_handler *handler,
CHARSET_INFO *cs, CHARSET_INFO *cs,
Field::geometry_type geom_type, uint srid, Field::geometry_type geom_type, uint srid,
Field::utype unireg_check, Field::utype unireg_check,
@ -3774,7 +3763,8 @@ Field *make_field(TABLE_SHARE *share, MEM_ROOT *mem_root,
/* /*
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
{ {
/** /**
Create "interval" from "interval_list". Create "interval" from "interval_list".
@ -3814,11 +3804,11 @@ class Column_definition: public Sql_alloc
set_if_bigger(*max_length, (uint32)length); set_if_bigger(*max_length, (uint32)length);
} }
} }
const Type_handler *field_type() const; // Prevent using this
public: public:
LEX_CSTRING field_name; LEX_CSTRING field_name;
LEX_CSTRING comment; // Comment for field LEX_CSTRING comment; // Comment for field
Item *on_update; // ON UPDATE NOW() Item *on_update; // ON UPDATE NOW()
enum enum_field_types sql_type;
/* /*
At various stages in execution this can be length of field in bytes or At various stages in execution this can be length of field in bytes or
max number of characters. max number of characters.
@ -3850,9 +3840,10 @@ public:
*default_value, // Default value *default_value, // Default value
*check_constraint; // Check constraint *check_constraint; // Check constraint
Column_definition(): Column_definition()
:Type_handler_hybrid_field_type(&type_handler_null),
comment(null_clex_str), comment(null_clex_str),
on_update(NULL), sql_type(MYSQL_TYPE_NULL), length(0), decimals(0), on_update(NULL), length(0), decimals(0),
flags(0), pack_length(0), key_length(0), unireg_check(Field::NONE), flags(0), pack_length(0), key_length(0), unireg_check(Field::NONE),
interval(0), charset(&my_charset_bin), interval(0), charset(&my_charset_bin),
srid(0), geom_type(Field::GEOM_GEOMETRY), srid(0), geom_type(Field::GEOM_GEOMETRY),
@ -3861,20 +3852,6 @@ public:
{ {
interval_list.empty(); interval_list.empty();
} }
Column_definition(LEX_CSTRING *name, enum_field_types type):
field_name(*name),
comment(null_clex_str),
on_update(NULL), sql_type(type), length(0), 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),
vcol_info(0), default_value(0), check_constraint(0)
{
interval_list.empty();
}
Column_definition(THD *thd, Field *field, Field *orig_field); Column_definition(THD *thd, Field *field, Field *orig_field);
void set_attributes(const Lex_field_type_st &type, CHARSET_INFO *cs); void set_attributes(const Lex_field_type_st &type, CHARSET_INFO *cs);
void create_length_to_internal_length(void); void create_length_to_internal_length(void);
@ -3896,7 +3873,7 @@ public:
void prepare_interval_field_calc_length() void prepare_interval_field_calc_length()
{ {
uint32 field_length, dummy; uint32 field_length, dummy;
if (sql_type == MYSQL_TYPE_SET) if (real_field_type() == MYSQL_TYPE_SET)
{ {
calculate_interval_lengths(&dummy, &field_length); calculate_interval_lengths(&dummy, &field_length);
length= field_length + (interval->count - 1); length= field_length + (interval->count - 1);
@ -3942,7 +3919,7 @@ public:
{ {
return ::make_field(share, mem_root, ptr, return ::make_field(share, mem_root, ptr,
(uint32)length, null_pos, null_bit, (uint32)length, null_pos, null_bit,
pack_flag, sql_type, charset, pack_flag, type_handler(), charset,
geom_type, srid, unireg_check, interval, geom_type, srid, unireg_check, interval,
field_name_arg); field_name_arg);
} }
@ -4042,7 +4019,7 @@ public:
{ {
return is_row() || is_table_rowtype_ref() || is_cursor_rowtype_ref() ? return is_row() || is_table_rowtype_ref() || is_cursor_rowtype_ref() ?
&type_handler_row : &type_handler_row :
Type_handler::get_handler_by_field_type(sql_type); Type_handler_hybrid_field_type::type_handler();
} }
bool is_column_type_ref() const { return m_column_type_ref != 0; } bool is_column_type_ref() const { return m_column_type_ref != 0; }
bool is_table_rowtype_ref() const { return m_table_rowtype_ref != 0; } bool is_table_rowtype_ref() const { return m_table_rowtype_ref != 0; }

View File

@ -3784,7 +3784,7 @@ sp_instr_freturn::print(String *str)
if (str->reserve(1024+8+32)) // Add some for the expr. too if (str->reserve(1024+8+32)) // Add some for the expr. too
return; return;
str->qs_append(STRING_WITH_LEN("freturn ")); str->qs_append(STRING_WITH_LEN("freturn "));
str->qs_append((uint)m_type); str->qs_append(m_type_handler->name().ptr());
str->qs_append(' '); str->qs_append(' ');
m_value->print(str, enum_query_type(QT_ORDINARY | m_value->print(str, enum_query_type(QT_ORDINARY |
QT_ITEM_ORIGINAL_FUNC_NULLIF)); QT_ITEM_ORIGINAL_FUNC_NULLIF));

View File

@ -1430,8 +1430,8 @@ class sp_instr_freturn : public sp_instr
public: public:
sp_instr_freturn(uint ip, sp_pcontext *ctx, sp_instr_freturn(uint ip, sp_pcontext *ctx,
Item *val, enum enum_field_types type_arg, LEX *lex) Item *val, const Type_handler *handler, LEX *lex)
: sp_instr(ip, ctx), m_value(val), m_type(type_arg), : sp_instr(ip, ctx), m_value(val), m_type_handler(handler),
m_lex_keeper(lex, TRUE) m_lex_keeper(lex, TRUE)
{} {}
@ -1453,7 +1453,7 @@ public:
protected: protected:
Item *m_value; Item *m_value;
enum enum_field_types m_type; const Type_handler *m_type_handler;
sp_lex_keeper m_lex_keeper; sp_lex_keeper m_lex_keeper;
}; // class sp_instr_freturn : public sp_instr }; // class sp_instr_freturn : public sp_instr

View File

@ -60,7 +60,7 @@ public:
Spvar_definition field_def; Spvar_definition field_def;
/// Field-type of the SP-variable. /// Field-type of the SP-variable.
enum_field_types sql_type() const { return field_def.sql_type; } enum_field_types sql_type() const { return field_def.real_field_type(); }
const Type_handler *type_handler() const { return field_def.type_handler(); } const Type_handler *type_handler() const { return field_def.type_handler(); }

View File

@ -5406,7 +5406,7 @@ sp_variable *LEX::sp_add_for_loop_variable(THD *thd, const LEX_CSTRING *name,
sp_variable *spvar= spcont->add_variable(thd, name); sp_variable *spvar= spcont->add_variable(thd, name);
spcont->declare_var_boundary(1); spcont->declare_var_boundary(1);
spvar->field_def.field_name= spvar->name; spvar->field_def.field_name= spvar->name;
spvar->field_def.sql_type= MYSQL_TYPE_LONGLONG; spvar->field_def.set_handler(&type_handler_longlong);
/* /*
The below is a simplified version of what The below is a simplified version of what
Column_definition::prepare_create_field() does for a LONGLONG field. Column_definition::prepare_create_field() does for a LONGLONG field.
@ -6363,7 +6363,8 @@ Item_splocal *LEX::create_item_spvar_row_field(THD *thd,
if (!(item= new (thd->mem_root) if (!(item= new (thd->mem_root)
Item_splocal_row_field(thd, a, b, Item_splocal_row_field(thd, a, b,
spv->offset, row_field_offset, spv->offset, row_field_offset,
def->sql_type, pos_in_q, length_in_q))) def->real_field_type(),
pos_in_q, length_in_q)))
return NULL; return NULL;
} }
#ifndef DBUG_OFF #ifndef DBUG_OFF

View File

@ -2214,7 +2214,7 @@ static int add_column_list_values(File fptr, partition_info *part_info,
my_error(ER_FIELD_NOT_FOUND_PART_ERROR, MYF(0)); my_error(ER_FIELD_NOT_FOUND_PART_ERROR, MYF(0));
return 1; return 1;
} }
if (check_part_field(sql_field->sql_type, if (check_part_field(sql_field->real_field_type(),
sql_field->field_name.str, sql_field->field_name.str,
&result_type, &result_type,
&need_cs_check)) &need_cs_check))

View File

@ -27,7 +27,7 @@ struct Field_definition
{ {
const char *field_name; const char *field_name;
uint length; uint length;
enum enum_field_types sql_type; const Type_handler *type_handler;
LEX_CSTRING comment; LEX_CSTRING comment;
ulong flags; ulong flags;
}; };
@ -45,19 +45,19 @@ struct Field_definition
static Field_definition sequence_structure[]= static Field_definition sequence_structure[]=
{ {
{"next_value", 21, MYSQL_TYPE_LONGLONG, {STRING_WITH_LEN("next not cached value")}, {"next_value", 21, &type_handler_longlong, {STRING_WITH_LEN("next not cached value")},
FL}, FL},
{"min_value", 21, MYSQL_TYPE_LONGLONG, {STRING_WITH_LEN("min value")}, FL}, {"min_value", 21, &type_handler_longlong, {STRING_WITH_LEN("min value")}, FL},
{"max_value", 21, MYSQL_TYPE_LONGLONG, {STRING_WITH_LEN("max value")}, FL}, {"max_value", 21, &type_handler_longlong, {STRING_WITH_LEN("max value")}, FL},
{"start", 21, MYSQL_TYPE_LONGLONG, {STRING_WITH_LEN("start value")}, FL}, {"start", 21, &type_handler_longlong, {STRING_WITH_LEN("start value")}, FL},
{"increment", 21, MYSQL_TYPE_LONGLONG, {"increment", 21, &type_handler_longlong,
{C_STRING_WITH_LEN("increment value")}, FL}, {C_STRING_WITH_LEN("increment value")}, FL},
{"cache", 21, MYSQL_TYPE_LONGLONG, {STRING_WITH_LEN("cache size")}, FL}, {"cache", 21, &type_handler_longlong, {STRING_WITH_LEN("cache size")}, FL},
{"cycle", 1, MYSQL_TYPE_TINY, {STRING_WITH_LEN("cycle state")}, {"cycle", 1, &type_handler_tiny, {STRING_WITH_LEN("cycle state")},
FL | UNSIGNED_FLAG }, FL | UNSIGNED_FLAG },
{"round", 21, MYSQL_TYPE_LONGLONG, {"round", 21, &type_handler_longlong,
{STRING_WITH_LEN("How many cycles has been done")}, FL}, {STRING_WITH_LEN("How many cycles has been done")}, FL},
{NULL, 0, MYSQL_TYPE_LONGLONG, {STRING_WITH_LEN("")}, 0} {NULL, 0, &type_handler_longlong, {STRING_WITH_LEN("")}, 0}
}; };
#undef FL #undef FL
@ -196,7 +196,7 @@ bool check_sequence_fields(LEX *lex, List<Create_field> *fields)
if (my_strcasecmp(system_charset_info, field_def->field_name, if (my_strcasecmp(system_charset_info, field_def->field_name,
field->field_name.str) || field->field_name.str) ||
field->flags != field_def->flags || field->flags != field_def->flags ||
field->sql_type != field_def->sql_type) field->type_handler() != field_def->type_handler)
{ {
reason= field->field_name.str; reason= field->field_name.str;
goto err; goto err;
@ -235,7 +235,7 @@ bool prepare_sequence_fields(THD *thd, List<Create_field> *fields)
DBUG_RETURN(TRUE); /* purify inspected */ DBUG_RETURN(TRUE); /* purify inspected */
new_field->field_name= field_name; new_field->field_name= field_name;
new_field->sql_type= field_info->sql_type; new_field->set_handler(field_info->type_handler);
new_field->length= field_info->length; new_field->length= field_info->length;
new_field->char_length= field_info->length; new_field->char_length= field_info->length;
new_field->comment= field_info->comment; new_field->comment= field_info->comment;

View File

@ -2869,7 +2869,7 @@ bool Column_definition::prepare_create_field(uint *blob_columns,
*/ */
DBUG_ASSERT(charset); DBUG_ASSERT(charset);
switch (sql_type) { switch (real_field_type()) {
case MYSQL_TYPE_BLOB: case MYSQL_TYPE_BLOB:
case MYSQL_TYPE_MEDIUM_BLOB: case MYSQL_TYPE_MEDIUM_BLOB:
case MYSQL_TYPE_TINY_BLOB: case MYSQL_TYPE_TINY_BLOB:
@ -2905,8 +2905,8 @@ bool Column_definition::prepare_create_field(uint *blob_columns,
if (table_flags & HA_NO_VARCHAR) if (table_flags & HA_NO_VARCHAR)
{ {
/* convert VARCHAR to CHAR because handler is not yet up to date */ /* convert VARCHAR to CHAR because handler is not yet up to date */
sql_type= MYSQL_TYPE_VAR_STRING; set_handler(&type_handler_var_string);
pack_length= calc_pack_length(sql_type, (uint) length); pack_length= calc_pack_length(real_field_type(), (uint) length);
if ((length / charset->mbmaxlen) > MAX_FIELD_CHARLENGTH) if ((length / charset->mbmaxlen) > MAX_FIELD_CHARLENGTH)
{ {
my_error(ER_TOO_BIG_FIELDLENGTH, MYF(0), field_name.str, my_error(ER_TOO_BIG_FIELDLENGTH, MYF(0), field_name.str,
@ -2950,7 +2950,7 @@ bool Column_definition::prepare_create_field(uint *blob_columns,
case MYSQL_TYPE_TIME2: case MYSQL_TYPE_TIME2:
case MYSQL_TYPE_DATETIME2: case MYSQL_TYPE_DATETIME2:
case MYSQL_TYPE_NULL: case MYSQL_TYPE_NULL:
pack_flag= f_settype((uint) sql_type); pack_flag= f_settype((uint) real_field_type());
break; break;
case MYSQL_TYPE_BIT: case MYSQL_TYPE_BIT:
/* /*
@ -2981,7 +2981,7 @@ bool Column_definition::prepare_create_field(uint *blob_columns,
pack_flag= (FIELDFLAG_NUMBER | pack_flag= (FIELDFLAG_NUMBER |
(flags & UNSIGNED_FLAG ? 0 : FIELDFLAG_DECIMAL) | (flags & UNSIGNED_FLAG ? 0 : FIELDFLAG_DECIMAL) |
(flags & ZEROFILL_FLAG ? FIELDFLAG_ZEROFILL : 0) | (flags & ZEROFILL_FLAG ? FIELDFLAG_ZEROFILL : 0) |
f_settype((uint) sql_type) | f_settype((uint) real_field_type()) |
(decimals_orig << FIELDFLAG_DEC_SHIFT)); (decimals_orig << FIELDFLAG_DEC_SHIFT));
break; break;
} }
@ -3044,7 +3044,7 @@ void promote_first_timestamp_column(List<Create_field> *column_definitions)
while ((column_definition= it++) != NULL) while ((column_definition= it++) != NULL)
{ {
if (is_timestamp_type(column_definition->sql_type) || // TIMESTAMP if (column_definition->is_timestamp_type() || // TIMESTAMP
column_definition->unireg_check == Field::TIMESTAMP_OLD_FIELD) // Legacy column_definition->unireg_check == Field::TIMESTAMP_OLD_FIELD) // Legacy
{ {
if ((column_definition->flags & NOT_NULL_FLAG) != 0 && // NOT NULL, if ((column_definition->flags & NOT_NULL_FLAG) != 0 && // NOT NULL,
@ -3229,8 +3229,8 @@ mysql_prepare_create_table(THD *thd, HA_CREATE_INFO *create_info,
!(sql_field->charset= find_bin_collation(sql_field->charset))) !(sql_field->charset= find_bin_collation(sql_field->charset)))
DBUG_RETURN(TRUE); DBUG_RETURN(TRUE);
if (sql_field->sql_type == MYSQL_TYPE_SET || if (sql_field->real_field_type() == MYSQL_TYPE_SET ||
sql_field->sql_type == MYSQL_TYPE_ENUM) sql_field->real_field_type() == MYSQL_TYPE_ENUM)
{ {
/* /*
Create the typelib in runtime memory - we will free the Create the typelib in runtime memory - we will free the
@ -3244,7 +3244,7 @@ mysql_prepare_create_table(THD *thd, HA_CREATE_INFO *create_info,
DBUG_RETURN(true); // E.g. wrong values with commas: SET('a,b') DBUG_RETURN(true); // E.g. wrong values with commas: SET('a,b')
} }
if (sql_field->sql_type == MYSQL_TYPE_BIT) if (sql_field->real_field_type() == MYSQL_TYPE_BIT)
{ {
sql_field->pack_flag= FIELDFLAG_NUMBER; sql_field->pack_flag= FIELDFLAG_NUMBER;
if (file->ha_table_flags() & HA_CAN_BIT_FIELD) if (file->ha_table_flags() & HA_CAN_BIT_FIELD)
@ -3265,14 +3265,14 @@ mysql_prepare_create_table(THD *thd, HA_CREATE_INFO *create_info,
if (sql_field->default_value && if (sql_field->default_value &&
sql_field->default_value->expr->basic_const_item() && sql_field->default_value->expr->basic_const_item() &&
save_cs != sql_field->default_value->expr->collation.collation && save_cs != sql_field->default_value->expr->collation.collation &&
(sql_field->sql_type == MYSQL_TYPE_VAR_STRING || (sql_field->real_field_type() == MYSQL_TYPE_VAR_STRING ||
sql_field->sql_type == MYSQL_TYPE_STRING || sql_field->real_field_type() == MYSQL_TYPE_STRING ||
sql_field->sql_type == MYSQL_TYPE_SET || sql_field->real_field_type() == MYSQL_TYPE_SET ||
sql_field->sql_type == MYSQL_TYPE_TINY_BLOB || sql_field->real_field_type() == MYSQL_TYPE_TINY_BLOB ||
sql_field->sql_type == MYSQL_TYPE_MEDIUM_BLOB || sql_field->real_field_type() == MYSQL_TYPE_MEDIUM_BLOB ||
sql_field->sql_type == MYSQL_TYPE_LONG_BLOB || sql_field->real_field_type() == MYSQL_TYPE_LONG_BLOB ||
sql_field->sql_type == MYSQL_TYPE_BLOB || sql_field->real_field_type() == MYSQL_TYPE_BLOB ||
sql_field->sql_type == MYSQL_TYPE_ENUM)) sql_field->real_field_type() == MYSQL_TYPE_ENUM))
{ {
Item *item; Item *item;
if (!(item= sql_field->default_value->expr-> if (!(item= sql_field->default_value->expr->
@ -3288,8 +3288,8 @@ mysql_prepare_create_table(THD *thd, HA_CREATE_INFO *create_info,
if (sql_field->default_value && if (sql_field->default_value &&
sql_field->default_value->expr->basic_const_item() && sql_field->default_value->expr->basic_const_item() &&
(sql_field->sql_type == MYSQL_TYPE_SET || (sql_field->real_field_type() == MYSQL_TYPE_SET ||
sql_field->sql_type == MYSQL_TYPE_ENUM)) sql_field->real_field_type() == MYSQL_TYPE_ENUM))
{ {
StringBuffer<MAX_FIELD_WIDTH> str; StringBuffer<MAX_FIELD_WIDTH> str;
String *def= sql_field->default_value->expr->val_str(&str); String *def= sql_field->default_value->expr->val_str(&str);
@ -3301,7 +3301,7 @@ mysql_prepare_create_table(THD *thd, HA_CREATE_INFO *create_info,
else else
{ {
not_found= false; not_found= false;
if (sql_field->sql_type == MYSQL_TYPE_SET) if (sql_field->real_field_type() == MYSQL_TYPE_SET)
{ {
char *not_used; char *not_used;
uint not_used2; uint not_used2;
@ -3357,12 +3357,12 @@ mysql_prepare_create_table(THD *thd, HA_CREATE_INFO *create_info,
If we are replacing a BIT field, revert the increment If we are replacing a BIT field, revert the increment
of total_uneven_bit_length that was done above. of total_uneven_bit_length that was done above.
*/ */
if (sql_field->sql_type == MYSQL_TYPE_BIT && if (sql_field->real_field_type() == MYSQL_TYPE_BIT &&
file->ha_table_flags() & HA_CAN_BIT_FIELD) file->ha_table_flags() & HA_CAN_BIT_FIELD)
total_uneven_bit_length-= sql_field->length & 7; total_uneven_bit_length-= sql_field->length & 7;
sql_field->default_value= dup_field->default_value; sql_field->default_value= dup_field->default_value;
sql_field->sql_type= dup_field->sql_type; sql_field->set_handler(dup_field->type_handler());
/* /*
If we are replacing a field with a BIT field, we need If we are replacing a field with a BIT field, we need
@ -3370,7 +3370,7 @@ mysql_prepare_create_table(THD *thd, HA_CREATE_INFO *create_info,
increment total_uneven_bit_length here as this dup_field increment total_uneven_bit_length here as this dup_field
has already been processed. has already been processed.
*/ */
if (sql_field->sql_type == MYSQL_TYPE_BIT) if (sql_field->real_field_type() == MYSQL_TYPE_BIT)
{ {
sql_field->pack_flag= FIELDFLAG_NUMBER; sql_field->pack_flag= FIELDFLAG_NUMBER;
if (!(file->ha_table_flags() & HA_CAN_BIT_FIELD)) if (!(file->ha_table_flags() & HA_CAN_BIT_FIELD))
@ -3404,7 +3404,7 @@ mysql_prepare_create_table(THD *thd, HA_CREATE_INFO *create_info,
} }
/* Don't pack rows in old tables if the user has requested this */ /* Don't pack rows in old tables if the user has requested this */
if ((sql_field->flags & BLOB_FLAG) || if ((sql_field->flags & BLOB_FLAG) ||
(sql_field->sql_type == MYSQL_TYPE_VARCHAR && (sql_field->real_field_type() == MYSQL_TYPE_VARCHAR &&
create_info->row_type != ROW_TYPE_FIXED)) create_info->row_type != ROW_TYPE_FIXED))
(*db_options)|= HA_OPTION_PACK_RECORD; (*db_options)|= HA_OPTION_PACK_RECORD;
it2.rewind(); it2.rewind();
@ -3421,7 +3421,7 @@ mysql_prepare_create_table(THD *thd, HA_CREATE_INFO *create_info,
if (sql_field->prepare_create_field(&blob_columns, file->ha_table_flags())) if (sql_field->prepare_create_field(&blob_columns, file->ha_table_flags()))
DBUG_RETURN(TRUE); DBUG_RETURN(TRUE);
if (sql_field->sql_type == MYSQL_TYPE_VARCHAR) if (sql_field->real_field_type() == MYSQL_TYPE_VARCHAR)
create_info->varchar= TRUE; create_info->varchar= TRUE;
sql_field->offset= record_offset; sql_field->offset= record_offset;
if (MTYP_TYPENR(sql_field->unireg_check) == Field::NEXT_NUMBER) if (MTYP_TYPENR(sql_field->unireg_check) == Field::NEXT_NUMBER)
@ -3721,8 +3721,8 @@ mysql_prepare_create_table(THD *thd, HA_CREATE_INFO *create_info,
cols2.rewind(); cols2.rewind();
if (key->type == Key::FULLTEXT) if (key->type == Key::FULLTEXT)
{ {
if ((sql_field->sql_type != MYSQL_TYPE_STRING && if ((sql_field->real_field_type() != MYSQL_TYPE_STRING &&
sql_field->sql_type != MYSQL_TYPE_VARCHAR && sql_field->real_field_type() != MYSQL_TYPE_VARCHAR &&
!f_is_blob(sql_field->pack_flag)) || !f_is_blob(sql_field->pack_flag)) ||
sql_field->charset == &my_charset_bin || sql_field->charset == &my_charset_bin ||
sql_field->charset->mbminlen > 1 || // ucs2 doesn't work yet sql_field->charset->mbminlen > 1 || // ucs2 doesn't work yet
@ -3848,7 +3848,7 @@ mysql_prepare_create_table(THD *thd, HA_CREATE_INFO *create_info,
if (f_is_blob(sql_field->pack_flag)) if (f_is_blob(sql_field->pack_flag))
{ {
key_part_length= MY_MIN(column->length, key_part_length= MY_MIN(column->length,
blob_length_by_type(sql_field->sql_type) blob_length_by_type(sql_field->real_field_type())
* sql_field->charset->mbmaxlen); * sql_field->charset->mbmaxlen);
if (key_part_length > max_key_length || if (key_part_length > max_key_length ||
key_part_length > file->max_key_part_length()) key_part_length > file->max_key_part_length())
@ -3878,7 +3878,7 @@ mysql_prepare_create_table(THD *thd, HA_CREATE_INFO *create_info,
// is prefix length bigger than field length? // is prefix length bigger than field length?
(column->length > key_part_length || (column->length > key_part_length ||
// can the field have a partial key? // can the field have a partial key?
!Field::type_can_have_key_part (sql_field->sql_type) || !sql_field->type_handler()->type_can_have_key_part() ||
// a packed field can't be used in a partial key // a packed field can't be used in a partial key
f_is_packed(sql_field->pack_flag) || f_is_packed(sql_field->pack_flag) ||
// does the storage engine allow prefixed search? // does the storage engine allow prefixed search?
@ -3922,12 +3922,12 @@ mysql_prepare_create_table(THD *thd, HA_CREATE_INFO *create_info,
if (!((*db_options) & HA_OPTION_NO_PACK_KEYS) && if (!((*db_options) & HA_OPTION_NO_PACK_KEYS) &&
!((create_info->table_options & HA_OPTION_NO_PACK_KEYS)) && !((create_info->table_options & HA_OPTION_NO_PACK_KEYS)) &&
(key_part_length >= KEY_DEFAULT_PACK_LENGTH && (key_part_length >= KEY_DEFAULT_PACK_LENGTH &&
(sql_field->sql_type == MYSQL_TYPE_STRING || (sql_field->real_field_type() == MYSQL_TYPE_STRING ||
sql_field->sql_type == MYSQL_TYPE_VARCHAR || sql_field->real_field_type() == MYSQL_TYPE_VARCHAR ||
sql_field->pack_flag & FIELDFLAG_BLOB))) sql_field->pack_flag & FIELDFLAG_BLOB)))
{ {
if ((column_nr == 0 && (sql_field->pack_flag & FIELDFLAG_BLOB)) || if ((column_nr == 0 && (sql_field->pack_flag & FIELDFLAG_BLOB)) ||
sql_field->sql_type == MYSQL_TYPE_VARCHAR) sql_field->real_field_type() == MYSQL_TYPE_VARCHAR)
key_info->flags|= HA_BINARY_PACK_KEY | HA_VAR_LENGTH_KEY; key_info->flags|= HA_BINARY_PACK_KEY | HA_VAR_LENGTH_KEY;
else else
key_info->flags|= HA_PACK_KEY; key_info->flags|= HA_PACK_KEY;
@ -4028,7 +4028,7 @@ mysql_prepare_create_table(THD *thd, HA_CREATE_INFO *create_info,
if (!sql_field->default_value && if (!sql_field->default_value &&
!sql_field->has_default_function() && !sql_field->has_default_function() &&
(sql_field->flags & NOT_NULL_FLAG) && (sql_field->flags & NOT_NULL_FLAG) &&
!is_timestamp_type(sql_field->sql_type)) !sql_field->is_timestamp_type())
{ {
sql_field->flags|= NO_DEFAULT_VALUE_FLAG; sql_field->flags|= NO_DEFAULT_VALUE_FLAG;
sql_field->pack_flag|= FIELDFLAG_NO_DEFAULT; sql_field->pack_flag|= FIELDFLAG_NO_DEFAULT;
@ -4036,7 +4036,7 @@ mysql_prepare_create_table(THD *thd, HA_CREATE_INFO *create_info,
if (thd->variables.sql_mode & MODE_NO_ZERO_DATE && if (thd->variables.sql_mode & MODE_NO_ZERO_DATE &&
!sql_field->default_value && !sql_field->vcol_info && !sql_field->default_value && !sql_field->vcol_info &&
is_timestamp_type(sql_field->sql_type) && sql_field->is_timestamp_type() &&
(sql_field->flags & NOT_NULL_FLAG) && (sql_field->flags & NOT_NULL_FLAG) &&
(type == Field::NONE || type == Field::TIMESTAMP_UN_FIELD)) (type == Field::NONE || type == Field::TIMESTAMP_UN_FIELD))
{ {
@ -4219,7 +4219,7 @@ bool Column_definition::prepare_blob_field(THD *thd)
static_cast<ulong>(MAX_FIELD_VARCHARLENGTH / charset->mbmaxlen)); static_cast<ulong>(MAX_FIELD_VARCHARLENGTH / charset->mbmaxlen));
DBUG_RETURN(1); DBUG_RETURN(1);
} }
sql_type= MYSQL_TYPE_BLOB; set_handler(&type_handler_blob);
flags|= BLOB_FLAG; flags|= BLOB_FLAG;
my_snprintf(warn_buff, sizeof(warn_buff), ER_THD(thd, ER_AUTO_CONVERT), my_snprintf(warn_buff, sizeof(warn_buff), ER_THD(thd, ER_AUTO_CONVERT),
field_name.str, field_name.str,
@ -4231,13 +4231,13 @@ bool Column_definition::prepare_blob_field(THD *thd)
if ((flags & BLOB_FLAG) && length) if ((flags & BLOB_FLAG) && length)
{ {
if (sql_type == FIELD_TYPE_BLOB || if (real_field_type() == FIELD_TYPE_BLOB ||
sql_type == FIELD_TYPE_TINY_BLOB || real_field_type() == FIELD_TYPE_TINY_BLOB ||
sql_type == FIELD_TYPE_MEDIUM_BLOB) real_field_type() == FIELD_TYPE_MEDIUM_BLOB)
{ {
/* The user has given a length to the blob column */ /* The user has given a length to the blob column */
sql_type= get_blob_type_from_length(length); set_handler(Type_handler::blob_type_handler(length));
pack_length= calc_pack_length(sql_type, 0); pack_length= calc_pack_length(real_field_type(), 0);
} }
length= 0; length= 0;
} }
@ -4262,7 +4262,8 @@ bool Column_definition::prepare_blob_field(THD *thd)
bool Column_definition::sp_prepare_create_field(THD *thd, MEM_ROOT *mem_root) bool Column_definition::sp_prepare_create_field(THD *thd, MEM_ROOT *mem_root)
{ {
if (sql_type == MYSQL_TYPE_SET || sql_type == MYSQL_TYPE_ENUM) if (real_field_type() == MYSQL_TYPE_SET ||
real_field_type() == MYSQL_TYPE_ENUM)
{ {
/* /*
Pass "false" as the last argument to allocate TYPELIB values on mem_root, Pass "false" as the last argument to allocate TYPELIB values on mem_root,
@ -4272,7 +4273,7 @@ bool Column_definition::sp_prepare_create_field(THD *thd, MEM_ROOT *mem_root)
return true; // E.g. wrong values with commas: SET('a,b') return true; // E.g. wrong values with commas: SET('a,b')
} }
if (sql_type == MYSQL_TYPE_BIT) if (real_field_type() == MYSQL_TYPE_BIT)
pack_flag= FIELDFLAG_NUMBER | FIELDFLAG_TREAT_BIT_AS_CHAR; pack_flag= FIELDFLAG_NUMBER | FIELDFLAG_TREAT_BIT_AS_CHAR;
create_length_to_internal_length(); create_length_to_internal_length();
DBUG_ASSERT(default_value == 0); DBUG_ASSERT(default_value == 0);
@ -6819,7 +6820,7 @@ bool mysql_compare_tables(TABLE *table,
if (create_info->row_type == ROW_TYPE_DYNAMIC || if (create_info->row_type == ROW_TYPE_DYNAMIC ||
create_info->row_type == ROW_TYPE_PAGE || create_info->row_type == ROW_TYPE_PAGE ||
(tmp_new_field->flags & BLOB_FLAG) || (tmp_new_field->flags & BLOB_FLAG) ||
(tmp_new_field->sql_type == MYSQL_TYPE_VARCHAR && (tmp_new_field->real_field_type() == MYSQL_TYPE_VARCHAR &&
create_info->row_type != ROW_TYPE_FIXED)) create_info->row_type != ROW_TYPE_FIXED))
create_info->table_options|= HA_OPTION_PACK_RECORD; create_info->table_options|= HA_OPTION_PACK_RECORD;
@ -7611,10 +7612,10 @@ mysql_prepare_alter_table(THD *thd, TABLE *table,
If the '0000-00-00' value isn't allowed then raise the error_if_not_empty If the '0000-00-00' value isn't allowed then raise the error_if_not_empty
flag to allow ALTER TABLE only if the table to be altered is empty. flag to allow ALTER TABLE only if the table to be altered is empty.
*/ */
if ((def->sql_type == MYSQL_TYPE_DATE || if ((def->real_field_type() == MYSQL_TYPE_DATE ||
def->sql_type == MYSQL_TYPE_NEWDATE || def->real_field_type() == MYSQL_TYPE_NEWDATE ||
def->sql_type == MYSQL_TYPE_DATETIME || def->real_field_type() == MYSQL_TYPE_DATETIME ||
def->sql_type == MYSQL_TYPE_DATETIME2) && def->real_field_type() == MYSQL_TYPE_DATETIME2) &&
!alter_ctx->datetime_field && !alter_ctx->datetime_field &&
!(~def->flags & (NO_DEFAULT_VALUE_FLAG | NOT_NULL_FLAG)) && !(~def->flags & (NO_DEFAULT_VALUE_FLAG | NOT_NULL_FLAG)) &&
thd->variables.sql_mode & MODE_NO_ZERO_DATE) thd->variables.sql_mode & MODE_NO_ZERO_DATE)
@ -7776,16 +7777,17 @@ mysql_prepare_alter_table(THD *thd, TABLE *table,
- data type maximum length is 255. - data type maximum length is 255.
- key_part_length is 1016 (=254*4, where 4 is mbmaxlen) - key_part_length is 1016 (=254*4, where 4 is mbmaxlen)
*/ */
if (!Field::type_can_have_key_part(cfield->field->type()) || if (!cfield->field->type_handler()->type_can_have_key_part() ||
!Field::type_can_have_key_part(cfield->sql_type) || !cfield->type_handler()->type_can_have_key_part() ||
/* spatial keys can't have sub-key length */ /* spatial keys can't have sub-key length */
(key_info->flags & HA_SPATIAL) || (key_info->flags & HA_SPATIAL) ||
(cfield->field->field_length == key_part_length && (cfield->field->field_length == key_part_length &&
!f_is_blob(key_part->key_type)) || !f_is_blob(key_part->key_type)) ||
(cfield->length && (((cfield->sql_type >= MYSQL_TYPE_TINY_BLOB && (cfield->length &&
cfield->sql_type <= MYSQL_TYPE_BLOB) ? (((cfield->real_field_type() >= MYSQL_TYPE_TINY_BLOB &&
blob_length_by_type(cfield->sql_type) : cfield->real_field_type() <= MYSQL_TYPE_BLOB) ?
cfield->length) < blob_length_by_type(cfield->real_field_type()) :
cfield->length) <
key_part_length / key_part->field->charset()->mbmaxlen))) key_part_length / key_part->field->charset()->mbmaxlen)))
key_part_length= 0; // Use whole field key_part_length= 0; // Use whole field
} }
@ -9494,7 +9496,7 @@ err_new_table_cleanup:
{ {
const char *f_val= 0; const char *f_val= 0;
enum enum_mysql_timestamp_type t_type= MYSQL_TIMESTAMP_DATE; enum enum_mysql_timestamp_type t_type= MYSQL_TIMESTAMP_DATE;
switch (alter_ctx.datetime_field->sql_type) switch (alter_ctx.datetime_field->real_field_type())
{ {
case MYSQL_TYPE_DATE: case MYSQL_TYPE_DATE:
case MYSQL_TYPE_NEWDATE: case MYSQL_TYPE_NEWDATE:

View File

@ -584,6 +584,20 @@ public:
{ {
return MYSQL_TIMESTAMP_ERROR; return MYSQL_TIMESTAMP_ERROR;
} }
virtual bool is_timestamp_type() const
{
return false;
}
/**
Check whether a field type can be partially indexed by a key.
@param type field type
@retval true Type can have a prefixed key
@retval false Type can not have a prefixed key
*/
virtual bool type_can_have_key_part() const
{
return false;
}
/** /**
Prepared statement long data: Prepared statement long data:
Check whether this parameter data type is compatible with long data. Check whether this parameter data type is compatible with long data.
@ -1837,6 +1851,10 @@ public:
{ {
return MYSQL_TIMESTAMP_DATETIME; return MYSQL_TIMESTAMP_DATETIME;
} }
bool is_timestamp_type() const
{
return true;
}
uint Item_decimal_scale(const Item *item) const uint Item_decimal_scale(const Item *item) const
{ {
return Item_decimal_scale_with_seconds(item); return Item_decimal_scale_with_seconds(item);
@ -1938,7 +1956,17 @@ public:
}; };
class Type_handler_string: public Type_handler_string_result class Type_handler_longstr: public Type_handler_string_result
{
public:
bool type_can_have_key_part() const
{
return true;
}
};
class Type_handler_string: public Type_handler_longstr
{ {
static const Name m_name_char; static const Name m_name_char;
public: public:
@ -1979,7 +2007,7 @@ public:
}; };
class Type_handler_varchar: public Type_handler_string_result class Type_handler_varchar: public Type_handler_longstr
{ {
static const Name m_name_varchar; static const Name m_name_varchar;
public: public:
@ -2004,7 +2032,7 @@ public:
}; };
class Type_handler_blob_common: public Type_handler_string_result class Type_handler_blob_common: public Type_handler_longstr
{ {
public: public:
virtual ~Type_handler_blob_common() { } virtual ~Type_handler_blob_common() { }
@ -2101,6 +2129,10 @@ public:
enum_field_types field_type() const { return MYSQL_TYPE_GEOMETRY; } enum_field_types field_type() const { return MYSQL_TYPE_GEOMETRY; }
bool is_param_long_data_type() const { return true; } bool is_param_long_data_type() const { return true; }
const Type_handler *type_handler_for_comparison() const; const Type_handler *type_handler_for_comparison() const;
bool type_can_have_key_part() const
{
return true;
}
bool subquery_type_allows_materialization(const Item *inner, bool subquery_type_allows_materialization(const Item *inner,
const Item *outer) const const Item *outer) const
{ {
@ -2213,6 +2245,10 @@ public:
{ {
return m_type_handler->mysql_timestamp_type(); return m_type_handler->mysql_timestamp_type();
} }
bool is_timestamp_type() const
{
return m_type_handler->is_timestamp_type();
}
void set_handler(const Type_handler *other) void set_handler(const Type_handler *other)
{ {
m_type_handler= other; m_type_handler= other;

View File

@ -3817,7 +3817,7 @@ sp_proc_stmt_return:
i= new (thd->mem_root) i= new (thd->mem_root)
sp_instr_freturn(sp->instructions(), lex->spcont, $3, sp_instr_freturn(sp->instructions(), lex->spcont, $3,
sp->m_return_field_def.sql_type, lex); sp->m_return_field_def.type_handler(), lex);
if (i == NULL || sp->add_instr(i)) if (i == NULL || sp->add_instr(i))
MYSQL_YYABORT; MYSQL_YYABORT;
sp->m_flags|= sp_head::HAS_RETURN; sp->m_flags|= sp_head::HAS_RETURN;
@ -6116,7 +6116,7 @@ field_type_or_serial:
field_def field_def
| SERIAL_SYM | SERIAL_SYM
{ {
Lex->last_field->sql_type= MYSQL_TYPE_LONGLONG; Lex->last_field->set_handler(&type_handler_longlong);
Lex->last_field->flags|= AUTO_INCREMENT_FLAG | NOT_NULL_FLAG Lex->last_field->flags|= AUTO_INCREMENT_FLAG | NOT_NULL_FLAG
| UNSIGNED_FLAG | UNIQUE_KEY_FLAG; | UNSIGNED_FLAG | UNIQUE_KEY_FLAG;
} }

View File

@ -3392,7 +3392,7 @@ sp_proc_stmt_return:
i= new (thd->mem_root) i= new (thd->mem_root)
sp_instr_freturn(sp->instructions(), lex->spcont, $3, sp_instr_freturn(sp->instructions(), lex->spcont, $3,
sp->m_return_field_def.sql_type, lex); sp->m_return_field_def.type_handler(), lex);
if (i == NULL || sp->add_instr(i)) if (i == NULL || sp->add_instr(i))
MYSQL_YYABORT; MYSQL_YYABORT;
sp->m_flags|= sp_head::HAS_RETURN; sp->m_flags|= sp_head::HAS_RETURN;
@ -5988,7 +5988,7 @@ field_type_or_serial:
field_def field_def
| SERIAL_SYM | SERIAL_SYM
{ {
Lex->last_field->sql_type= MYSQL_TYPE_LONGLONG; Lex->last_field->set_handler(&type_handler_longlong);
Lex->last_field->flags|= AUTO_INCREMENT_FLAG | NOT_NULL_FLAG Lex->last_field->flags|= AUTO_INCREMENT_FLAG | NOT_NULL_FLAG
| UNSIGNED_FLAG | UNIQUE_KEY_FLAG; | UNSIGNED_FLAG | UNIQUE_KEY_FLAG;
} }

View File

@ -1753,6 +1753,7 @@ int TABLE_SHARE::init_from_binary_frm_image(THD *thd, bool write,
Virtual_column_info *vcol_info= 0; Virtual_column_info *vcol_info= 0;
uint gis_length, gis_decimals, srid= 0; uint gis_length, gis_decimals, srid= 0;
Field::utype unireg_check; Field::utype unireg_check;
const Type_handler *handler;
if (new_frm_ver >= 3) if (new_frm_ver >= 3)
{ {
@ -1964,9 +1965,11 @@ int TABLE_SHARE::init_from_binary_frm_image(THD *thd, bool write,
unireg_check= (Field::utype) MTYP_TYPENR(unireg_type); 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)))
goto err; // Not supported field type
*field_ptr= reg_field= *field_ptr= reg_field=
make_field(share, &share->mem_root, record+recpos, (uint32) field_length, make_field(share, &share->mem_root, record+recpos, (uint32) field_length,
null_pos, null_bit_pos, pack_flag, field_type, charset, null_pos, null_bit_pos, pack_flag, handler, charset,
geom_type, srid, unireg_check, geom_type, srid, unireg_check,
(interval_nr ? share->intervals+interval_nr-1 : NULL), (interval_nr ? share->intervals+interval_nr-1 : NULL),
&name); &name);

View File

@ -626,7 +626,7 @@ static bool pack_header(THD *thd, uchar *forminfo,
We mark first TIMESTAMP field with NOW() in DEFAULT or ON UPDATE We mark first TIMESTAMP field with NOW() in DEFAULT or ON UPDATE
as auto-update field. as auto-update field.
*/ */
if (field->sql_type == MYSQL_TYPE_TIMESTAMP && if (field->real_field_type() == MYSQL_TYPE_TIMESTAMP &&
MTYP_TYPENR(field->unireg_check) != Field::NONE && MTYP_TYPENR(field->unireg_check) != Field::NONE &&
!time_stamp_pos) !time_stamp_pos)
time_stamp_pos= (uint) field->offset+ (uint) data_offset + 1; time_stamp_pos= (uint) field->offset+ (uint) data_offset + 1;
@ -808,8 +808,8 @@ static bool pack_fields(uchar **buff_arg, List<Create_field> &create_fields,
int2store(buff+8,field->pack_flag); int2store(buff+8,field->pack_flag);
buff[10]= (uchar) field->unireg_check; buff[10]= (uchar) field->unireg_check;
buff[12]= (uchar) field->interval_id; buff[12]= (uchar) field->interval_id;
buff[13]= (uchar) field->sql_type; buff[13]= (uchar) field->real_field_type();
if (field->sql_type == MYSQL_TYPE_GEOMETRY) if (field->real_field_type() == MYSQL_TYPE_GEOMETRY)
{ {
buff[11]= 0; buff[11]= 0;
buff[14]= (uchar) field->geom_type; buff[14]= (uchar) field->geom_type;
@ -954,7 +954,7 @@ static bool make_empty_rec(THD *thd, uchar *buff, uint table_options,
null_pos + null_count / 8, null_pos + null_count / 8,
null_count & 7, null_count & 7,
field->pack_flag, field->pack_flag,
field->sql_type, field->type_handler(),
field->charset, field->charset,
field->geom_type, field->srid, field->geom_type, field->srid,
field->unireg_check, field->unireg_check,
@ -976,7 +976,8 @@ static bool make_empty_rec(THD *thd, uchar *buff, uint table_options,
null_count++; null_count++;
} }
if (field->sql_type == MYSQL_TYPE_BIT && !f_bit_as_char(field->pack_flag)) if (field->real_field_type() == MYSQL_TYPE_BIT &&
!f_bit_as_char(field->pack_flag))
null_count+= field->length & 7; null_count+= field->length & 7;
if (field->default_value && !field->default_value->flags && if (field->default_value && !field->default_value->flags &&

View File

@ -735,7 +735,7 @@ ha_innobase::check_if_supported_inplace_alter(
is TIMESTAMP and it is defined as NOT NULL and is TIMESTAMP and it is defined as NOT NULL and
it has either constant default or function default it has either constant default or function default
we must use "Copy" method. */ we must use "Copy" method. */
if (is_timestamp_type(def->sql_type)) { if (def->is_timestamp_type()) {
if ((def->flags & NOT_NULL_FLAG) != 0 && // NOT NULL if ((def->flags & NOT_NULL_FLAG) != 0 && // NOT NULL
(def->default_value != NULL || // constant default ? (def->default_value != NULL || // constant default ?
def->unireg_check != Field::NONE)) { // function default def->unireg_check != Field::NONE)) { // function default

View File

@ -396,7 +396,7 @@ void PFS_engine_table::set_field_enum(Field *f, ulonglong value)
void PFS_engine_table::set_field_timestamp(Field *f, ulonglong value) void PFS_engine_table::set_field_timestamp(Field *f, ulonglong value)
{ {
DBUG_ASSERT(is_timestamp_type(f->real_type())); DBUG_ASSERT(f->type_handler()->is_timestamp_type());
Field_timestamp *f2= (Field_timestamp*) f; Field_timestamp *f2= (Field_timestamp*) f;
f2->store_TIME((long)(value / 1000000), (value % 1000000)); f2->store_TIME((long)(value / 1000000), (value % 1000000));
} }

View File

@ -452,7 +452,7 @@ ha_innobase::check_if_supported_inplace_alter(
is TIMESTAMP and it is defined as NOT NULL and is TIMESTAMP and it is defined as NOT NULL and
it has either constant default or function default it has either constant default or function default
we must use "Copy" method. */ we must use "Copy" method. */
if (is_timestamp_type(def->sql_type)) { if (def->is_timestamp_type()) {
if ((def->flags & NOT_NULL_FLAG) != 0 && // NOT NULL if ((def->flags & NOT_NULL_FLAG) != 0 && // NOT NULL
(def->default_value != NULL || // constant default ? (def->default_value != NULL || // constant default ?
def->unireg_check != Field::NONE)) { // function default def->unireg_check != Field::NONE)) { // function default