summaryrefslogtreecommitdiff
path: root/sql/field.h
diff options
context:
space:
mode:
Diffstat (limited to 'sql/field.h')
-rw-r--r--sql/field.h366
1 files changed, 316 insertions, 50 deletions
diff --git a/sql/field.h b/sql/field.h
index 287837ee1e7..e1017f04c27 100644
--- a/sql/field.h
+++ b/sql/field.h
@@ -32,6 +32,7 @@
#include "sql_error.h" /* Sql_condition */
#include "compat56.h"
#include "sql_type.h" /* Type_std_attributes */
+#include "field_comp.h"
class Send_field;
class Copy_field;
@@ -49,8 +50,9 @@ class Virtual_tmp_table;
enum enum_check_fields
{
CHECK_FIELD_IGNORE,
+ CHECK_FIELD_EXPRESSION,
CHECK_FIELD_WARN,
- CHECK_FIELD_ERROR_FOR_NULL
+ CHECK_FIELD_ERROR_FOR_NULL,
};
/*
@@ -557,6 +559,7 @@ static inline const char *vcol_type_name(enum_vcol_info_type type)
#define VCOL_TIME_FUNC 8
#define VCOL_AUTO_INC 16
#define VCOL_IMPOSSIBLE 32
+#define VCOL_NOT_VIRTUAL 64 /* Function can't be virtual */
#define VCOL_NOT_STRICTLY_DETERMINISTIC \
(VCOL_NON_DETERMINISTIC | VCOL_TIME_FUNC | VCOL_SESSION_FUNC)
@@ -672,7 +675,17 @@ public:
static void operator delete(void *ptr, MEM_ROOT *mem_root)
{ DBUG_ASSERT(0); }
+ /**
+ Used by System Versioning.
+ */
+ virtual void set_max()
+ { DBUG_ASSERT(0); }
+ virtual bool is_max()
+ { DBUG_ASSERT(0); return false; }
+
uchar *ptr; // Position to field in record
+
+ field_visibility_t invisible;
/**
Byte where the @c NULL bit is stored inside a record. If this Field is a
@c NOT @c NULL field, this member is @c NULL.
@@ -713,7 +726,8 @@ public:
TIMESTAMP_OLD_FIELD=18, // TIMESTAMP created before 4.1.3
TIMESTAMP_DN_FIELD=21, // TIMESTAMP DEFAULT NOW()
TIMESTAMP_UN_FIELD=22, // TIMESTAMP ON UPDATE NOW()
- TIMESTAMP_DNUN_FIELD=23 // TIMESTAMP DEFAULT NOW() ON UPDATE NOW()
+ TIMESTAMP_DNUN_FIELD=23, // TIMESTAMP DEFAULT NOW() ON UPDATE NOW()
+ TMYSQL_COMPRESSED= 24, // Compatibility with TMySQL
};
enum geometry_type
{
@@ -917,8 +931,21 @@ public:
DBUG_RETURN(field_metadata);
}
virtual uint row_pack_length() const { return 0; }
+
+
+ /**
+ Retrieve the field metadata for fields.
+
+ This default implementation returns 0 and saves 0 in the first_byte value.
+
+ @param first_byte First byte of field metadata
+
+ @returns 0 no bytes written.
+ */
+
virtual int save_field_metadata(uchar *first_byte)
- { return do_save_field_metadata(first_byte); }
+ { return 0; }
+
/*
data_length() return the "real size" of the data in memory.
@@ -989,6 +1016,13 @@ public:
}
bool set_explicit_default(Item *value);
+ virtual my_time_t get_timestamp(const uchar *pos, ulong *sec_part) const
+ { DBUG_ASSERT(0); return 0; }
+ my_time_t get_timestamp(ulong *sec_part) const
+ {
+ return get_timestamp(ptr, sec_part);
+ }
+
/**
Evaluates the @c UPDATE default function, if one exists, and stores the
result in the record buffer. If no such function exists for the column,
@@ -1430,6 +1464,21 @@ public:
FIELD_FLAGS_COLUMN_FORMAT;
}
+ bool vers_sys_field() const
+ {
+ return flags & (VERS_SYS_START_FLAG | VERS_SYS_END_FLAG);
+ }
+
+ bool vers_update_unversioned() const
+ {
+ return flags & VERS_UPDATE_UNVERSIONED_FLAG;
+ }
+
+ virtual bool vers_trx_id() const
+ {
+ return false;
+ }
+
/*
Validate a non-null field value stored in the given record
according to the current thread settings, e.g. sql_mode.
@@ -1517,6 +1566,8 @@ public:
/* Mark field in read map. Updates also virtual fields */
void register_field_in_read_map();
+ virtual Compression_method *compression_method() const { return 0; }
+
virtual Virtual_tmp_table **virtual_tmp_table_addr()
{
return NULL;
@@ -1551,19 +1602,6 @@ private:
*/
virtual size_t do_last_null_byte() const;
-/**
- Retrieve the field metadata for fields.
-
- This default implementation returns 0 and saves 0 in the metadata_ptr
- value.
-
- @param metadata_ptr First byte of field metadata
-
- @returns 0 no bytes written.
-*/
- virtual int do_save_field_metadata(uchar *metadata_ptr)
- { return 0; }
-
protected:
uchar *pack_int(uchar *to, const uchar *from, size_t size)
{
@@ -1704,7 +1742,7 @@ public:
charset() == from->charset();
}
int store(double nr);
- int store(longlong nr, bool unsigned_val)=0;
+ int store(longlong nr, bool unsigned_val);
int store_decimal(const my_decimal *);
int store(const char *to,uint length,CHARSET_INFO *cs)=0;
int store_hex_hybrid(const char *str, uint length)
@@ -1752,6 +1790,11 @@ protected:
const Item *item) const;
bool cmp_to_string_with_stricter_collation(const Item_bool_func *cond,
const Item *item) const;
+ int compress(char *to, uint *to_length,
+ const char *from, uint length,
+ CHARSET_INFO *cs);
+ String *uncompress(String *val_buffer, String *val_ptr,
+ const uchar *from, uint from_length);
public:
Field_longstr(uchar *ptr_arg, uint32 len_arg, uchar *null_ptr_arg,
uchar null_bit_arg, utype unireg_check_arg,
@@ -1862,7 +1905,7 @@ public:
/* New decimal/numeric field which use fixed point arithmetic */
class Field_new_decimal :public Field_num {
private:
- int do_save_field_metadata(uchar *first_byte);
+ int save_field_metadata(uchar *first_byte);
public:
/* The maximum number of decimal digits can be stored */
uint precision;
@@ -2144,6 +2187,57 @@ public:
{
return unpack_int64(to, from, from_end);
}
+
+ void set_max();
+ bool is_max();
+};
+
+
+class Field_vers_trx_id :public Field_longlong {
+ MYSQL_TIME cache;
+ ulonglong cached;
+public:
+ Field_vers_trx_id(uchar *ptr_arg, uint32 len_arg, uchar *null_ptr_arg,
+ uchar null_bit_arg, enum utype unireg_check_arg,
+ const LEX_CSTRING *field_name_arg, bool zero_arg,
+ bool unsigned_arg)
+ : Field_longlong(ptr_arg, len_arg, null_ptr_arg, null_bit_arg,
+ unireg_check_arg, field_name_arg, zero_arg,
+ unsigned_arg),
+ cached(0)
+ {}
+ enum_field_types real_type() const { return MYSQL_TYPE_LONGLONG; }
+ enum_field_types type() const { return MYSQL_TYPE_LONGLONG;}
+ uint size_of() const { return sizeof(*this); }
+ bool get_date(MYSQL_TIME *ltime, ulonglong fuzzydate, ulonglong trx_id);
+ bool get_date(MYSQL_TIME *ltime, ulonglong fuzzydate)
+ {
+ return get_date(ltime, fuzzydate, (ulonglong) val_int());
+ }
+ bool test_if_equality_guarantees_uniqueness(const Item *item) const;
+ bool can_optimize_keypart_ref(const Item_bool_func *cond,
+ const Item *item) const
+ {
+ return true;
+ }
+
+ bool can_optimize_group_min_max(const Item_bool_func *cond,
+ const Item *const_item) const
+ {
+ return true;
+ }
+ bool can_optimize_range(const Item_bool_func *cond,
+ const Item *item,
+ bool is_eq_func) const
+ {
+ return true;
+ }
+ /* cmp_type() cannot be TIME_RESULT, because we want to compare this field against
+ integers. But in all other cases we treat it as TIME_RESULT! */
+ bool vers_trx_id() const
+ {
+ return true;
+ }
};
@@ -2184,7 +2278,7 @@ public:
uint row_pack_length() const { return pack_length(); }
void sql_type(String &str) const;
private:
- int do_save_field_metadata(uchar *first_byte);
+ int save_field_metadata(uchar *first_byte);
};
@@ -2237,7 +2331,7 @@ public:
uint row_pack_length() const { return pack_length(); }
void sql_type(String &str) const;
private:
- int do_save_field_metadata(uchar *first_byte);
+ int save_field_metadata(uchar *first_byte);
};
@@ -2279,13 +2373,11 @@ public:
bool can_optimize_keypart_ref(const Item_bool_func *cond,
const Item *item) const
{
- DBUG_ASSERT(0);
return false;
}
bool can_optimize_group_min_max(const Item_bool_func *cond,
const Item *const_item) const
{
- DBUG_ASSERT(0);
return false;
}
};
@@ -2426,7 +2518,7 @@ public:
return res;
}
/* Get TIMESTAMP field value as seconds since begging of Unix Epoch */
- virtual my_time_t get_timestamp(const uchar *pos, ulong *sec_part) const;
+ my_time_t get_timestamp(const uchar *pos, ulong *sec_part) const;
my_time_t get_timestamp(ulong *sec_part) const
{
return get_timestamp(ptr, sec_part);
@@ -2525,7 +2617,7 @@ public:
TIMESTAMP(0..6) - MySQL56 version
*/
class Field_timestampf :public Field_timestamp_with_dec {
- int do_save_field_metadata(uchar *metadata_ptr)
+ int save_field_metadata(uchar *metadata_ptr)
{
*metadata_ptr= (uchar) decimals();
return 1;
@@ -2556,8 +2648,14 @@ public:
{
return memcmp(a_ptr, b_ptr, pack_length());
}
+ void set_max();
+ bool is_max();
void store_TIME(my_time_t timestamp, ulong sec_part);
my_time_t get_timestamp(const uchar *pos, ulong *sec_part) const;
+ my_time_t get_timestamp(ulong *sec_part) const
+ {
+ return get_timestamp(ptr, sec_part);
+ }
uint size_of() const { return sizeof(*this); }
};
@@ -2793,7 +2891,7 @@ public:
*/
class Field_timef :public Field_time_with_dec {
void store_TIME(MYSQL_TIME *ltime);
- int do_save_field_metadata(uchar *metadata_ptr)
+ int save_field_metadata(uchar *metadata_ptr)
{
*metadata_ptr= (uchar) decimals();
return 1;
@@ -2955,7 +3053,7 @@ public:
class Field_datetimef :public Field_datetime_with_dec {
void store_TIME(MYSQL_TIME *ltime);
bool get_TIME(MYSQL_TIME *ltime, const uchar *pos, ulonglong fuzzydate) const;
- int do_save_field_metadata(uchar *metadata_ptr)
+ int save_field_metadata(uchar *metadata_ptr)
{
*metadata_ptr= (uchar) decimals();
return 1;
@@ -3086,8 +3184,7 @@ public:
return 0;
}
int store(const char *to,uint length,CHARSET_INFO *charset);
- int store(longlong nr, bool unsigned_val);
- int store(double nr) { return Field_str::store(nr); } /* QQ: To be deleted */
+ using Field_str::store;
double val_real(void);
longlong val_int(void);
String *val_str(String*,String *);
@@ -3120,7 +3217,7 @@ public:
Field *make_new_field(MEM_ROOT *root, TABLE *new_table, bool keep_type);
virtual uint get_key_image(uchar *buff,uint length, imagetype type);
private:
- int do_save_field_metadata(uchar *first_byte);
+ int save_field_metadata(uchar *first_byte);
};
@@ -3134,6 +3231,15 @@ public:
{
return length_bytes == 1 ? (uint) *ptr : uint2korr(ptr);
}
+protected:
+ void store_length(uint32 number)
+ {
+ if (length_bytes == 1)
+ *ptr= (uchar) number;
+ else
+ int2store(ptr, number);
+ }
+public:
/*
The maximum space available in a Field_varstring, in bytes. See
length_bytes.
@@ -3178,11 +3284,11 @@ public:
bool memcpy_field_possible(const Field *from) const
{
return Field_str::memcpy_field_possible(from) &&
+ !compression_method() == !from->compression_method() &&
length_bytes == ((Field_varstring*) from)->length_bytes;
}
int store(const char *to,uint length,CHARSET_INFO *charset);
- int store(longlong nr, bool unsigned_val);
- int store(double nr) { return Field_str::store(nr); } /* QQ: To be deleted */
+ using Field_str::store;
double val_real(void);
longlong val_int(void);
String *val_str(String*,String *);
@@ -3216,10 +3322,91 @@ public:
void hash(ulong *nr, ulong *nr2);
uint length_size() { return length_bytes; }
private:
- int do_save_field_metadata(uchar *first_byte);
+ int save_field_metadata(uchar *first_byte);
};
+class Field_varstring_compressed: public Field_varstring {
+public:
+ Field_varstring_compressed(uchar *ptr_arg,
+ uint32 len_arg, uint length_bytes_arg,
+ uchar *null_ptr_arg, uchar null_bit_arg,
+ enum utype unireg_check_arg,
+ const LEX_CSTRING *field_name_arg,
+ TABLE_SHARE *share, const DTCollation &collation,
+ Compression_method *compression_method_arg):
+ Field_varstring(ptr_arg, len_arg, length_bytes_arg, null_ptr_arg,
+ null_bit_arg, unireg_check_arg, field_name_arg,
+ share, collation),
+ compression_method_ptr(compression_method_arg) { DBUG_ASSERT(len_arg > 0); }
+ Compression_method *compression_method() const
+ { return compression_method_ptr; }
+private:
+ Compression_method *compression_method_ptr;
+ int store(const char *to, uint length, CHARSET_INFO *charset);
+ using Field_str::store;
+ String *val_str(String *, String *);
+ double val_real(void);
+ longlong val_int(void);
+ uint size_of() const { return sizeof(*this); }
+ enum_field_types binlog_type() const { return MYSQL_TYPE_VARCHAR_COMPRESSED; }
+ void sql_type(String &str) const
+ {
+ Field_varstring::sql_type(str);
+ str.append(STRING_WITH_LEN(" /*!100301 COMPRESSED*/"));
+ }
+ uint32 max_display_length() { return field_length - 1; }
+ int cmp_max(const uchar *a_ptr, const uchar *b_ptr, uint max_len);
+
+ /*
+ Compressed fields can't have keys as two rows may have different
+ compression methods or compression levels.
+ */
+
+ int key_cmp(const uchar *str, uint length)
+ { DBUG_ASSERT(0); return 0; }
+ using Field_varstring::key_cmp;
+};
+
+
+static inline uint8 number_storage_requirement(uint32 n)
+{
+ return n < 256 ? 1 : n < 65536 ? 2 : n < 16777216 ? 3 : 4;
+}
+
+
+static inline void store_bigendian(ulonglong num, uchar *to, uint bytes)
+{
+ switch(bytes) {
+ case 1: mi_int1store(to, num); break;
+ case 2: mi_int2store(to, num); break;
+ case 3: mi_int3store(to, num); break;
+ case 4: mi_int4store(to, num); break;
+ case 5: mi_int5store(to, num); break;
+ case 6: mi_int6store(to, num); break;
+ case 7: mi_int7store(to, num); break;
+ case 8: mi_int8store(to, num); break;
+ default: DBUG_ASSERT(0);
+ }
+}
+
+
+static inline longlong read_bigendian(const uchar *from, uint bytes)
+{
+ switch(bytes) {
+ case 1: return mi_uint1korr(from);
+ case 2: return mi_uint2korr(from);
+ case 3: return mi_uint3korr(from);
+ case 4: return mi_uint4korr(from);
+ case 5: return mi_uint5korr(from);
+ case 6: return mi_uint6korr(from);
+ case 7: return mi_uint7korr(from);
+ case 8: return mi_sint8korr(from);
+ default: DBUG_ASSERT(0); return 0;
+ }
+}
+
+
extern LEX_CSTRING temp_lex_str;
class Field_blob :public Field_longstr {
@@ -3262,13 +3449,7 @@ public:
NONE, field_name_arg, collation)
{
flags|= BLOB_FLAG;
- packlength= 4;
- if (set_packlength)
- {
- packlength= len_arg <= 255 ? 1 :
- len_arg <= 65535 ? 2 :
- len_arg <= 16777215 ? 3 : 4;
- }
+ packlength= set_packlength ? number_storage_requirement(len_arg) : 4;
}
Field_blob(uint32 packlength_arg)
:Field_longstr((uchar*) 0, 0, (uchar*) "", 0, NONE, &temp_lex_str,
@@ -3301,7 +3482,8 @@ public:
if (from->type() == MYSQL_TYPE_BIT)
return do_field_int;
*/
- if (!(from->flags & BLOB_FLAG) || from->charset() != charset())
+ if (!(from->flags & BLOB_FLAG) || from->charset() != charset() ||
+ !from->compression_method() != !compression_method())
return do_conv_blob;
if (from->pack_length() != Field_blob::pack_length())
return do_copy_blob;
@@ -3318,11 +3500,11 @@ public:
bool memcpy_field_possible(const Field *from) const
{
return Field_str::memcpy_field_possible(from) &&
+ !compression_method() == !from->compression_method() &&
!table->copy_blobs;
}
- int store(const char *to,uint length,CHARSET_INFO *charset);
- int store(double nr);
- int store(longlong nr, bool unsigned_val);
+ int store(const char *to, uint length, CHARSET_INFO *charset);
+ using Field_str::store;
double val_real(void);
longlong val_int(void);
String *val_str(String*,String *);
@@ -3456,7 +3638,54 @@ public:
uint32 char_length() const;
uint is_equal(Create_field *new_field);
private:
- int do_save_field_metadata(uchar *first_byte);
+ int save_field_metadata(uchar *first_byte);
+};
+
+
+class Field_blob_compressed: public Field_blob {
+public:
+ Field_blob_compressed(uchar *ptr_arg, uchar *null_ptr_arg,
+ uchar null_bit_arg, enum utype unireg_check_arg,
+ const LEX_CSTRING *field_name_arg, TABLE_SHARE *share,
+ uint blob_pack_length, const DTCollation &collation,
+ Compression_method *compression_method_arg):
+ Field_blob(ptr_arg, null_ptr_arg, null_bit_arg, unireg_check_arg,
+ field_name_arg, share, blob_pack_length, collation),
+ compression_method_ptr(compression_method_arg) {}
+ Compression_method *compression_method() const
+ { return compression_method_ptr; }
+private:
+ Compression_method *compression_method_ptr;
+ int store(const char *to, uint length, CHARSET_INFO *charset);
+ using Field_str::store;
+ String *val_str(String *, String *);
+ double val_real(void);
+ longlong val_int(void);
+ uint size_of() const { return sizeof(*this); }
+ enum_field_types binlog_type() const { return MYSQL_TYPE_BLOB_COMPRESSED; }
+ void sql_type(String &str) const
+ {
+ Field_blob::sql_type(str);
+ str.append(STRING_WITH_LEN(" /*!100301 COMPRESSED*/"));
+ }
+
+ /*
+ Compressed fields can't have keys as two rows may have different
+ compression methods or compression levels.
+ */
+
+ uint get_key_image(uchar *buff, uint length, imagetype type_arg)
+ { DBUG_ASSERT(0); return 0; }
+ void set_key_image(const uchar *buff, uint length)
+ { DBUG_ASSERT(0); }
+ int key_cmp(const uchar *a, const uchar *b)
+ { DBUG_ASSERT(0); return 0; }
+ int key_cmp(const uchar *str, uint length)
+ { DBUG_ASSERT(0); return 0; }
+ Field *new_key_field(MEM_ROOT *root, TABLE *new_table,
+ uchar *new_ptr, uint32 length,
+ uchar *new_null_ptr, uint new_null_bit)
+ { DBUG_ASSERT(0); return 0; }
};
@@ -3621,7 +3850,7 @@ public:
const Item *item,
bool is_eq_func) const;
private:
- int do_save_field_metadata(uchar *first_byte);
+ int save_field_metadata(uchar *first_byte);
uint is_equal(Create_field *new_field);
};
@@ -3799,7 +4028,7 @@ public:
private:
virtual size_t do_last_null_byte() const;
- int do_save_field_metadata(uchar *first_byte);
+ int save_field_metadata(uchar *first_byte);
};
@@ -3848,7 +4077,8 @@ Field *make_field(TABLE_SHARE *share, MEM_ROOT *mem_root,
CHARSET_INFO *cs,
Field::geometry_type geom_type, uint srid,
Field::utype unireg_check,
- TYPELIB *interval, const LEX_CSTRING *field_name);
+ TYPELIB *interval, const LEX_CSTRING *field_name,
+ uint32 flags);
/*
Create field class for CREATE TABLE
@@ -3898,15 +4128,23 @@ class Column_definition: public Sql_alloc,
bool prepare_stage1_check_typelib_default();
bool prepare_stage1_convert_default(THD *, MEM_ROOT *, CHARSET_INFO *to);
const Type_handler *field_type() const; // Prevent using this
+ Compression_method *compression_method_ptr;
public:
LEX_CSTRING field_name;
LEX_CSTRING comment; // Comment for field
+ enum enum_column_versioning
+ {
+ VERSIONING_NOT_SET,
+ WITH_VERSIONING,
+ 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
for most of the types, or of bytes for BLOBs or numeric types.
@@ -3933,18 +4171,23 @@ public:
*default_value, // Default value
*check_constraint; // Check constraint
+ enum_column_versioning versioning;
+
Column_definition()
:Type_handler_hybrid_field_type(&type_handler_null),
+ compression_method_ptr(0),
comment(null_clex_str),
- on_update(NULL), length(0), decimals(0),
+ 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),
- vcol_info(0), default_value(0), check_constraint(0)
+ vcol_info(0), default_value(0), check_constraint(0),
+ versioning(VERSIONING_NOT_SET)
{
interval_list.empty();
}
+
Column_definition(THD *thd, Field *field, Field *orig_field);
void set_attributes(const Lex_field_type_st &type, CHARSET_INFO *cs);
void create_length_to_internal_length_null()
@@ -3959,6 +4202,8 @@ public:
void create_length_to_internal_length_string()
{
length*= charset->mbmaxlen;
+ if (real_field_type() == MYSQL_TYPE_VARCHAR && compression_method())
+ length++;
DBUG_ASSERT(length <= UINT_MAX32);
key_length= (uint) length;
pack_length= type_handler()->calc_pack_length((uint32) length);
@@ -4069,7 +4314,7 @@ public:
(uint32)length, null_pos, null_bit,
pack_flag, type_handler(), charset,
geom_type, srid, unireg_check, interval,
- field_name_arg);
+ field_name_arg, flags);
}
Field *make_field(TABLE_SHARE *share, MEM_ROOT *mem_root,
const LEX_CSTRING *field_name_arg) const
@@ -4108,6 +4353,11 @@ public:
{
*this= *def;
}
+ bool set_compressed(const char *method);
+ void set_compression_method(Compression_method *compression_method_arg)
+ { compression_method_ptr= compression_method_arg; }
+ Compression_method *compression_method() const
+ { return compression_method_ptr; }
};
@@ -4406,5 +4656,21 @@ bool check_expression(Virtual_column_info *vcol, LEX_CSTRING *name,
#define f_no_default(x) ((x) & FIELDFLAG_NO_DEFAULT)
#define f_bit_as_char(x) ((x) & FIELDFLAG_TREAT_BIT_AS_CHAR)
#define f_is_hex_escape(x) ((x) & FIELDFLAG_HEX_ESCAPE)
+#define f_visibility(x) (static_cast<field_visibility_t> ((x) & INVISIBLE_MAX_BITS))
+
+inline
+ulonglong TABLE::vers_end_id() const
+{
+ DBUG_ASSERT(versioned(VERS_TRX_ID));
+ return static_cast<ulonglong>(vers_end_field()->val_int());
+}
+
+inline
+ulonglong TABLE::vers_start_id() const
+{
+ DBUG_ASSERT(versioned(VERS_TRX_ID));
+ return static_cast<ulonglong>(vers_start_field()->val_int());
+}
+
#endif /* FIELD_INCLUDED */