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