1 /* Copyright (c) 2008, 2021, Oracle and/or its affiliates. 2 3 This program is free software; you can redistribute it and/or modify 4 it under the terms of the GNU General Public License, version 2.0, 5 as published by the Free Software Foundation. 6 7 This program is also distributed with certain software (including 8 but not limited to OpenSSL) that is licensed under separate terms, 9 as designated in a particular file or component or in included license 10 documentation. The authors of MySQL hereby grant you an additional 11 permission to link the program and your derivative works with the 12 separately licensed software that they have included with MySQL. 13 14 This program is distributed in the hope that it will be useful, 15 but WITHOUT ANY WARRANTY; without even the implied warranty of 16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 17 GNU General Public License, version 2.0, for more details. 18 19 You should have received a copy of the GNU General Public License 20 along with this program; if not, write to the Free Software 21 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */ 22 23 #ifndef PFS_TABLE_HELPER_H 24 #define PFS_TABLE_HELPER_H 25 26 #include "pfs_column_types.h" 27 #include "pfs_stat.h" 28 #include "pfs_timer.h" 29 #include "pfs_engine_table.h" 30 #include "pfs_instr_class.h" 31 #include "pfs_digest.h" 32 33 /* 34 Write MD5 hash value in a string to be used 35 as DIGEST for the statement. 36 */ 37 #define MD5_HASH_TO_STRING(_hash, _str) \ 38 sprintf(_str, "%02x%02x%02x%02x%02x%02x%02x%02x" \ 39 "%02x%02x%02x%02x%02x%02x%02x%02x", \ 40 _hash[0], _hash[1], _hash[2], _hash[3], \ 41 _hash[4], _hash[5], _hash[6], _hash[7], \ 42 _hash[8], _hash[9], _hash[10], _hash[11], \ 43 _hash[12], _hash[13], _hash[14], _hash[15]) 44 45 #define MD5_HASH_TO_STRING_LENGTH 32 46 47 struct PFS_host; 48 struct PFS_user; 49 struct PFS_account; 50 struct PFS_object_name; 51 struct PFS_program; 52 class System_variable; 53 class Status_variable; 54 55 /** 56 @file storage/perfschema/table_helper.h 57 Performance schema table helpers (declarations). 58 */ 59 60 /** 61 @addtogroup Performance_schema_tables 62 @{ 63 */ 64 65 /** Namespace, internal views used within table setup_instruments. */ 66 struct PFS_instrument_view_constants 67 { 68 static const uint FIRST_VIEW= 1; 69 static const uint VIEW_MUTEX= 1; 70 static const uint VIEW_RWLOCK= 2; 71 static const uint VIEW_COND= 3; 72 static const uint VIEW_FILE= 4; 73 static const uint VIEW_TABLE= 5; 74 static const uint VIEW_SOCKET= 6; 75 static const uint VIEW_IDLE= 7; 76 static const uint VIEW_METADATA= 8; 77 static const uint LAST_VIEW= 8; 78 }; 79 80 /** Namespace, internal views used within object summaries. */ 81 struct PFS_object_view_constants 82 { 83 static const uint FIRST_VIEW= 1; 84 static const uint VIEW_TABLE= 1; 85 static const uint VIEW_PROGRAM= 2; 86 static const uint LAST_VIEW= 2; 87 }; 88 89 /** Row fragment for column HOST. */ 90 struct PFS_host_row 91 { 92 /** Column HOST. */ 93 char m_hostname[HOSTNAME_LENGTH]; 94 /** Length in bytes of @c m_hostname. */ 95 uint m_hostname_length; 96 97 /** Build a row from a memory buffer. */ 98 int make_row(PFS_host *pfs); 99 /** Set a table field from the row. */ 100 void set_field(Field *f); 101 }; 102 103 /** Row fragment for column USER. */ 104 struct PFS_user_row 105 { 106 /** Column USER. */ 107 char m_username[USERNAME_LENGTH]; 108 /** Length in bytes of @c m_username. */ 109 uint m_username_length; 110 111 /** Build a row from a memory buffer. */ 112 int make_row(PFS_user *pfs); 113 /** Set a table field from the row. */ 114 void set_field(Field *f); 115 }; 116 117 /** Row fragment for columns USER, HOST. */ 118 struct PFS_account_row 119 { 120 /** Column USER. */ 121 char m_username[USERNAME_LENGTH]; 122 /** Length in bytes of @c m_username. */ 123 uint m_username_length; 124 /** Column HOST. */ 125 char m_hostname[HOSTNAME_LENGTH]; 126 /** Length in bytes of @c m_hostname. */ 127 uint m_hostname_length; 128 129 /** Build a row from a memory buffer. */ 130 int make_row(PFS_account *pfs); 131 /** Set a table field from the row. */ 132 void set_field(uint index, Field *f); 133 }; 134 135 /** Row fragment for columns DIGEST, DIGEST_TEXT. */ 136 struct PFS_digest_row 137 { 138 /** Column SCHEMA_NAME. */ 139 char m_schema_name[NAME_LEN]; 140 /** Length in bytes of @c m_schema_name. */ 141 uint m_schema_name_length; 142 /** Column DIGEST. */ 143 char m_digest[COL_DIGEST_SIZE]; 144 /** Length in bytes of @c m_digest. */ 145 uint m_digest_length; 146 /** Column DIGEST_TEXT. */ 147 String m_digest_text; 148 149 /** Build a row from a memory buffer. */ 150 int make_row(PFS_statements_digest_stat*); 151 /** Set a table field from the row. */ 152 void set_field(uint index, Field *f); 153 }; 154 155 /** Row fragment for column EVENT_NAME. */ 156 struct PFS_event_name_row 157 { 158 /** Column EVENT_NAME. */ 159 const char *m_name; 160 /** Length in bytes of @c m_name. */ 161 uint m_name_length; 162 163 /** Build a row from a memory buffer. */ make_rowPFS_event_name_row164 inline void make_row(PFS_instr_class *pfs) 165 { 166 m_name= pfs->m_name; 167 m_name_length= pfs->m_name_length; 168 } 169 170 /** Set a table field from the row. */ set_fieldPFS_event_name_row171 inline void set_field(Field *f) 172 { 173 PFS_engine_table::set_field_varchar_utf8(f, m_name, m_name_length); 174 } 175 }; 176 177 /** Row fragment for columns OBJECT_TYPE, SCHEMA_NAME, OBJECT_NAME. */ 178 struct PFS_object_row 179 { 180 /** Column OBJECT_TYPE. */ 181 enum_object_type m_object_type; 182 /** Column SCHEMA_NAME. */ 183 char m_schema_name[NAME_LEN]; 184 /** Length in bytes of @c m_schema_name. */ 185 uint m_schema_name_length; 186 /** Column OBJECT_NAME. */ 187 char m_object_name[NAME_LEN]; 188 /** Length in bytes of @c m_object_name. */ 189 uint m_object_name_length; 190 191 /** Build a row from a memory buffer. */ 192 int make_row(PFS_table_share *pfs); 193 int make_row(PFS_program *pfs); 194 int make_row(const MDL_key *pfs); 195 /** Set a table field from the row. */ 196 void set_field(uint index, Field *f); 197 void set_nullable_field(uint index, Field *f); 198 }; 199 200 /** Row fragment for columns OBJECT_TYPE, SCHEMA_NAME, OBJECT_NAME, INDEX_NAME. */ 201 struct PFS_index_row 202 { 203 PFS_object_row m_object_row; 204 /** Column INDEX_NAME. */ 205 char m_index_name[NAME_LEN]; 206 /** Length in bytes of @c m_index_name. */ 207 uint m_index_name_length; 208 209 /** Build a row from a memory buffer. */ 210 int make_row(PFS_table_share *pfs, PFS_table_share_index *pfs_index, 211 uint table_index); 212 /** Set a table field from the row. */ 213 void set_field(uint index, Field *f); 214 }; 215 216 /** Row fragment for single statistics columns (COUNT, SUM, MIN, AVG, MAX) */ 217 struct PFS_stat_row 218 { 219 /** Column COUNT_STAR. */ 220 ulonglong m_count; 221 /** Column SUM_TIMER_WAIT. */ 222 ulonglong m_sum; 223 /** Column MIN_TIMER_WAIT. */ 224 ulonglong m_min; 225 /** Column AVG_TIMER_WAIT. */ 226 ulonglong m_avg; 227 /** Column MAX_TIMER_WAIT. */ 228 ulonglong m_max; 229 resetPFS_stat_row230 inline void reset() 231 { 232 m_count= 0; 233 m_sum= 0; 234 m_min= 0; 235 m_avg= 0; 236 m_max= 0; 237 } 238 239 /** Build a row with timer fields from a memory buffer. */ setPFS_stat_row240 inline void set(time_normalizer *normalizer, const PFS_single_stat *stat) 241 { 242 m_count= stat->m_count; 243 244 if ((m_count != 0) && stat->has_timed_stats()) 245 { 246 m_sum= normalizer->wait_to_pico(stat->m_sum); 247 m_min= normalizer->wait_to_pico(stat->m_min); 248 m_max= normalizer->wait_to_pico(stat->m_max); 249 m_avg= normalizer->wait_to_pico(stat->m_sum / m_count); 250 } 251 else 252 { 253 m_sum= 0; 254 m_min= 0; 255 m_avg= 0; 256 m_max= 0; 257 } 258 } 259 260 /** Set a table field from the row. */ set_fieldPFS_stat_row261 void set_field(uint index, Field *f) 262 { 263 switch (index) 264 { 265 case 0: /* COUNT */ 266 PFS_engine_table::set_field_ulonglong(f, m_count); 267 break; 268 case 1: /* SUM */ 269 PFS_engine_table::set_field_ulonglong(f, m_sum); 270 break; 271 case 2: /* MIN */ 272 PFS_engine_table::set_field_ulonglong(f, m_min); 273 break; 274 case 3: /* AVG */ 275 PFS_engine_table::set_field_ulonglong(f, m_avg); 276 break; 277 case 4: /* MAX */ 278 PFS_engine_table::set_field_ulonglong(f, m_max); 279 break; 280 default: 281 assert(false); 282 } 283 } 284 }; 285 286 /** Row fragment for timer and byte count stats. Corresponds to PFS_byte_stat */ 287 struct PFS_byte_stat_row 288 { 289 PFS_stat_row m_waits; 290 ulonglong m_bytes; 291 292 /** Build a row with timer and byte count fields from a memory buffer. */ setPFS_byte_stat_row293 inline void set(time_normalizer *normalizer, const PFS_byte_stat *stat) 294 { 295 m_waits.set(normalizer, stat); 296 m_bytes= stat->m_bytes; 297 } 298 }; 299 300 /** Row fragment for table io statistics columns. */ 301 struct PFS_table_io_stat_row 302 { 303 PFS_stat_row m_all; 304 PFS_stat_row m_all_read; 305 PFS_stat_row m_all_write; 306 PFS_stat_row m_fetch; 307 PFS_stat_row m_insert; 308 PFS_stat_row m_update; 309 PFS_stat_row m_delete; 310 311 /** Build a row from a memory buffer. */ setPFS_table_io_stat_row312 inline void set(time_normalizer *normalizer, const PFS_table_io_stat *stat) 313 { 314 PFS_single_stat all_read; 315 PFS_single_stat all_write; 316 PFS_single_stat all; 317 318 m_fetch.set(normalizer, & stat->m_fetch); 319 320 all_read.aggregate(& stat->m_fetch); 321 322 m_insert.set(normalizer, & stat->m_insert); 323 m_update.set(normalizer, & stat->m_update); 324 m_delete.set(normalizer, & stat->m_delete); 325 326 all_write.aggregate(& stat->m_insert); 327 all_write.aggregate(& stat->m_update); 328 all_write.aggregate(& stat->m_delete); 329 330 all.aggregate(& all_read); 331 all.aggregate(& all_write); 332 333 m_all_read.set(normalizer, & all_read); 334 m_all_write.set(normalizer, & all_write); 335 m_all.set(normalizer, & all); 336 } 337 }; 338 339 /** Row fragment for table lock statistics columns. */ 340 struct PFS_table_lock_stat_row 341 { 342 PFS_stat_row m_all; 343 PFS_stat_row m_all_read; 344 PFS_stat_row m_all_write; 345 PFS_stat_row m_read_normal; 346 PFS_stat_row m_read_with_shared_locks; 347 PFS_stat_row m_read_high_priority; 348 PFS_stat_row m_read_no_insert; 349 PFS_stat_row m_read_external; 350 PFS_stat_row m_write_allow_write; 351 PFS_stat_row m_write_concurrent_insert; 352 PFS_stat_row m_write_low_priority; 353 PFS_stat_row m_write_normal; 354 PFS_stat_row m_write_external; 355 356 /** Build a row from a memory buffer. */ setPFS_table_lock_stat_row357 inline void set(time_normalizer *normalizer, const PFS_table_lock_stat *stat) 358 { 359 PFS_single_stat all_read; 360 PFS_single_stat all_write; 361 PFS_single_stat all; 362 363 m_read_normal.set(normalizer, & stat->m_stat[PFS_TL_READ]); 364 m_read_with_shared_locks.set(normalizer, & stat->m_stat[PFS_TL_READ_WITH_SHARED_LOCKS]); 365 m_read_high_priority.set(normalizer, & stat->m_stat[PFS_TL_READ_HIGH_PRIORITY]); 366 m_read_no_insert.set(normalizer, & stat->m_stat[PFS_TL_READ_NO_INSERT]); 367 m_read_external.set(normalizer, & stat->m_stat[PFS_TL_READ_EXTERNAL]); 368 369 all_read.aggregate(& stat->m_stat[PFS_TL_READ]); 370 all_read.aggregate(& stat->m_stat[PFS_TL_READ_WITH_SHARED_LOCKS]); 371 all_read.aggregate(& stat->m_stat[PFS_TL_READ_HIGH_PRIORITY]); 372 all_read.aggregate(& stat->m_stat[PFS_TL_READ_NO_INSERT]); 373 all_read.aggregate(& stat->m_stat[PFS_TL_READ_EXTERNAL]); 374 375 m_write_allow_write.set(normalizer, & stat->m_stat[PFS_TL_WRITE_ALLOW_WRITE]); 376 m_write_concurrent_insert.set(normalizer, & stat->m_stat[PFS_TL_WRITE_CONCURRENT_INSERT]); 377 m_write_low_priority.set(normalizer, & stat->m_stat[PFS_TL_WRITE_LOW_PRIORITY]); 378 m_write_normal.set(normalizer, & stat->m_stat[PFS_TL_WRITE]); 379 m_write_external.set(normalizer, & stat->m_stat[PFS_TL_WRITE_EXTERNAL]); 380 381 all_write.aggregate(& stat->m_stat[PFS_TL_WRITE_ALLOW_WRITE]); 382 all_write.aggregate(& stat->m_stat[PFS_TL_WRITE_CONCURRENT_INSERT]); 383 all_write.aggregate(& stat->m_stat[PFS_TL_WRITE_LOW_PRIORITY]); 384 all_write.aggregate(& stat->m_stat[PFS_TL_WRITE]); 385 all_write.aggregate(& stat->m_stat[PFS_TL_WRITE_EXTERNAL]); 386 387 all.aggregate(& all_read); 388 all.aggregate(& all_write); 389 390 m_all_read.set(normalizer, & all_read); 391 m_all_write.set(normalizer, & all_write); 392 m_all.set(normalizer, & all); 393 } 394 }; 395 396 /** Row fragment for stage statistics columns. */ 397 struct PFS_stage_stat_row 398 { 399 PFS_stat_row m_timer1_row; 400 401 /** Build a row from a memory buffer. */ setPFS_stage_stat_row402 inline void set(time_normalizer *normalizer, const PFS_stage_stat *stat) 403 { 404 m_timer1_row.set(normalizer, & stat->m_timer1_stat); 405 } 406 407 /** Set a table field from the row. */ set_fieldPFS_stage_stat_row408 void set_field(uint index, Field *f) 409 { 410 m_timer1_row.set_field(index, f); 411 } 412 }; 413 414 /** Row fragment for statement statistics columns. */ 415 struct PFS_statement_stat_row 416 { 417 PFS_stat_row m_timer1_row; 418 ulonglong m_error_count; 419 ulonglong m_warning_count; 420 ulonglong m_rows_affected; 421 ulonglong m_lock_time; 422 ulonglong m_rows_sent; 423 ulonglong m_rows_examined; 424 ulonglong m_created_tmp_disk_tables; 425 ulonglong m_created_tmp_tables; 426 ulonglong m_select_full_join; 427 ulonglong m_select_full_range_join; 428 ulonglong m_select_range; 429 ulonglong m_select_range_check; 430 ulonglong m_select_scan; 431 ulonglong m_sort_merge_passes; 432 ulonglong m_sort_range; 433 ulonglong m_sort_rows; 434 ulonglong m_sort_scan; 435 ulonglong m_no_index_used; 436 ulonglong m_no_good_index_used; 437 438 /** Build a row from a memory buffer. */ setPFS_statement_stat_row439 inline void set(time_normalizer *normalizer, const PFS_statement_stat *stat) 440 { 441 if (stat->m_timer1_stat.m_count != 0) 442 { 443 m_timer1_row.set(normalizer, & stat->m_timer1_stat); 444 445 m_error_count= stat->m_error_count; 446 m_warning_count= stat->m_warning_count; 447 m_lock_time= stat->m_lock_time * MICROSEC_TO_PICOSEC; 448 m_rows_affected= stat->m_rows_affected; 449 m_rows_sent= stat->m_rows_sent; 450 m_rows_examined= stat->m_rows_examined; 451 m_created_tmp_disk_tables= stat->m_created_tmp_disk_tables; 452 m_created_tmp_tables= stat->m_created_tmp_tables; 453 m_select_full_join= stat->m_select_full_join; 454 m_select_full_range_join= stat->m_select_full_range_join; 455 m_select_range= stat->m_select_range; 456 m_select_range_check= stat->m_select_range_check; 457 m_select_scan= stat->m_select_scan; 458 m_sort_merge_passes= stat->m_sort_merge_passes; 459 m_sort_range= stat->m_sort_range; 460 m_sort_rows= stat->m_sort_rows; 461 m_sort_scan= stat->m_sort_scan; 462 m_no_index_used= stat->m_no_index_used; 463 m_no_good_index_used= stat->m_no_good_index_used; 464 } 465 else 466 { 467 m_timer1_row.reset(); 468 469 m_error_count= 0; 470 m_warning_count= 0; 471 m_lock_time= 0; 472 m_rows_affected= 0; 473 m_rows_sent= 0; 474 m_rows_examined= 0; 475 m_created_tmp_disk_tables= 0; 476 m_created_tmp_tables= 0; 477 m_select_full_join= 0; 478 m_select_full_range_join= 0; 479 m_select_range= 0; 480 m_select_range_check= 0; 481 m_select_scan= 0; 482 m_sort_merge_passes= 0; 483 m_sort_range= 0; 484 m_sort_rows= 0; 485 m_sort_scan= 0; 486 m_no_index_used= 0; 487 m_no_good_index_used= 0; 488 } 489 } 490 491 /** Set a table field from the row. */ 492 void set_field(uint index, Field *f); 493 }; 494 495 /** Row fragment for stored program statistics. */ 496 struct PFS_sp_stat_row 497 { 498 PFS_stat_row m_timer1_row; 499 500 /** Build a row from a memory buffer. */ setPFS_sp_stat_row501 inline void set(time_normalizer *normalizer, const PFS_sp_stat *stat) 502 { 503 m_timer1_row.set(normalizer, & stat->m_timer1_stat); 504 } 505 506 /** Set a table field from the row. */ set_fieldPFS_sp_stat_row507 inline void set_field(uint index, Field *f) 508 { 509 m_timer1_row.set_field(index, f); 510 } 511 }; 512 513 /** Row fragment for transaction statistics columns. */ 514 struct PFS_transaction_stat_row 515 { 516 PFS_stat_row m_timer1_row; 517 PFS_stat_row m_read_write_row; 518 PFS_stat_row m_read_only_row; 519 ulonglong m_savepoint_count; 520 ulonglong m_rollback_to_savepoint_count; 521 ulonglong m_release_savepoint_count; 522 523 /** Build a row from a memory buffer. */ setPFS_transaction_stat_row524 inline void set(time_normalizer *normalizer, const PFS_transaction_stat *stat) 525 { 526 /* Combine read write/read only stats */ 527 PFS_single_stat all; 528 all.aggregate(&stat->m_read_only_stat); 529 all.aggregate(&stat->m_read_write_stat); 530 531 m_timer1_row.set(normalizer, &all); 532 m_read_write_row.set(normalizer, &stat->m_read_write_stat); 533 m_read_only_row.set(normalizer, &stat->m_read_only_stat); 534 } 535 536 /** Set a table field from the row. */ 537 void set_field(uint index, Field *f); 538 }; 539 540 /** Row fragment for connection statistics. */ 541 struct PFS_connection_stat_row 542 { 543 ulonglong m_current_connections; 544 ulonglong m_total_connections; 545 setPFS_connection_stat_row546 inline void set(const PFS_connection_stat *stat) 547 { 548 m_current_connections= stat->m_current_connections; 549 m_total_connections= stat->m_total_connections; 550 } 551 552 /** Set a table field from the row. */ 553 void set_field(uint index, Field *f); 554 }; 555 556 void set_field_object_type(Field *f, enum_object_type object_type); 557 void set_field_lock_type(Field *f, PFS_TL_LOCK_TYPE lock_type); 558 void set_field_mdl_type(Field *f, opaque_mdl_type mdl_type); 559 void set_field_mdl_duration(Field *f, opaque_mdl_duration mdl_duration); 560 void set_field_mdl_status(Field *f, opaque_mdl_status mdl_status); 561 void set_field_isolation_level(Field *f, enum_isolation_level iso_level); 562 void set_field_xa_state(Field *f, enum_xa_transaction_state xa_state); 563 564 /** Row fragment for socket io statistics columns. */ 565 struct PFS_socket_io_stat_row 566 { 567 PFS_byte_stat_row m_read; 568 PFS_byte_stat_row m_write; 569 PFS_byte_stat_row m_misc; 570 PFS_byte_stat_row m_all; 571 setPFS_socket_io_stat_row572 inline void set(time_normalizer *normalizer, const PFS_socket_io_stat *stat) 573 { 574 PFS_byte_stat all; 575 576 m_read.set(normalizer, &stat->m_read); 577 m_write.set(normalizer, &stat->m_write); 578 m_misc.set(normalizer, &stat->m_misc); 579 580 /* Combine stats for all operations */ 581 all.aggregate(&stat->m_read); 582 all.aggregate(&stat->m_write); 583 all.aggregate(&stat->m_misc); 584 585 m_all.set(normalizer, &all); 586 } 587 }; 588 589 /** Row fragment for file io statistics columns. */ 590 struct PFS_file_io_stat_row 591 { 592 PFS_byte_stat_row m_read; 593 PFS_byte_stat_row m_write; 594 PFS_byte_stat_row m_misc; 595 PFS_byte_stat_row m_all; 596 setPFS_file_io_stat_row597 inline void set(time_normalizer *normalizer, const PFS_file_io_stat *stat) 598 { 599 PFS_byte_stat all; 600 601 m_read.set(normalizer, &stat->m_read); 602 m_write.set(normalizer, &stat->m_write); 603 m_misc.set(normalizer, &stat->m_misc); 604 605 /* Combine stats for all operations */ 606 all.aggregate(&stat->m_read); 607 all.aggregate(&stat->m_write); 608 all.aggregate(&stat->m_misc); 609 610 m_all.set(normalizer, &all); 611 } 612 }; 613 614 /** Row fragment for memory statistics columns. */ 615 struct PFS_memory_stat_row 616 { 617 PFS_memory_stat m_stat; 618 619 /** Build a row from a memory buffer. */ setPFS_memory_stat_row620 inline void set(const PFS_memory_stat *stat) 621 { 622 m_stat= *stat; 623 } 624 625 /** Set a table field from the row. */ 626 void set_field(uint index, Field *f); 627 }; 628 629 struct PFS_variable_name_row 630 { 631 public: PFS_variable_name_rowPFS_variable_name_row632 PFS_variable_name_row() 633 { 634 m_str[0]= '\0'; 635 m_length= 0; 636 } 637 638 void make_row(const char* str, size_t length); 639 640 char m_str[NAME_CHAR_LEN+1]; 641 uint m_length; 642 }; 643 644 struct PFS_variable_value_row 645 { 646 public: 647 /** Set the row from a status variable. */ 648 void make_row(const Status_variable *var); 649 650 /** Set the row from a system variable. */ 651 void make_row(const System_variable *var); 652 653 /** Set a table field from the row. */ 654 void set_field(Field *f); 655 656 private: 657 void make_row(const CHARSET_INFO *cs, const char* str, size_t length); 658 659 char m_str[1024]; 660 uint m_length; 661 const CHARSET_INFO *m_charset; 662 }; 663 664 struct PFS_user_variable_value_row 665 { 666 public: PFS_user_variable_value_rowPFS_user_variable_value_row667 PFS_user_variable_value_row() 668 : m_value(NULL), m_value_length(0) 669 {} 670 PFS_user_variable_value_rowPFS_user_variable_value_row671 PFS_user_variable_value_row(const PFS_user_variable_value_row& rhs) 672 { 673 make_row(rhs.m_value, rhs.m_value_length); 674 } 675 ~PFS_user_variable_value_rowPFS_user_variable_value_row676 ~PFS_user_variable_value_row() 677 { 678 clear(); 679 } 680 681 void make_row(const char* val, size_t length); 682 get_valuePFS_user_variable_value_row683 const char *get_value() const 684 { return m_value; } 685 get_value_lengthPFS_user_variable_value_row686 size_t get_value_length() const 687 { return m_value_length; } 688 689 void clear(); 690 691 private: 692 char *m_value; 693 size_t m_value_length; 694 }; 695 696 /** @} */ 697 698 #endif 699 700