1 #ifndef STRUCTS_INCLUDED 2 #define STRUCTS_INCLUDED 3 4 /* Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved. 5 6 This program is free software; you can redistribute it and/or modify 7 it under the terms of the GNU General Public License, version 2.0, 8 as published by the Free Software Foundation. 9 10 This program is also distributed with certain software (including 11 but not limited to OpenSSL) that is licensed under separate terms, 12 as designated in a particular file or component or in included license 13 documentation. The authors of MySQL hereby grant you an additional 14 permission to link the program and your derivative works with the 15 separately licensed software that they have included with MySQL. 16 17 This program is distributed in the hope that it will be useful, 18 but WITHOUT ANY WARRANTY; without even the implied warranty of 19 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 20 GNU General Public License, version 2.0, for more details. 21 22 You should have received a copy of the GNU General Public License 23 along with this program; if not, write to the Free Software Foundation, 24 51 Franklin Street, Suite 500, Boston, MA 02110-1335 USA */ 25 26 27 28 /* The old structures from unireg */ 29 30 #include "sql_plugin.h" /* plugin_ref */ 31 #include "sql_const.h" /* MAX_REFLENGTH */ 32 #include "my_time.h" /* enum_mysql_timestamp_type */ 33 #include "thr_lock.h" /* thr_lock_type */ 34 #include "my_base.h" /* ha_rows, ha_key_alg */ 35 #include "mysql_com.h" 36 37 struct TABLE; 38 class Field; 39 40 class THD; 41 42 typedef struct st_date_time_format { 43 uchar positions[8]; 44 char time_separator; /* Separator between hour and minute */ 45 uint flag; /* For future */ 46 LEX_STRING format; 47 } DATE_TIME_FORMAT; 48 49 50 typedef struct st_keyfile_info { /* used with ha_info() */ 51 uchar ref[MAX_REFLENGTH]; /* Pointer to current row */ 52 uchar dupp_ref[MAX_REFLENGTH]; /* Pointer to dupp row */ 53 uint ref_length; /* Length of ref (1-8) */ 54 uint block_size; /* index block size */ 55 File filenr; /* (uniq) filenr for table */ 56 ha_rows records; /* Records i datafilen */ 57 ha_rows deleted; /* Deleted records */ 58 ulonglong data_file_length; /* Length off data file */ 59 ulonglong max_data_file_length; /* Length off data file */ 60 ulonglong index_file_length; 61 ulonglong max_index_file_length; 62 ulonglong delete_length; /* Free bytes */ 63 ulonglong auto_increment_value; 64 int errkey,sortkey; /* Last errorkey and sorted by */ 65 time_t create_time; /* When table was created */ 66 time_t check_time; 67 time_t update_time; 68 ulong mean_rec_length; /* physical reclength */ 69 } KEYFILE_INFO; 70 71 72 class KEY_PART_INFO { /* Info about a key part */ 73 public: 74 Field *field; 75 uint offset; /* offset in record (from 0) */ 76 uint null_offset; /* Offset to null_bit in record */ 77 /* Length of key part in bytes, excluding NULL flag and length bytes */ 78 uint16 length; 79 /* 80 Number of bytes required to store the keypart value. This may be 81 different from the "length" field as it also counts 82 - possible NULL-flag byte (see HA_KEY_NULL_LENGTH) 83 - possible HA_KEY_BLOB_LENGTH bytes needed to store actual value length. 84 */ 85 uint16 store_length; 86 uint16 key_type; 87 uint16 fieldnr; /* Fieldnum in UNIREG */ 88 uint16 key_part_flag; /* 0 or HA_REVERSE_SORT */ 89 uint8 type; 90 uint8 null_bit; /* Position to null_bit */ 91 void init_from_field(Field *fld); /** Fill data from given field */ 92 void init_flags(); /** Set key_part_flag from field */ 93 }; 94 95 96 typedef struct st_key { 97 /** Tot length of key */ 98 uint key_length; 99 /** dupp key and pack flags */ 100 ulong flags; 101 /** dupp key and pack flags for actual key parts */ 102 ulong actual_flags; 103 /** How many key_parts */ 104 uint user_defined_key_parts; 105 /** How many key_parts including hidden parts */ 106 uint actual_key_parts; 107 /** 108 Key parts allocated for primary key parts extension but 109 not used due to some reasons(no primary key, duplicated key parts) 110 */ 111 uint unused_key_parts; 112 /** Should normally be = key_parts */ 113 uint usable_key_parts; 114 uint block_size; 115 enum ha_key_alg algorithm; 116 /** 117 Note that parser is used when the table is opened for use, and 118 parser_name is used when the table is being created. 119 */ 120 union 121 { 122 /** Fulltext [pre]parser */ 123 plugin_ref parser; 124 /** Fulltext [pre]parser name */ 125 LEX_STRING *parser_name; 126 }; 127 KEY_PART_INFO *key_part; 128 /** Name of key */ 129 char *name; 130 /** 131 Array of AVG(#records with the same field value) for 1st ... Nth key part. 132 0 means 'not known'. 133 For temporary heap tables this member is NULL. 134 */ 135 ulong *rec_per_key; 136 union { 137 int bdb_return_if_eq; 138 } handler; 139 TABLE *table; 140 LEX_STRING comment; 141 } KEY; 142 143 144 struct st_join_table; 145 146 typedef struct st_reginfo { /* Extra info about reg */ 147 struct st_join_table *join_tab; /* Used by SELECT() */ 148 enum thr_lock_type lock_type; /* How database is used */ 149 bool not_exists_optimize; 150 /* 151 TRUE <=> range optimizer found that there is no rows satisfying 152 table conditions. 153 */ 154 bool impossible_range; 155 } REGINFO; 156 157 158 /* 159 Originally MySQL used MYSQL_TIME structure inside server only, but since 160 4.1 it's exported to user in the new client API. Define aliases for 161 new names to keep existing code simple. 162 */ 163 164 typedef enum enum_mysql_timestamp_type timestamp_type; 165 166 167 typedef struct { 168 ulong year,month,day,hour; 169 ulonglong minute,second,second_part; 170 bool neg; 171 } INTERVAL; 172 173 174 typedef struct st_known_date_time_format { 175 const char *format_name; 176 const char *date_format; 177 const char *datetime_format; 178 const char *time_format; 179 } KNOWN_DATE_TIME_FORMAT; 180 181 extern const char *show_comp_option_name[]; 182 183 typedef int *(*update_var)(THD *, struct st_mysql_show_var *); 184 185 typedef struct st_lex_user { 186 LEX_STRING user, host, password, plugin, auth; 187 bool uses_identified_by_clause; 188 bool uses_identified_with_clause; 189 bool uses_authentication_string_clause; 190 bool uses_identified_by_password_clause; 191 } LEX_USER; 192 193 /* 194 This structure specifies the maximum amount of resources which 195 can be consumed by each account. Zero value of a member means 196 there is no limit. 197 */ 198 typedef struct user_resources { 199 /* Maximum number of queries/statements per hour. */ 200 uint questions; 201 /* 202 Maximum number of updating statements per hour (which statements are 203 updating is defined by sql_command_flags array). 204 */ 205 uint updates; 206 /* Maximum number of connections established per hour. */ 207 uint conn_per_hour; 208 /* Maximum number of concurrent connections. */ 209 uint user_conn; 210 /* 211 Values of this enum and specified_limits member are used by the 212 parser to store which user limits were specified in GRANT statement. 213 */ 214 enum {QUERIES_PER_HOUR= 1, UPDATES_PER_HOUR= 2, CONNECTIONS_PER_HOUR= 4, 215 USER_CONNECTIONS= 8}; 216 uint specified_limits; 217 } USER_RESOURCES; 218 219 220 /* 221 This structure is used for counting resources consumed and for checking 222 them against specified user limits. 223 */ 224 typedef struct user_conn { 225 /* 226 Pointer to user+host key (pair separated by '\0') defining the entity 227 for which resources are counted (By default it is user account thus 228 priv_user/priv_host pair is used. If --old-style-user-limits option 229 is enabled, resources are counted for each user+host separately). 230 */ 231 char *user; 232 /* Pointer to host part of the key. */ 233 char *host; 234 /** 235 The moment of time when per hour counters were reset last time 236 (i.e. start of "hour" for conn_per_hour, updates, questions counters). 237 */ 238 ulonglong reset_utime; 239 /* Total length of the key. */ 240 uint len; 241 /* Current amount of concurrent connections for this account. */ 242 uint connections; 243 /* 244 Current number of connections per hour, number of updating statements 245 per hour and total number of statements per hour for this account. 246 */ 247 uint conn_per_hour, updates, questions; 248 /* Maximum amount of resources which account is allowed to consume. */ 249 USER_RESOURCES user_resources; 250 } USER_CONN; 251 252 typedef struct st_user_stats { 253 char user[MY_MAX(USERNAME_LENGTH, LIST_PROCESS_HOST_LEN) + 1]; 254 // Account name the user is mapped to when this is a user from mapped_user. 255 // Otherwise, the same value as user. 256 char priv_user[MY_MAX(USERNAME_LENGTH, LIST_PROCESS_HOST_LEN) + 1]; 257 uint total_connections; 258 uint total_ssl_connections; 259 uint concurrent_connections; 260 size_t user_len; 261 size_t priv_user_len; 262 time_t connected_time; // in seconds 263 double busy_time; // in seconds 264 double cpu_time; // in seconds 265 ulonglong bytes_received; 266 ulonglong bytes_sent; 267 ulonglong binlog_bytes_written; 268 ha_rows rows_fetched, rows_updated, rows_read; 269 ulonglong select_commands, update_commands, other_commands; 270 ulonglong commit_trans, rollback_trans; 271 ulonglong denied_connections, lost_connections; 272 ulonglong access_denied_errors; 273 ulonglong empty_queries; 274 } USER_STATS; 275 276 typedef struct st_thread_stats { 277 my_thread_id id; 278 uint total_connections; 279 uint total_ssl_connections; 280 uint concurrent_connections; 281 time_t connected_time; // in seconds 282 double busy_time; // in seconds 283 double cpu_time; // in seconds 284 ulonglong bytes_received; 285 ulonglong bytes_sent; 286 ulonglong binlog_bytes_written; 287 ha_rows rows_fetched, rows_updated, rows_read; 288 ulonglong select_commands, update_commands, other_commands; 289 ulonglong commit_trans, rollback_trans; 290 ulonglong denied_connections, lost_connections; 291 ulonglong access_denied_errors; 292 ulonglong empty_queries; 293 } THREAD_STATS; 294 295 typedef struct st_table_stats { 296 char table[NAME_LEN * 2 + 2]; // [db] + '.' + [table] + '\0' 297 size_t table_len; 298 ulonglong rows_read, rows_changed; 299 ulonglong rows_changed_x_indexes; 300 /* Stores enum db_type, but forward declarations cannot be done */ 301 int engine_type; 302 } TABLE_STATS; 303 304 typedef struct st_index_stats { 305 char index[NAME_LEN * 3 + 3]; // [db] + '.' + [table] + '.' + [index] + '\0' 306 size_t index_len; 307 ulonglong rows_read; 308 } INDEX_STATS; 309 310 /* Bits in form->update */ 311 #define REG_MAKE_DUPP 1 /* Make a copy of record when read */ 312 #define REG_NEW_RECORD 2 /* Write a new record if not found */ 313 #define REG_UPDATE 4 /* Uppdate record */ 314 #define REG_DELETE 8 /* Delete found record */ 315 #define REG_PROG 16 /* User is updating database */ 316 #define REG_CLEAR_AFTER_WRITE 32 317 #define REG_MAY_BE_UPDATED 64 318 #define REG_AUTO_UPDATE 64 /* Used in D-forms for scroll-tables */ 319 #define REG_OVERWRITE 128 320 #define REG_SKIP_DUP 256 321 322 /** 323 Flags for TABLE::status (maximum 8 bits). Do NOT add new ones. 324 @todo: GARBAGE and NOT_FOUND could be unified. UPDATED and DELETED could be 325 changed to "bool current_row_has_already_been_modified" in the 326 multi_update/delete objects (one such bool per to-be-modified table). 327 @todo aim at removing the status. There should be more local ways. 328 */ 329 #define STATUS_GARBAGE 1 330 /** 331 Means we were searching for a row and didn't find it. This is used by 332 storage engines (@see handler::index_read_map()) and the Server layer. 333 */ 334 #define STATUS_NOT_FOUND 2 335 /// Reserved for use by multi-table update. Means the row has been updated. 336 #define STATUS_UPDATED 16 337 /** 338 Means that table->null_row is set. This is an artificial NULL-filled row 339 (one example: in outer join, if no match has been found in inner table). 340 */ 341 #define STATUS_NULL_ROW 32 342 /// Reserved for use by multi-table delete. Means the row has been deleted. 343 #define STATUS_DELETED 64 344 345 /* 346 Such interval is "discrete": it is the set of 347 { auto_inc_interval_min + k * increment, 348 0 <= k <= (auto_inc_interval_values-1) } 349 Where "increment" is maintained separately by the user of this class (and is 350 currently only thd->variables.auto_increment_increment). 351 It mustn't derive from Sql_alloc, because SET INSERT_ID needs to 352 allocate memory which must stay allocated for use by the next statement. 353 */ 354 class Discrete_interval { 355 private: 356 ulonglong interval_min; 357 ulonglong interval_values; 358 ulonglong interval_max; // excluded bound. Redundant. 359 public: 360 Discrete_interval *next; // used when linked into Discrete_intervals_list 361 362 /// Determine if the given value is within the interval in_range(const ulonglong value)363 bool in_range(const ulonglong value) const 364 { 365 return ((value >= interval_min) && (value < interval_max)); 366 } 367 replace(ulonglong start,ulonglong val,ulonglong incr)368 void replace(ulonglong start, ulonglong val, ulonglong incr) 369 { 370 interval_min= start; 371 interval_values= val; 372 interval_max= (val == ULONGLONG_MAX) ? val : start + val * incr; 373 } Discrete_interval(ulonglong start,ulonglong val,ulonglong incr)374 Discrete_interval(ulonglong start, ulonglong val, ulonglong incr) : 375 next(NULL) { replace(start, val, incr); }; Discrete_interval()376 Discrete_interval() : next(NULL) { replace(0, 0, 0); }; minimum()377 ulonglong minimum() const { return interval_min; }; values()378 ulonglong values() const { return interval_values; }; maximum()379 ulonglong maximum() const { return interval_max; }; 380 /* 381 If appending [3,5] to [1,2], we merge both in [1,5] (they should have the 382 same increment for that, user of the class has to ensure that). That is 383 just a space optimization. Returns 0 if merge succeeded. 384 */ merge_if_contiguous(ulonglong start,ulonglong val,ulonglong incr)385 bool merge_if_contiguous(ulonglong start, ulonglong val, ulonglong incr) 386 { 387 if (interval_max == start) 388 { 389 if (val == ULONGLONG_MAX) 390 { 391 interval_values= interval_max= val; 392 } 393 else 394 { 395 interval_values+= val; 396 interval_max= start + val * incr; 397 } 398 return 0; 399 } 400 return 1; 401 }; 402 }; 403 404 /// List of Discrete_interval objects 405 class Discrete_intervals_list { 406 407 /** 408 Discrete_intervals_list objects are used to remember the 409 intervals of autoincrement values that have been used by the 410 current INSERT statement, so that the values can be written to the 411 binary log. However, the binary log can currently only store the 412 beginning of the first interval (because WL#3404 is not yet 413 implemented). Hence, it is currently not necessary to store 414 anything else than the first interval, in the list. When WL#3404 is 415 implemented, we should change the '# define' below. 416 */ 417 #define DISCRETE_INTERVAL_LIST_HAS_MAX_ONE_ELEMENT 1 418 419 private: 420 /** 421 To avoid heap allocation in the common case when there is only one 422 interval in the list, we store the first interval here. 423 */ 424 Discrete_interval first_interval; 425 Discrete_interval *head; 426 Discrete_interval *tail; 427 /** 428 When many intervals are provided at the beginning of the execution of a 429 statement (in a replication slave or SET INSERT_ID), "current" points to 430 the interval being consumed by the thread now (so "current" goes from 431 "head" to "tail" then to NULL). 432 */ 433 Discrete_interval *current; 434 uint elements; ///< number of elements 435 void operator=(Discrete_intervals_list &); // prevent use of this append(Discrete_interval * new_interval)436 bool append(Discrete_interval *new_interval) 437 { 438 if (unlikely(new_interval == NULL)) 439 return true; 440 DBUG_PRINT("info",("adding new auto_increment interval")); 441 if (head == NULL) 442 head= current= new_interval; 443 else 444 tail->next= new_interval; 445 tail= new_interval; 446 elements++; 447 return false; 448 } copy_shallow(const Discrete_intervals_list * other)449 void copy_shallow(const Discrete_intervals_list *other) 450 { 451 const Discrete_interval *o_first_interval= &other->first_interval; 452 first_interval= other->first_interval; 453 head= other->head == o_first_interval ? &first_interval : other->head; 454 tail= other->tail == o_first_interval ? &first_interval : other->tail; 455 current= 456 other->current == o_first_interval ? &first_interval : other->current; 457 elements= other->elements; 458 } Discrete_intervals_list(const Discrete_intervals_list & other)459 Discrete_intervals_list(const Discrete_intervals_list &other) 460 { copy_shallow(&other); } 461 462 public: Discrete_intervals_list()463 Discrete_intervals_list() 464 : head(NULL), tail(NULL), current(NULL), elements(0) {} empty()465 void empty() 466 { 467 if (head) 468 { 469 // first element, not on heap, should not be delete-d; start with next: 470 for (Discrete_interval *i= head->next; i;) 471 { 472 #ifdef DISCRETE_INTERVAL_LIST_HAS_MAX_ONE_ELEMENT 473 DBUG_ASSERT(0); 474 #endif 475 Discrete_interval *next= i->next; 476 delete i; 477 i= next; 478 } 479 } 480 head= tail= current= NULL; 481 elements= 0; 482 } swap(Discrete_intervals_list * other)483 void swap(Discrete_intervals_list *other) 484 { 485 const Discrete_intervals_list tmp(*other); 486 other->copy_shallow(this); 487 copy_shallow(&tmp); 488 } get_next()489 const Discrete_interval *get_next() 490 { 491 const Discrete_interval *tmp= current; 492 if (current != NULL) 493 current= current->next; 494 return tmp; 495 } ~Discrete_intervals_list()496 ~Discrete_intervals_list() { empty(); }; 497 /** 498 Appends an interval to the list. 499 500 @param start start of interval 501 @val how many values it contains 502 @param incr what increment between each value 503 @retval true error 504 @retval false success 505 */ append(ulonglong start,ulonglong val,ulonglong incr)506 bool append(ulonglong start, ulonglong val, ulonglong incr) 507 { 508 // If there are no intervals, add one. 509 if (head == NULL) 510 { 511 first_interval.replace(start, val, incr); 512 return append(&first_interval); 513 } 514 // If this interval can be merged with previous, do that. 515 if (tail->merge_if_contiguous(start, val, incr) == 0) 516 return false; 517 // If this interval cannot be merged, append it. 518 #ifdef DISCRETE_INTERVAL_LIST_HAS_MAX_ONE_ELEMENT 519 /* 520 We cannot create yet another interval as we already contain one. This 521 situation can happen. Assume innodb_autoinc_lock_mode>=1 and 522 CREATE TABLE T(A INT AUTO_INCREMENT PRIMARY KEY) ENGINE=INNODB; 523 INSERT INTO T VALUES (NULL),(NULL),(1025),(NULL); 524 Then InnoDB will reserve [1,4] (because of 4 rows) then 525 [1026,1026]. Only the first interval is important for 526 statement-based binary logging as it tells the starting point. So we 527 ignore the second interval: 528 */ 529 return false; 530 #else 531 return append(new Discrete_interval(start, val, incr)); 532 #endif 533 } minimum()534 ulonglong minimum() const { return (head ? head->minimum() : 0); }; maximum()535 ulonglong maximum() const { return (head ? tail->maximum() : 0); }; nb_elements()536 uint nb_elements() const { return elements; } 537 }; 538 539 #endif /* STRUCTS_INCLUDED */ 540