Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
M
MariaDB
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Analytics
Analytics
CI / CD
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
nexedi
MariaDB
Commits
f5845574
Commit
f5845574
authored
May 24, 2018
by
Alexander Barkov
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
MDEV-9216 Split field.cc:make_field() into virtual methods in Type_handler
parent
dc580225
Changes
6
Hide whitespace changes
Inline
Side-by-side
Showing
6 changed files
with
972 additions
and
465 deletions
+972
-465
sql/field.cc
sql/field.cc
+46
-272
sql/field.h
sql/field.h
+49
-31
sql/sql_type.cc
sql/sql_type.cc
+484
-0
sql/sql_type.h
sql/sql_type.h
+216
-0
sql/table.cc
sql/table.cc
+168
-129
sql/unireg.cc
sql/unireg.cc
+9
-33
No files found.
sql/field.cc
View file @
f5845574
...
...
@@ -10529,21 +10529,32 @@ uint pack_length_to_packflag(uint type)
}
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
*
field_charset
,
Field
::
geometry_type
geom_type
,
uint
srid
,
Field
::
utype
unireg_check
,
TYPELIB
*
interval
,
const
LEX_CSTRING
*
field_name
,
uint32
flags
)
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
,
const
Type_handler
*
handler
,
const
LEX_CSTRING
*
field_name
,
uint32
flags
)
const
{
DBUG_ASSERT
(
length
<=
UINT_MAX32
);
DBUG_PRINT
(
"debug"
,
(
"field_type: %s, field_length: %u, interval: %p, pack_flag: %s%s%s%s%s"
,
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
:
{
Bit_addr
bit
(
rec
->
null
());
if
(
!
f_bit_as_char
(
pack_flag
)
&&
f_maybe_null
(
pack_flag
))
bit
.
inc
();
return
(
f_bit_as_char
(
pack_flag
)
?
new
(
mem_root
)
Field_bit_as_char
(
addr
.
ptr
(),
field_length
,
addr
.
null_ptr
(),
addr
.
null_bit
(),
unireg_check
,
field_name
)
:
new
(
mem_root
)
Field_bit
(
addr
.
ptr
(),
field_length
,
addr
.
null_ptr
(),
addr
.
null_bit
(),
bit
.
ptr
(),
bit
.
offs
(),
unireg_check
,
field_name
));
}
default:
// Impossible (Wrong version)
break
;
}
return
0
;
/*
Special code for the BIT-alike data types
who store data bits together with NULL-bits.
*/
Bit_addr
bit
(
rec
->
null
());
if
(
f_maybe_null
(
pack_flag
))
bit
.
inc
();
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
;
...
...
sql/field.h
View file @
f5845574
...
...
@@ -4072,21 +4072,53 @@ class Field_row: public Field_null
extern
const
LEX_CSTRING
null_clex_str
;
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
);
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
,
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 @@ class Column_definition: public Sql_alloc,
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 @@ class Column_definition: public Sql_alloc,
*/
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 @@ class Column_definition: public Sql_alloc,
:
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,10 +4335,9 @@ class Column_definition: public Sql_alloc,
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
,
field_name_arg
,
flags
);
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
,
const
LEX_CSTRING
*
field_name_arg
)
const
...
...
@@ -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)
...
...
sql/sql_type.cc
View file @
f5845574
...
...
@@ -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
/***************************************************************************/
sql/sql_type.h
View file @
f5845574
...
...
@@ -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 @@ class Type_handler
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 @@ class Type_handler_row: public Type_handler
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 @@ class Type_handler_tiny: public Type_handler_general_purpose_int
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 @@ class Type_handler_short: public Type_handler_general_purpose_int
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 @@ class Type_handler_long: public Type_handler_general_purpose_int
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 @@ class Type_handler_longlong: public Type_handler_general_purpose_int
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 @@ class Type_handler_int24: public Type_handler_general_purpose_int
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 @@ class Type_handler_year: public Type_handler_int_result
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 @@ class Type_handler_bit: public Type_handler_int_result
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 @@ class Type_handler_float: public Type_handler_real_result
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 @@ class Type_handler_double: public Type_handler_real_result
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 @@ class Type_handler_time: public Type_handler_time_common
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 @@ class Type_handler_time2: public Type_handler_time_common
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 @@ class Type_handler_date: public Type_handler_date_common
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 @@ class Type_handler_newdate: public Type_handler_date_common
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 @@ class Type_handler_datetime: public Type_handler_datetime_common
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 @@ class Type_handler_datetime2: public Type_handler_datetime_common
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 @@ class Type_handler_timestamp: public Type_handler_timestamp_common
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 @@ class Type_handler_timestamp2: public Type_handler_timestamp_common
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 @@ class Type_handler_olddecimal: public Type_handler_decimal_result
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 @@ class Type_handler_newdecimal: public Type_handler_decimal_result
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 @@ class Type_handler_null: public Type_handler_general_purpose_string
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 @@ class Type_handler_string: public Type_handler_longstr
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 @@ class Type_handler_varchar: public Type_handler_longstr
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 @@ class Type_handler_blob_common: public Type_handler_longstr
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 @@ class Type_handler_geometry: public Type_handler_string_result
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 @@ class Type_handler_geometry: public Type_handler_string_result
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 @@ class Type_handler_enum: public Type_handler_typelib
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 @@ class Type_handler_set: public Type_handler_typelib
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
;
};
...
...
sql/table.cc
View file @
f5845574
...
...
@@ -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 @@ bool parse_vcol_defs(THD *thd, MEM_ROOT *mem_root, TABLE *table,
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
)(
FRM_VCOL_OLD_HEADER_SIZE
(
opt_interval_id
));
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
,
MY_CS_BINSORT
,
MYF
(
0
))))
charset
=
&
my_charset_bin
;
if
(
!
(
attr
.
charset
=
get_charset_by_csname
(
share
->
table_charset
->
csname
,
MY_CS_BINSORT
,
MYF
(
0
))))
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
)
...
...
sql/unireg.cc
View file @
f5845574
...
...
@@ -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,18 +1025,14 @@ 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
->
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
);
Field
*
regfield
=
tmp
.
make_field
(
&
share
,
thd
->
mem_root
,
&
addr
,
field
->
type_handler
(),
&
field
->
field_name
,
field
->
flags
);
if
(
!
regfield
)
{
error
=
1
;
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment