diff options
Diffstat (limited to 'sql/unireg.cc')
-rw-r--r-- | sql/unireg.cc | 142 |
1 files changed, 121 insertions, 21 deletions
diff --git a/sql/unireg.cc b/sql/unireg.cc index 1342e4c2b66..7bb08cfbf7b 100644 --- a/sql/unireg.cc +++ b/sql/unireg.cc @@ -25,7 +25,7 @@ str is a (long) to record position where 0 is the first position. */ -#include <my_global.h> +#include "mariadb.h" #include "sql_priv.h" #include "unireg.h" #include "sql_partition.h" // struct partition_info @@ -87,7 +87,69 @@ static uchar *extra2_write(uchar *pos, enum extra2_frm_value_type type, return extra2_write(pos, type, reinterpret_cast<LEX_CSTRING *>(str)); } -/* +static uchar *extra2_write_field_properties(uchar *pos, + List<Create_field> &create_fields) +{ + List_iterator<Create_field> it(create_fields); + *pos++= EXTRA2_FIELD_FLAGS; + /* + always first 2 for field visibility + */ + pos= extra2_write_len(pos, create_fields.elements); + while (Create_field *cf= it++) + { + uchar flags= cf->invisible; + if (cf->flags & VERS_UPDATE_UNVERSIONED_FLAG) + flags|= VERS_OPTIMIZED_UPDATE; + *pos++= flags; + } + return pos; +} + +static const bool ROW_START = true; +static const bool ROW_END = false; + +static inline +uint16 +vers_get_field(HA_CREATE_INFO *create_info, List<Create_field> &create_fields, bool row_start) +{ + DBUG_ASSERT(create_info->versioned()); + + List_iterator<Create_field> it(create_fields); + Create_field *sql_field = NULL; + + const LString_i row_field= row_start ? create_info->vers_info.as_row.start + : create_info->vers_info.as_row.end; + DBUG_ASSERT(row_field); + + for (unsigned field_no = 0; (sql_field = it++); ++field_no) + { + if (row_field == sql_field->field_name) + { + DBUG_ASSERT(field_no <= uint16(~0U)); + return uint16(field_no); + } + } + + DBUG_ASSERT(0); /* Not Reachable */ + return 0; +} + +static inline +bool has_extra2_field_flags(List<Create_field> &create_fields) +{ + List_iterator<Create_field> it(create_fields); + while (Create_field *f= it++) + { + if (f->invisible) + return true; + if (f->flags & VERS_UPDATE_UNVERSIONED_FLAG) + return true; + } + return false; +} + +/** Create a frm (table definition) file @param thd Thread handler @@ -102,7 +164,7 @@ static uchar *extra2_write(uchar *pos, enum extra2_frm_value_type type, or null LEX_CUSTRING (str==0) in case of an error. */ -LEX_CUSTRING build_frm_image(THD *thd, const char *table, +LEX_CUSTRING build_frm_image(THD *thd, const LEX_CSTRING *table, HA_CREATE_INFO *create_info, List<Create_field> &create_fields, uint keys, KEY *key_info, handler *db_file) @@ -110,12 +172,13 @@ LEX_CUSTRING build_frm_image(THD *thd, const char *table, LEX_CSTRING str_db_type; uint reclength, key_info_length, i; ulong key_buff_length; - ulong filepos, data_offset; + size_t filepos; + ulong data_offset; uint options_len; uint gis_extra2_len= 0; uchar fileinfo[FRM_HEADER_SIZE],forminfo[FRM_FORMINFO_SIZE]; const partition_info *part_info= IF_PARTITIONING(thd->work_part_info, 0); - int error; + bool error; uchar *frm_ptr, *pos; LEX_CUSTRING frm= {0,0}; StringBuffer<MAX_FIELD_WIDTH> vcols; @@ -138,7 +201,7 @@ LEX_CUSTRING build_frm_image(THD *thd, const char *table, create_info->expression_length= vcols.length() + FRM_VCOL_NEW_BASE_SIZE; error= pack_header(thd, forminfo, create_fields, create_info, - data_offset, db_file); + (ulong)data_offset, db_file); if (error) DBUG_RETURN(frm); @@ -147,7 +210,7 @@ LEX_CUSTRING build_frm_image(THD *thd, const char *table, /* Calculate extra data segment length */ str_db_type= *hton_name(create_info->db_type); /* str_db_type */ - create_info->extra_size= (2 + str_db_type.length + + create_info->extra_size= (uint)(2 + str_db_type.length + 2 + create_info->connect_string.length); /* Partition: @@ -158,12 +221,12 @@ LEX_CUSTRING build_frm_image(THD *thd, const char *table, */ create_info->extra_size+= 6; if (part_info) - create_info->extra_size+= part_info->part_info_len; + create_info->extra_size+= (uint)part_info->part_info_len; for (i= 0; i < keys; i++) { if (key_info[i].parser_name) - create_info->extra_size+= key_info[i].parser_name->length + 1; + create_info->extra_size+= (uint)key_info[i].parser_name->length + 1; } options_len= engine_table_options_frm_length(create_info->option_list, @@ -175,8 +238,7 @@ LEX_CUSTRING build_frm_image(THD *thd, const char *table, DBUG_PRINT("info", ("Options length: %u", options_len)); if (validate_comment_length(thd, &create_info->comment, TABLE_COMMENT_MAXLEN, - ER_TOO_LONG_TABLE_COMMENT, - table)) + ER_TOO_LONG_TABLE_COMMENT, table->str)) DBUG_RETURN(frm); /* If table comment is longer than TABLE_COMMENT_INLINE_MAXLEN bytes, @@ -186,7 +248,7 @@ LEX_CUSTRING build_frm_image(THD *thd, const char *table, if (create_info->comment.length > TABLE_COMMENT_INLINE_MAXLEN) { forminfo[46]=255; - create_info->extra_size+= 2 + create_info->comment.length; + create_info->extra_size+= 2 + (uint)create_info->comment.length; } else { @@ -210,7 +272,7 @@ LEX_CUSTRING build_frm_image(THD *thd, const char *table, prepare_frm_header(thd, reclength, fileinfo, create_info, keys, key_info); /* one byte for a type, one or three for a length */ - uint extra2_size= 1 + 1 + create_info->tabledef_version.length; + size_t extra2_size= 1 + 1 + create_info->tabledef_version.length; if (options_len) extra2_size+= 1 + (options_len > 255 ? 3 : 1) + options_len; @@ -220,6 +282,22 @@ LEX_CUSTRING build_frm_image(THD *thd, const char *table, if (gis_extra2_len) extra2_size+= 1 + (gis_extra2_len > 255 ? 3 : 1) + gis_extra2_len; + if (create_info->versioned()) + { + extra2_size+= 1 + 1 + 2 * sizeof(uint16); + } + + if (create_info->vtmd()) + { + extra2_size+= 1 + 1 + 1; + } + + bool has_extra2_field_flags_= has_extra2_field_flags(create_fields); + if (has_extra2_field_flags_) + { + extra2_size+= 1 + (create_fields.elements > 255 ? 3 : 1) + + create_fields.elements; + } key_buff_length= uint4korr(fileinfo+47); @@ -240,7 +318,7 @@ LEX_CUSTRING build_frm_image(THD *thd, const char *table, if (frm.length > FRM_MAX_SIZE || create_info->expression_length > UINT_MAX32) { - my_error(ER_TABLE_DEFINITION_TOO_BIG, MYF(0), table); + my_error(ER_TABLE_DEFINITION_TOO_BIG, MYF(0), table->str); DBUG_RETURN(frm); } @@ -276,6 +354,26 @@ LEX_CUSTRING build_frm_image(THD *thd, const char *table, } #endif /*HAVE_SPATIAL*/ + if (create_info->versioned()) + { + *pos++= EXTRA2_PERIOD_FOR_SYSTEM_TIME; + *pos++= 2 * sizeof(uint16); + int2store(pos, vers_get_field(create_info, create_fields, ROW_START)); + pos+= sizeof(uint16); + int2store(pos, vers_get_field(create_info, create_fields, ROW_END)); + pos+= sizeof(uint16); + } + + if (create_info->vtmd()) + { + *pos++= EXTRA2_VTMD; + *pos++= 1; + *pos++= 1; + } + + if (has_extra2_field_flags_) + pos= extra2_write_field_properties(pos, create_fields); + int4store(pos, filepos); // end of the extra2 segment pos+= 4; @@ -286,7 +384,7 @@ LEX_CUSTRING build_frm_image(THD *thd, const char *table, my_printf_error(ER_CANT_CREATE_TABLE, "Cannot create table %`s: index information is too long. " "Decrease number of indexes or use shorter index names or shorter comments.", - MYF(0), table); + MYF(0), table->str); goto err; } @@ -487,7 +585,7 @@ static uint pack_keys(uchar *keybuff, uint key_count, KEY *keyinfo, *pos++=(uchar) NAMES_SEP_CHAR; for (key=keyinfo ; key != end ; key++) { - uchar *tmp=(uchar*) strmov((char*) pos,key->name); + uchar *tmp=(uchar*) strmov((char*) pos,key->name.str); *tmp++= (uchar) NAMES_SEP_CHAR; *tmp=0; pos=tmp; @@ -548,7 +646,7 @@ static bool pack_expression(String *buf, Virtual_column_info *vcol, size_t len_off= buf->length(); buf->q_append2b(0); // to be added later buf->q_append((char)vcol->name.length); - buf->q_append(vcol->name.str, vcol->name.length); + buf->q_append(&vcol->name); size_t expr_start= buf->length(); vcol->print(buf); size_t expr_len= buf->length() - expr_start; @@ -673,10 +771,10 @@ static bool pack_header(THD *thd, uchar *forminfo, { char *dst; const char *src= field->save_interval->type_names[pos]; - uint hex_length; + size_t hex_length; length= field->save_interval->type_lengths[pos]; hex_length= length * 2; - field->interval->type_lengths[pos]= hex_length; + field->interval->type_lengths[pos]= (uint)hex_length; field->interval->type_names[pos]= dst= (char*) thd->alloc(hex_length + 1); octet2hex(dst, src, length); @@ -800,7 +898,8 @@ static bool pack_fields(uchar **buff_arg, List<Create_field> &create_fields, ulong data_offset) { uchar *buff= *buff_arg; - uint int_count, comment_length= 0; + uint int_count; + size_t comment_length= 0; Create_field *field; DBUG_ENTER("pack_fields"); @@ -969,7 +1068,8 @@ static bool make_empty_rec(THD *thd, uchar *buff, uint table_options, field->unireg_check, field->save_interval ? field->save_interval : field->interval, - &field->field_name); + &field->field_name, + field->flags); if (!regfield) { error= 1; |