From fc4caabb0cc8f0fa503f23a34df165308eee6daa Mon Sep 17 00:00:00 2001 From: Jayesh45-master Date: Wed, 24 Dec 2025 01:39:29 +0530 Subject: [PATCH] Optional-metadata-feild --- sql/log_event.cc | 151 +++++++++++++++++++++++++++++++++------- sql/log_event.h | 45 +++++++++--- sql/log_event_client.cc | 71 +++++++++---------- 3 files changed, 192 insertions(+), 75 deletions(-) diff --git a/sql/log_event.cc b/sql/log_event.cc index 8709b63ee1b80..f676b0a31d333 100644 --- a/sql/log_event.cc +++ b/sql/log_event.cc @@ -247,6 +247,31 @@ static inline bool read_str(const uchar **buf, const uchar *buf_end, return 0; } +Table_map_log_event::Optional_metadata_fields::~Optional_metadata_fields() +{ + if (m_signedness) + my_free(m_signedness); + if (m_column_charset) + my_free(m_column_charset); + if (m_enum_and_set_column_charset) + my_free(m_enum_and_set_column_charset); + if (m_geometry_type) + my_free(m_geometry_type); + if (m_column_name) + { + for (unsigned int i=0; i < m_column_name_count; i++) + if (m_column_name[i]) + my_free(m_column_name[i]); + my_free(m_column_name); + } + if (m_column_name_len) + my_free(m_column_name_len); + if (m_column_definition) + my_free(m_column_definition); + if (m_primary_key) + my_free(m_primary_key); +} + /** Transforms a string into "" or its expression in X'HHHH' form. @@ -3580,13 +3605,16 @@ Table_map_log_event::~Table_map_log_event() @param[in] field SIGNEDNESS field in table_map_event. @param[in] length length of the field */ -static void parse_signedness(std::vector &vec, +static void parse_signedness(unsigned char *arr, unsigned int column_count, unsigned char *field, unsigned int length) { - for (unsigned int i= 0; i < length; i++) + unsigned int col= 0; + for (unsigned int i= 0; i < length && col < column_count; i++) { - for (unsigned char c= 0x80; c != 0; c>>= 1) - vec.push_back(field[i] & c); + for (unsigned char c= 0x80; c != 0 && col < column_count; c>>= 1) + { + arr[col++]= (field[i] & c) ? 1 : 0; + } } } @@ -3621,13 +3649,16 @@ static void parse_default_charset(Table_map_log_event::Optional_metadata_fields: @param[in] field COLUMN_CHARSET field in table_map_event. @param[in] length length of the field */ -static void parse_column_charset(std::vector &vec, +static void parse_column_charset(unsigned int *arr, unsigned int *out_count, unsigned char *field, unsigned int length) { unsigned char* p= field; + unsigned int col= 0; while (p < field + length) - vec.push_back(net_field_length(&p)); + arr[col++]= net_field_length(&p); + if (out_count) + *out_count= col; } /** @@ -3637,17 +3668,31 @@ static void parse_column_charset(std::vector &vec, @param[in] field COLUMN_NAME field in table_map_event. @param[in] length length of the field */ -static void parse_column_name(std::vector &vec, - unsigned char *field, unsigned int length) +static void parse_column_name(char **names, unsigned int *name_len, + unsigned int *out_count, unsigned char *field, + unsigned int length) { unsigned char* p= field; + unsigned int col= 0; while (p < field + length) { unsigned len= net_field_length(&p); - vec.push_back(std::string(reinterpret_cast(p), len)); + if (names && name_len) + { + names[col]= (char*) my_malloc(PSI_INSTRUMENT_ME, len + 1, MYF(MY_WME)); + if (names[col]) + { + memcpy(names[col], p, len); + names[col][len]= '\0'; + name_len[col]= len; + } + } p+= len; + col++; } + if (out_count) + *out_count= col; } /** @@ -3687,13 +3732,16 @@ static void parse_set_str_value(std::vector &vec, +static void parse_geometry_type(unsigned int *arr, unsigned int *out_count, unsigned char *field, unsigned int length) { unsigned char* p= field; + unsigned int col= 0; while (p < field + length) - vec.push_back(net_field_length(&p)); + arr[col++]= net_field_length(&p); + if (out_count) + *out_count= col; } /** @@ -3706,14 +3754,21 @@ static void parse_geometry_type(std::vector &vec, @param[in] field SIMPLE_PRIMARY_KEY field in table_map_event. @param[in] length length of the field */ -static void parse_simple_pk(std::vector &vec, +static void parse_simple_pk(Table_map_log_event::Optional_metadata_fields:: + uint_pair *arr, unsigned int *out_count, unsigned char *field, unsigned int length) { unsigned char* p= field; + unsigned int col= 0; while (p < field + length) - vec.push_back(std::make_pair(net_field_length(&p), 0)); + { + arr[col].first= net_field_length(&p); + arr[col].second= 0; + col++; + } + if (out_count) + *out_count= col; } /** @@ -3726,26 +3781,63 @@ static void parse_simple_pk(std::vector &vec, +static void parse_pk_with_prefix(Table_map_log_event::Optional_metadata_fields:: + uint_pair *arr, unsigned int *out_count, unsigned char *field, unsigned int length) { unsigned char* p= field; - + unsigned int col= 0; while (p < field + length) { unsigned int col_index= net_field_length(&p); unsigned int col_prefix= net_field_length(&p); - vec.push_back(std::make_pair(col_index, col_prefix)); + arr[col].first= col_index; + arr[col].second= col_prefix; + col++; } + if (out_count) + *out_count= col; } Table_map_log_event::Optional_metadata_fields:: Optional_metadata_fields(unsigned char* optional_metadata, - unsigned int optional_metadata_len) + unsigned int optional_metadata_len, + unsigned int column_count) { unsigned char* field= optional_metadata; + /* Initialize array members */ + m_signedness= NULL; + m_column_charset= NULL; m_column_charset_count= 0; + m_enum_and_set_column_charset= NULL; m_enum_and_set_column_charset_count= 0; + m_geometry_type= NULL; m_geometry_type_count= 0; + + if (column_count > 0) + { + m_signedness= (unsigned char*) my_malloc(PSI_INSTRUMENT_ME, column_count, MYF(MY_WME)); + if (m_signedness) memset(m_signedness, 0, column_count); + + m_column_charset= (unsigned int*) my_malloc(PSI_INSTRUMENT_ME, sizeof(unsigned int) * column_count, MYF(MY_WME)); + m_column_charset_count= 0; + + m_enum_and_set_column_charset= (unsigned int*) my_malloc(PSI_INSTRUMENT_ME, sizeof(unsigned int) * column_count, MYF(MY_WME)); + m_enum_and_set_column_charset_count= 0; + + m_geometry_type= (unsigned int*) my_malloc(PSI_INSTRUMENT_ME, sizeof(unsigned int) * column_count, MYF(MY_WME)); + m_geometry_type_count= 0; + + m_column_name= (char**) my_malloc(PSI_INSTRUMENT_ME, sizeof(char*) * column_count, MYF(MY_WME)); + m_column_name_len= (unsigned int*) my_malloc(PSI_INSTRUMENT_ME, sizeof(unsigned int) * column_count, MYF(MY_WME)); + m_column_name_count= 0; + + m_column_definition= (Column_definition**) my_malloc(PSI_INSTRUMENT_ME, sizeof(Column_definition*) * column_count, MYF(MY_WME)); + m_column_definition_count= 0; + if (m_column_definition) memset(m_column_definition, 0, sizeof(Column_definition*) * column_count); + + m_primary_key= (uint_pair*) my_malloc(PSI_INSTRUMENT_ME, sizeof(uint_pair) * column_count, MYF(MY_WME)); + m_primary_key_count= 0; + } + if (optional_metadata == NULL) return; @@ -3762,16 +3854,19 @@ Optional_metadata_fields(unsigned char* optional_metadata, switch(type) { case SIGNEDNESS: - parse_signedness(m_signedness, field, len); + if (m_signedness) + parse_signedness(m_signedness, column_count, field, len); break; case DEFAULT_CHARSET: parse_default_charset(m_default_charset, field, len); break; case COLUMN_CHARSET: - parse_column_charset(m_column_charset, field, len); + if (m_column_charset) + parse_column_charset(m_column_charset, &m_column_charset_count, field, len); break; case COLUMN_NAME: - parse_column_name(m_column_name, field, len); + if (m_column_name) + parse_column_name(m_column_name, m_column_name_len, &m_column_name_count, field, len); break; case SET_STR_VALUE: parse_set_str_value(m_set_str_value, field, len); @@ -3780,19 +3875,23 @@ Optional_metadata_fields(unsigned char* optional_metadata, parse_set_str_value(m_enum_str_value, field, len); break; case GEOMETRY_TYPE: - parse_geometry_type(m_geometry_type, field, len); + if (m_geometry_type) + parse_geometry_type(m_geometry_type, &m_geometry_type_count, field, len); break; case SIMPLE_PRIMARY_KEY: - parse_simple_pk(m_primary_key, field, len); + if (m_primary_key) + parse_simple_pk(m_primary_key, &m_primary_key_count, field, len); break; case PRIMARY_KEY_WITH_PREFIX: - parse_pk_with_prefix(m_primary_key, field, len); + if (m_primary_key) + parse_pk_with_prefix(m_primary_key, &m_primary_key_count, field, len); break; case ENUM_AND_SET_DEFAULT_CHARSET: parse_default_charset(m_enum_and_set_default_charset, field, len); break; case ENUM_AND_SET_COLUMN_CHARSET: - parse_column_charset(m_enum_and_set_column_charset, field, len); + if (m_enum_and_set_column_charset) + parse_column_charset(m_enum_and_set_column_charset, &m_enum_and_set_column_charset_count, field, len); break; default: DBUG_ASSERT(0); diff --git a/sql/log_event.h b/sql/log_event.h index 5c174a9e403b4..dab246c0d4397 100644 --- a/sql/log_event.h +++ b/sql/log_event.h @@ -4309,6 +4309,9 @@ class table_def; */ +/* Forward declare the global Column_definition used across the server. */ +class Column_definition; + class Table_map_log_event : public Log_event { public: @@ -4383,6 +4386,7 @@ class Table_map_log_event : public Log_event Metadata_fields organizes m_optional_metadata into a structured format which is easy to access. */ + /* Use the global Column_definition for per-column metadata. */ // Values for binlog_row_metadata sysvar enum enum_binlog_row_metadata { @@ -4412,21 +4416,40 @@ class Table_map_log_event : public Log_event // Contents of ENUM_AND_SET_DEFAULT_CHARSET are converted into // Default_charset. Default_charset m_enum_and_set_default_charset; - std::vector m_signedness; - // Character set number of every string column - std::vector m_column_charset; - // Character set number of every ENUM or SET column. - std::vector m_enum_and_set_column_charset; - std::vector m_column_name; + + /* Per-column arrays (allocated when constructed). NULL if absent. */ + unsigned char *m_signedness; /* one byte per column, 0/1 */ + + /* Character set number of every string column (array) */ + unsigned int *m_column_charset; + unsigned int m_column_charset_count; + + /* Character set number of every ENUM or SET column (array) */ + unsigned int *m_enum_and_set_column_charset; + unsigned int m_enum_and_set_column_charset_count; + + /* Column names stored as array of char* and lengths */ + char **m_column_name; + unsigned int *m_column_name_len; + unsigned int m_column_name_count; // each str_vector stores values of one enum/set column std::vector m_enum_str_value; std::vector m_set_str_value; - std::vector m_geometry_type; + + /* Geometry types for geometry columns (array), and count */ + unsigned int *m_geometry_type; + unsigned int m_geometry_type_count; + /* The uint_pair means . Prefix length is 0 if whole column value is used. */ - std::vector m_primary_key; + uint_pair *m_primary_key; + unsigned int m_primary_key_count; + + /* Per-column Column_definition pointers (NULL if not constructed). */ + Column_definition **m_column_definition; + unsigned int m_column_definition_count; /* It parses m_optional_metadata and populates into above variables. @@ -4434,9 +4457,13 @@ class Table_map_log_event : public Log_event @param[in] optional_metadata points to the begin of optional metadata fields in table_map_event. @param[in] optional_metadata_len length of optional_metadata field. + @param[in] column_count number of columns in the table map event */ Optional_metadata_fields(unsigned char* optional_metadata, - unsigned int optional_metadata_len); + unsigned int optional_metadata_len, + unsigned int column_count); + + ~Optional_metadata_fields(); }; /** diff --git a/sql/log_event_client.cc b/sql/log_event_client.cc index 57f41d5897152..b019ab6c89dcd 100644 --- a/sql/log_event_client.cc +++ b/sql/log_event_client.cc @@ -3175,7 +3175,8 @@ bool Table_map_log_event::print(FILE *file, PRINT_EVENT_INFO *print_event_info) if (print_event_info->print_table_metadata) { Optional_metadata_fields fields(m_optional_metadata, - m_optional_metadata_len); + m_optional_metadata_len, + m_colcnt); print_columns(&print_event_info->head_cache, fields); print_primary_key(&print_event_info->head_cache, fields); @@ -3210,9 +3211,9 @@ class Table_map_log_event::Charset_iterator /** Factory method to create an instance of the appropriate subclass. */ - static std::unique_ptr create_charset_iterator( + static std::unique_ptr create_charset_iterator( const Default_charset &default_charset, - const std::vector &column_charset); + const unsigned int *column_charset, unsigned int column_charset_count); }; /** @@ -3253,8 +3254,9 @@ class Table_map_log_event::Default_charset_iterator : public Charset_iterator class Table_map_log_event::Column_charset_iterator : public Charset_iterator { public: - Column_charset_iterator(const std::vector &column_charset) - : m_iterator(column_charset.begin()), m_end(column_charset.end()) {} + Column_charset_iterator(const unsigned int *column_charset, + unsigned int column_charset_count) + : m_iterator(column_charset), m_end(column_charset + column_charset_count) {} const CHARSET_INFO *next() override { const CHARSET_INFO *ret = nullptr; @@ -3267,22 +3269,22 @@ class Table_map_log_event::Column_charset_iterator : public Charset_iterator ~Column_charset_iterator(){}; private: - std::vector::const_iterator m_iterator; - std::vector::const_iterator m_end; + const unsigned int *m_iterator; + const unsigned int *m_end; }; //Table_map_log_event::Column_charset_iterator::~Column_charset_iterator(){int a=8;a++; a--;}; std::unique_ptr Table_map_log_event::Charset_iterator::create_charset_iterator( const Default_charset &default_charset, - const std::vector &column_charset) + const unsigned int *column_charset, unsigned int column_charset_count) { if (!default_charset.empty()) return std::unique_ptr( new Default_charset_iterator(default_charset)); else return std::unique_ptr( - new Column_charset_iterator(column_charset)); + new Column_charset_iterator(column_charset, column_charset_count)); } /** return the string name of a type. @@ -3441,24 +3443,22 @@ void Table_map_log_event::print_columns(IO_CACHE *file, const Optional_metadata_fields &fields) { unsigned char* field_metadata_ptr= m_field_metadata; - std::vector::const_iterator signedness_it= fields.m_signedness.begin(); - std::unique_ptr charset_it = Charset_iterator::create_charset_iterator(fields.m_default_charset, - fields.m_column_charset); + fields.m_column_charset, + fields.m_column_charset_count); std::unique_ptr enum_and_set_charset_it = Charset_iterator::create_charset_iterator( fields.m_enum_and_set_default_charset, - fields.m_enum_and_set_column_charset); - std::vector::const_iterator col_names_it= - fields.m_column_name.begin(); + fields.m_enum_and_set_column_charset, + fields.m_enum_and_set_column_charset_count); + (void)0; /* no-op to keep similar structure */ std::vector::const_iterator set_str_values_it= fields.m_set_str_value.begin(); std::vector::const_iterator enum_str_values_it= fields.m_enum_str_value.begin(); - std::vector::const_iterator geometry_type_it= - fields.m_geometry_type.begin(); - + const unsigned int *geometry_type_it= fields.m_geometry_type; + unsigned int geometry_type_idx= 0; uint geometry_type= 0; my_b_printf(file, "# Columns("); @@ -3480,11 +3480,10 @@ void Table_map_log_event::print_columns(IO_CACHE *file, cs = enum_and_set_charset_it->next(); // Print column name - if (col_names_it != fields.m_column_name.end()) + if (i < fields.m_column_name_count && fields.m_column_name[i]) { - pretty_print_identifier(file, col_names_it->c_str(), col_names_it->size()); + pretty_print_identifier(file, fields.m_column_name[i], fields.m_column_name_len[i]); my_b_printf(file, " "); - col_names_it++; } @@ -3509,12 +3508,10 @@ void Table_map_log_event::print_columns(IO_CACHE *file, my_b_printf(file, "%s", type_name); // Print UNSIGNED for numeric column - if (is_numeric_type(real_type) && - signedness_it != fields.m_signedness.end()) + if (is_numeric_type(real_type) && fields.m_signedness != NULL) { - if (*signedness_it == true) + if (fields.m_signedness[i]) my_b_printf(file, " UNSIGNED"); - signedness_it++; } // if the column is not marked as 'null', print 'not null' @@ -3562,29 +3559,23 @@ void Table_map_log_event::print_columns(IO_CACHE *file, void Table_map_log_event::print_primary_key (IO_CACHE *file,const Optional_metadata_fields &fields) { - if (!fields.m_primary_key.empty()) + if (fields.m_primary_key_count > 0) { my_b_printf(file, "# Primary Key("); - - std::vector::const_iterator it= - fields.m_primary_key.begin(); - - for (; it != fields.m_primary_key.end(); it++) + for (unsigned int idx= 0; idx < fields.m_primary_key_count; idx++) { - if (it != fields.m_primary_key.begin()) + if (idx != 0) my_b_printf(file, ", "); - // Print column name or column index - if (it->first >= fields.m_column_name.size()) - my_b_printf(file, "%u", it->first); + auto &p= fields.m_primary_key[idx]; + if (p.first >= fields.m_column_name_count) + my_b_printf(file, "%u", p.first); else - my_b_printf(file, "%s", fields.m_column_name[it->first].c_str()); + my_b_printf(file, "%s", fields.m_column_name[p.first]); - // Print prefix length - if (it->second != 0) - my_b_printf(file, "(%u)", it->second); + if (p.second != 0) + my_b_printf(file, "(%u)", p.second); } - my_b_printf(file, ")\n"); } }