diff options
Diffstat (limited to 'sql/datadict.cc')
-rw-r--r-- | sql/datadict.cc | 135 |
1 files changed, 135 insertions, 0 deletions
diff --git a/sql/datadict.cc b/sql/datadict.cc index e85478a710c..decb947fb97 100644 --- a/sql/datadict.cc +++ b/sql/datadict.cc @@ -271,3 +271,138 @@ bool dd_recreate_table(THD *thd, const char *db, const char *table_name) DBUG_RETURN(ha_create_table(thd, path_buf, db, table_name, &create_info, 0, 0)); } + +bool Extra2_info::read(const uchar *frm_image, size_t frm_size) +{ + read_size= uint2korr(frm_image + 4); + + if (frm_size < FRM_HEADER_SIZE + read_size) + return true; + + const uchar *pos= frm_image + 64; + + DBUG_ENTER("Extra2_info::read"); + + if (*pos == '/') // old frm had '/' there + DBUG_RETURN(false); + + const uchar *e2end= pos + read_size; + while (pos + 3 <= e2end) + { + extra2_frm_value_type type= (extra2_frm_value_type)*pos++; + size_t length= extra2_read_len(&pos, e2end); + if (!length) + DBUG_RETURN(true); + + bool fail= false; + switch (type) { + case EXTRA2_TABLEDEF_VERSION: + if (version.str) // see init_from_sql_statement_string() + { + if (length != version.length) + DBUG_RETURN(true); + } + else + { + version.str= pos; + version.length= length; + } + break; + case EXTRA2_ENGINE_TABLEOPTS: + fail= read_once(&options, pos, length); + break; + case EXTRA2_DEFAULT_PART_ENGINE: + engine.set((const char*)pos, length); + break; + case EXTRA2_GIS: + fail= read_once(&gis, pos, length); + break; + case EXTRA2_PERIOD_FOR_SYSTEM_TIME: + fail= read_once(&system_period, pos, length) + || length != 2 * frm_fieldno_size; + break; + case EXTRA2_FIELD_FLAGS: + fail= read_once(&field_flags, pos, length); + break; + case EXTRA2_APPLICATION_TIME_PERIOD: + fail= read_once(&application_period, pos, length); + break; + case EXTRA2_FIELD_DATA_TYPE_INFO: + fail= read_once(&field_data_type_info, pos, length); + break; + case EXTRA2_PERIOD_WITHOUT_OVERLAPS: + fail= read_once(&without_overlaps, pos, length); + break; + case EXTRA2_INDEX_FLAGS: + fail= read_once(&index_flags, pos, length); + break; + default: + /* abort frm parsing if it's an unknown but important extra2 value */ + if (type >= EXTRA2_ENGINE_IMPORTANT) + DBUG_RETURN(true); + } + if (fail) + DBUG_RETURN(true); + + pos+= length; + } + if (pos != e2end) + DBUG_RETURN(true); + + DBUG_ASSERT(store_size() == read_size); + DBUG_RETURN(false); +} + + +/* + TODO: now this is used in by MDEV-20865 but this can be also used by + build_frm_image() (see TODO comment there). +*/ +uchar * +Extra2_info::write(uchar *frm_image, size_t frm_size) +{ + // FIXME: what to do with frm_size here (and in read())? + uchar *pos; + /* write the extra2 segment */ + pos = frm_image + FRM_HEADER_SIZE; + compile_time_assert(EXTRA2_TABLEDEF_VERSION != '/'); + + if (version.str) + pos= extra2_write(pos, EXTRA2_TABLEDEF_VERSION, version); + + if (engine.str) + pos= extra2_write(pos, EXTRA2_DEFAULT_PART_ENGINE, engine); + + if (options.str) + pos= extra2_write(pos, EXTRA2_ENGINE_TABLEOPTS, options); + + if (gis.str) + pos= extra2_write(pos, EXTRA2_GIS, gis); + + if (field_data_type_info.str) + pos= extra2_write(pos, EXTRA2_FIELD_DATA_TYPE_INFO, field_data_type_info); + + if (index_flags.str) + pos= extra2_write(pos, EXTRA2_INDEX_FLAGS, index_flags); + + if (system_period.str) + pos= extra2_write(pos, EXTRA2_PERIOD_FOR_SYSTEM_TIME, system_period); + + if (application_period.str) + pos= extra2_write(pos, EXTRA2_APPLICATION_TIME_PERIOD, application_period); + + if (without_overlaps.str) + pos= extra2_write(pos, EXTRA2_PERIOD_WITHOUT_OVERLAPS, without_overlaps); + + if (field_flags.str) + pos= extra2_write(pos, EXTRA2_FIELD_FLAGS, field_flags); + + write_size= pos - frm_image - FRM_HEADER_SIZE; + DBUG_ASSERT(write_size == store_size()); + DBUG_ASSERT(write_size <= 0xffff - FRM_HEADER_SIZE - 4); + +#if 0 + int4store(pos, filepos); // end of the extra2 segment +#endif + return pos; +} |