| 1 | #ifndef STRUCTS_INCLUDED | 
| 2 | #define STRUCTS_INCLUDED | 
| 3 |  | 
| 4 | /* Copyright (c) 2000, 2010, Oracle and/or its affiliates. All rights reserved. | 
| 5 |    Copyright (c) 2017, MariaDB Corporation. | 
| 6 |  | 
| 7 |    This program is free software; you can redistribute it and/or modify | 
| 8 |    it under the terms of the GNU General Public License as published by | 
| 9 |    the Free Software Foundation; version 2 of the License. | 
| 10 |  | 
| 11 |    This program is distributed in the hope that it will be useful, | 
| 12 |    but WITHOUT ANY WARRANTY; without even the implied warranty of | 
| 13 |    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the | 
| 14 |    GNU General Public License for more details. | 
| 15 |  | 
| 16 |    You should have received a copy of the GNU General Public License | 
| 17 |    along with this program; if not, write to the Free Software | 
| 18 |    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301  USA */ | 
| 19 |  | 
| 20 |  | 
| 21 |  | 
| 22 | /* The old structures from unireg */ | 
| 23 |  | 
| 24 | #include "sql_plugin.h"                         /* plugin_ref */ | 
| 25 | #include "sql_const.h"                          /* MAX_REFLENGTH */ | 
| 26 | #include "my_time.h"                   /* enum_mysql_timestamp_type */ | 
| 27 | #include "thr_lock.h"                  /* thr_lock_type */ | 
| 28 | #include "my_base.h"                   /* ha_rows, ha_key_alg */ | 
| 29 | #include <mysql_com.h>                  /* USERNAME_LENGTH */ | 
| 30 |  | 
| 31 | struct TABLE; | 
| 32 | class Type_handler; | 
| 33 | class Field; | 
| 34 | class Index_statistics; | 
| 35 |  | 
| 36 | class THD; | 
| 37 |  | 
| 38 | typedef struct st_date_time_format { | 
| 39 |   uchar positions[8]; | 
| 40 |   char  time_separator;			/* Separator between hour and minute */ | 
| 41 |   uint flag;				/* For future */ | 
| 42 |   LEX_CSTRING format; | 
| 43 | } DATE_TIME_FORMAT; | 
| 44 |  | 
| 45 |  | 
| 46 | typedef struct st_keyfile_info {	/* used with ha_info() */ | 
| 47 |   uchar ref[MAX_REFLENGTH];		/* Pointer to current row */ | 
| 48 |   uchar dupp_ref[MAX_REFLENGTH];	/* Pointer to dupp row */ | 
| 49 |   uint ref_length;			/* Length of ref (1-8) */ | 
| 50 |   uint block_size;			/* index block size */ | 
| 51 |   File filenr;				/* (uniq) filenr for table */ | 
| 52 |   ha_rows records;			/* Records i datafilen */ | 
| 53 |   ha_rows deleted;			/* Deleted records */ | 
| 54 |   ulonglong data_file_length;		/* Length off data file */ | 
| 55 |   ulonglong max_data_file_length;	/* Length off data file */ | 
| 56 |   ulonglong index_file_length; | 
| 57 |   ulonglong max_index_file_length; | 
| 58 |   ulonglong delete_length;		/* Free bytes */ | 
| 59 |   ulonglong auto_increment_value; | 
| 60 |   int errkey,sortkey;			/* Last errorkey and sorted by */ | 
| 61 |   time_t create_time;			/* When table was created */ | 
| 62 |   time_t check_time; | 
| 63 |   time_t update_time; | 
| 64 |   ulong mean_rec_length;		/* physical reclength */ | 
| 65 | } KEYFILE_INFO; | 
| 66 |  | 
| 67 |  | 
| 68 | typedef struct st_key_part_info {	/* Info about a key part */ | 
| 69 |   Field *field;                         /* the Field object for the indexed | 
| 70 |                                            prefix of the original table Field. | 
| 71 |                                            NOT necessarily the original Field */ | 
| 72 |   uint  offset;                         /* Offset in record (from 0) */ | 
| 73 |   uint  null_offset;                    /* Offset to null_bit in record */ | 
| 74 |   /* Length of key part in bytes, excluding NULL flag and length bytes */ | 
| 75 |   uint16 length; | 
| 76 |   /*  | 
| 77 |     Number of bytes required to store the keypart value. This may be | 
| 78 |     different from the "length" field as it also counts | 
| 79 |      - possible NULL-flag byte (see HA_KEY_NULL_LENGTH) | 
| 80 |      - possible HA_KEY_BLOB_LENGTH bytes needed to store actual value length. | 
| 81 |   */ | 
| 82 |   uint16 store_length; | 
| 83 |   uint16 key_type; | 
| 84 |   uint16 fieldnr;                       /* Fieldnr begins counting from 1 */ | 
| 85 |   uint16 key_part_flag;                 /* 0 or HA_REVERSE_SORT */ | 
| 86 |   uint8 type; | 
| 87 |   uint8 null_bit;			/* Position to null_bit */ | 
| 88 | } KEY_PART_INFO ; | 
| 89 |  | 
| 90 | class engine_option_value; | 
| 91 | struct ha_index_option_struct; | 
| 92 |  | 
| 93 | typedef struct st_key { | 
| 94 |   uint	key_length;			/* Tot length of key */ | 
| 95 |   ulong flags;                          /* dupp key and pack flags */ | 
| 96 |   uint	user_defined_key_parts;	   /* How many key_parts */ | 
| 97 |   uint	usable_key_parts; /* Should normally be = user_defined_key_parts */ | 
| 98 |   uint ext_key_parts;              /* Number of key parts in extended key */ | 
| 99 |   ulong ext_key_flags;             /* Flags for extended key              */ | 
| 100 |   /* | 
| 101 |     Parts of primary key that are in the extension of this index.  | 
| 102 |  | 
| 103 |     Example: if this structure describes idx1, which is defined as  | 
| 104 |       INDEX idx1 (pk2, col2) | 
| 105 |     and pk is defined as: | 
| 106 |       PRIMARY KEY (pk1, pk2) | 
| 107 |     then  | 
| 108 |       pk1 is in the extension idx1, ext_key_part_map.is_set(0) == true | 
| 109 |       pk2 is explicitly present in idx1, it is not in the extension, so | 
| 110 |       ext_key_part_map.is_set(1) == false | 
| 111 |   */ | 
| 112 |   LEX_CSTRING name; | 
| 113 |   key_part_map ext_key_part_map; | 
| 114 |   uint  block_size; | 
| 115 |   enum  ha_key_alg algorithm; | 
| 116 |   /*  | 
| 117 |     The flag is on if statistical data for the index prefixes | 
| 118 |     has to be taken from the system statistical tables. | 
| 119 |   */ | 
| 120 |   bool is_statistics_from_stat_tables; | 
| 121 |   /* | 
| 122 |     Note that parser is used when the table is opened for use, and | 
| 123 |     parser_name is used when the table is being created. | 
| 124 |   */ | 
| 125 |   union | 
| 126 |   { | 
| 127 |     plugin_ref parser;                  /* Fulltext [pre]parser */ | 
| 128 |     LEX_CSTRING *parser_name;           /* Fulltext [pre]parser name */ | 
| 129 |   }; | 
| 130 |   KEY_PART_INFO *key_part; | 
| 131 |   /* Unique name for cache;  db + \0 + table_name + \0 + key_name + \0 */ | 
| 132 |   uchar *cache_name; | 
| 133 |   /* | 
| 134 |     Array of AVG(#records with the same field value) for 1st ... Nth key part. | 
| 135 |     0 means 'not known'. | 
| 136 |     For temporary heap tables this member is NULL. | 
| 137 |   */ | 
| 138 |   ulong *rec_per_key; | 
| 139 |  | 
| 140 |   /* | 
| 141 |     This structure is used for statistical data on the index | 
| 142 |     that has been read from the statistical table index_stat | 
| 143 |   */  | 
| 144 |   Index_statistics *read_stats; | 
| 145 |   /* | 
| 146 |     This structure is used for statistical data on the index that | 
| 147 |     is collected by the function collect_statistics_for_table | 
| 148 |   */ | 
| 149 |   Index_statistics *collected_stats; | 
| 150 |   | 
| 151 |   union { | 
| 152 |     int  bdb_return_if_eq; | 
| 153 |   } handler; | 
| 154 |   TABLE *table; | 
| 155 |   LEX_CSTRING ; | 
| 156 |   /** reference to the list of options or NULL */ | 
| 157 |   engine_option_value *option_list; | 
| 158 |   ha_index_option_struct *option_struct;                  /* structure with parsed options */ | 
| 159 |  | 
| 160 |   double actual_rec_per_key(uint i); | 
| 161 |  | 
| 162 | } KEY; | 
| 163 |  | 
| 164 |  | 
| 165 | struct st_join_table; | 
| 166 |  | 
| 167 | typedef struct st_reginfo {		/* Extra info about reg */ | 
| 168 |   struct st_join_table *join_tab;	/* Used by SELECT() */ | 
| 169 |   enum thr_lock_type lock_type;		/* How database is used */ | 
| 170 |   bool not_exists_optimize; | 
| 171 |   /* | 
| 172 |     TRUE <=> range optimizer found that there is no rows satisfying | 
| 173 |     table conditions. | 
| 174 |   */ | 
| 175 |   bool impossible_range; | 
| 176 | } REGINFO; | 
| 177 |  | 
| 178 |  | 
| 179 | /* | 
| 180 |   Originally MySQL used MYSQL_TIME structure inside server only, but since | 
| 181 |   4.1 it's exported to user in the new client API. Define aliases for | 
| 182 |   new names to keep existing code simple. | 
| 183 | */ | 
| 184 |  | 
| 185 | typedef enum enum_mysql_timestamp_type timestamp_type; | 
| 186 |  | 
| 187 |  | 
| 188 | typedef struct { | 
| 189 |   ulong year,month,day,hour; | 
| 190 |   ulonglong minute,second,second_part; | 
| 191 |   bool neg; | 
| 192 | } INTERVAL; | 
| 193 |  | 
| 194 |  | 
| 195 | typedef struct st_known_date_time_format { | 
| 196 |   const char *format_name; | 
| 197 |   const char *date_format; | 
| 198 |   const char *datetime_format; | 
| 199 |   const char *time_format; | 
| 200 | } KNOWN_DATE_TIME_FORMAT; | 
| 201 |  | 
| 202 | extern const char *show_comp_option_name[]; | 
| 203 |  | 
| 204 | typedef int *(*update_var)(THD *, struct st_mysql_show_var *); | 
| 205 |  | 
| 206 |  | 
| 207 | struct AUTHID | 
| 208 | { | 
| 209 |   LEX_CSTRING user, host; | 
| 210 |   void init() { memset(this, 0, sizeof(*this)); } | 
| 211 |   void copy(MEM_ROOT *root, const LEX_CSTRING *usr, const LEX_CSTRING *host); | 
| 212 |   bool is_role() const { return user.str[0] && !host.str[0]; } | 
| 213 |   void set_lex_string(LEX_CSTRING *l, char *buf) | 
| 214 |   { | 
| 215 |     if (is_role()) | 
| 216 |       *l= user; | 
| 217 |     else | 
| 218 |     { | 
| 219 |       l->str= buf; | 
| 220 |       l->length= strxmov(buf, user.str, "@" , host.str, NullS) - buf; | 
| 221 |     } | 
| 222 |   } | 
| 223 |   void parse(const char *str, size_t length); | 
| 224 |   bool read_from_mysql_proc_row(THD *thd, TABLE *table); | 
| 225 | }; | 
| 226 |  | 
| 227 |  | 
| 228 | struct LEX_USER: public AUTHID | 
| 229 | { | 
| 230 |   LEX_CSTRING plugin, auth; | 
| 231 |   LEX_CSTRING pwtext, pwhash; | 
| 232 |   void reset_auth() | 
| 233 |   { | 
| 234 |     pwtext.length= pwhash.length= plugin.length= auth.length= 0; | 
| 235 |     pwtext.str= pwhash.str= 0; | 
| 236 |     plugin.str= auth.str= "" ; | 
| 237 |   } | 
| 238 | }; | 
| 239 |  | 
| 240 | /* | 
| 241 |   This structure specifies the maximum amount of resources which | 
| 242 |   can be consumed by each account. Zero value of a member means | 
| 243 |   there is no limit. | 
| 244 | */ | 
| 245 | typedef struct user_resources { | 
| 246 |   /* Maximum number of queries/statements per hour. */ | 
| 247 |   uint questions; | 
| 248 |   /* | 
| 249 |      Maximum number of updating statements per hour (which statements are | 
| 250 |      updating is defined by sql_command_flags array). | 
| 251 |   */ | 
| 252 |   uint updates; | 
| 253 |   /* Maximum number of connections established per hour. */ | 
| 254 |   uint conn_per_hour; | 
| 255 |   /* | 
| 256 |     Maximum number of concurrent connections. If -1 then no new | 
| 257 |     connections allowed | 
| 258 |   */ | 
| 259 |   int user_conn; | 
| 260 |   /* Max query timeout */ | 
| 261 |   double max_statement_time; | 
| 262 |  | 
| 263 |   /* | 
| 264 |      Values of this enum and specified_limits member are used by the | 
| 265 |      parser to store which user limits were specified in GRANT statement. | 
| 266 |   */ | 
| 267 |   enum {QUERIES_PER_HOUR= 1, UPDATES_PER_HOUR= 2, CONNECTIONS_PER_HOUR= 4, | 
| 268 |         USER_CONNECTIONS= 8, MAX_STATEMENT_TIME= 16}; | 
| 269 |   uint specified_limits; | 
| 270 | } USER_RESOURCES; | 
| 271 |  | 
| 272 |  | 
| 273 | /* | 
| 274 |   This structure is used for counting resources consumed and for checking | 
| 275 |   them against specified user limits. | 
| 276 | */ | 
| 277 | typedef struct  user_conn { | 
| 278 |   /* | 
| 279 |      Pointer to user+host key (pair separated by '\0') defining the entity | 
| 280 |      for which resources are counted (By default it is user account thus | 
| 281 |      priv_user/priv_host pair is used. If --old-style-user-limits option | 
| 282 |      is enabled, resources are counted for each user+host separately). | 
| 283 |   */ | 
| 284 |   char *user; | 
| 285 |   /* Pointer to host part of the key. */ | 
| 286 |   char *host; | 
| 287 |   /** | 
| 288 |      The moment of time when per hour counters were reset last time | 
| 289 |      (i.e. start of "hour" for conn_per_hour, updates, questions counters). | 
| 290 |   */ | 
| 291 |   ulonglong reset_utime; | 
| 292 |   /* Total length of the key. */ | 
| 293 |   uint len; | 
| 294 |   /* Current amount of concurrent connections for this account. */ | 
| 295 |   int connections; | 
| 296 |   /* | 
| 297 |      Current number of connections per hour, number of updating statements | 
| 298 |      per hour and total number of statements per hour for this account. | 
| 299 |   */ | 
| 300 |   uint conn_per_hour, updates, questions; | 
| 301 |   /* Maximum amount of resources which account is allowed to consume. */ | 
| 302 |   USER_RESOURCES user_resources; | 
| 303 | } USER_CONN; | 
| 304 |  | 
| 305 | typedef struct st_user_stats | 
| 306 | { | 
| 307 |   char user[MY_MAX(USERNAME_LENGTH, LIST_PROCESS_HOST_LEN) + 1]; | 
| 308 |   // Account name the user is mapped to when this is a user from mapped_user. | 
| 309 |   // Otherwise, the same value as user. | 
| 310 |   char priv_user[MY_MAX(USERNAME_LENGTH, LIST_PROCESS_HOST_LEN) + 1]; | 
| 311 |   uint user_name_length; | 
| 312 |   uint total_connections; | 
| 313 |   uint total_ssl_connections; | 
| 314 |   uint concurrent_connections; | 
| 315 |   time_t connected_time;  // in seconds | 
| 316 |   ha_rows rows_read, rows_sent; | 
| 317 |   ha_rows rows_updated, rows_deleted, rows_inserted; | 
| 318 |   ulonglong bytes_received; | 
| 319 |   ulonglong bytes_sent; | 
| 320 |   ulonglong binlog_bytes_written; | 
| 321 |   ulonglong select_commands, update_commands, other_commands; | 
| 322 |   ulonglong commit_trans, rollback_trans; | 
| 323 |   ulonglong denied_connections, lost_connections, max_statement_time_exceeded; | 
| 324 |   ulonglong access_denied_errors; | 
| 325 |   ulonglong empty_queries; | 
| 326 |   double busy_time;       // in seconds | 
| 327 |   double cpu_time;        // in seconds | 
| 328 | } USER_STATS; | 
| 329 |  | 
| 330 | typedef struct st_table_stats | 
| 331 | { | 
| 332 |   char table[NAME_LEN * 2 + 2];  // [db] + '\0' + [table] + '\0' | 
| 333 |   size_t table_name_length; | 
| 334 |   ulonglong rows_read, rows_changed; | 
| 335 |   ulonglong rows_changed_x_indexes; | 
| 336 |   /* Stores enum db_type, but forward declarations cannot be done */ | 
| 337 |   int engine_type; | 
| 338 | } TABLE_STATS; | 
| 339 |  | 
| 340 | typedef struct st_index_stats | 
| 341 | { | 
| 342 |   // [db] + '\0' + [table] + '\0' + [index] + '\0' | 
| 343 |   char index[NAME_LEN * 3 + 3]; | 
| 344 |   size_t index_name_length;                       /* Length of 'index' */ | 
| 345 |   ulonglong rows_read; | 
| 346 | } INDEX_STATS; | 
| 347 |  | 
| 348 |  | 
| 349 | 	/* Bits in form->update */ | 
| 350 | #define REG_MAKE_DUPP		1U	/* Make a copy of record when read */ | 
| 351 | #define REG_NEW_RECORD		2U	/* Write a new record if not found */ | 
| 352 | #define REG_UPDATE		4U	/* Uppdate record */ | 
| 353 | #define REG_DELETE		8U	/* Delete found record */ | 
| 354 | #define REG_PROG		16U	/* User is updating database */ | 
| 355 | #define REG_CLEAR_AFTER_WRITE	32U | 
| 356 | #define REG_MAY_BE_UPDATED	64U | 
| 357 | #define REG_AUTO_UPDATE		64U	/* Used in D-forms for scroll-tables */ | 
| 358 | #define REG_OVERWRITE		128U | 
| 359 | #define REG_SKIP_DUP		256U | 
| 360 |  | 
| 361 | 	/* Bits in form->status */ | 
| 362 | #define STATUS_NO_RECORD	(1U+2U)	/* Record isn't usable */ | 
| 363 | #define STATUS_GARBAGE		1U | 
| 364 | #define STATUS_NOT_FOUND	2U	/* No record in database when needed */ | 
| 365 | #define STATUS_NO_PARENT	4U	/* Parent record wasn't found */ | 
| 366 | #define STATUS_NOT_READ		8U	/* Record isn't read */ | 
| 367 | #define STATUS_UPDATED		16U	/* Record is updated by formula */ | 
| 368 | #define STATUS_NULL_ROW		32U	/* table->null_row is set */ | 
| 369 | #define STATUS_DELETED		64U | 
| 370 |  | 
| 371 | /* | 
| 372 |   Such interval is "discrete": it is the set of | 
| 373 |   { auto_inc_interval_min + k * increment, | 
| 374 |     0 <= k <= (auto_inc_interval_values-1) } | 
| 375 |   Where "increment" is maintained separately by the user of this class (and is | 
| 376 |   currently only thd->variables.auto_increment_increment). | 
| 377 |   It mustn't derive from Sql_alloc, because SET INSERT_ID needs to | 
| 378 |   allocate memory which must stay allocated for use by the next statement. | 
| 379 | */ | 
| 380 | class Discrete_interval { | 
| 381 | private: | 
| 382 |   ulonglong interval_min; | 
| 383 |   ulonglong interval_values; | 
| 384 |   ulonglong  interval_max;    // excluded bound. Redundant. | 
| 385 | public: | 
| 386 |   Discrete_interval *next;    // used when linked into Discrete_intervals_list | 
| 387 |   void replace(ulonglong start, ulonglong val, ulonglong incr) | 
| 388 |   { | 
| 389 |     interval_min=    start; | 
| 390 |     interval_values= val; | 
| 391 |     interval_max=    (val == ULONGLONG_MAX) ? val : start + val * incr; | 
| 392 |   } | 
| 393 |   Discrete_interval(ulonglong start, ulonglong val, ulonglong incr) : | 
| 394 |     next(NULL) { replace(start, val, incr); }; | 
| 395 |   Discrete_interval() : next(NULL) { replace(0, 0, 0); }; | 
| 396 |   ulonglong minimum() const { return interval_min;    }; | 
| 397 |   ulonglong values()  const { return interval_values; }; | 
| 398 |   ulonglong maximum() const { return interval_max;    }; | 
| 399 |   /* | 
| 400 |     If appending [3,5] to [1,2], we merge both in [1,5] (they should have the | 
| 401 |     same increment for that, user of the class has to ensure that). That is | 
| 402 |     just a space optimization. Returns 0 if merge succeeded. | 
| 403 |   */ | 
| 404 |   bool merge_if_contiguous(ulonglong start, ulonglong val, ulonglong incr) | 
| 405 |   { | 
| 406 |     if (interval_max == start) | 
| 407 |     { | 
| 408 |       if (val == ULONGLONG_MAX) | 
| 409 |       { | 
| 410 |         interval_values=   interval_max= val; | 
| 411 |       } | 
| 412 |       else | 
| 413 |       { | 
| 414 |         interval_values+=  val; | 
| 415 |         interval_max=      start + val * incr; | 
| 416 |       } | 
| 417 |       return 0; | 
| 418 |     } | 
| 419 |     return 1; | 
| 420 |   }; | 
| 421 | }; | 
| 422 |  | 
| 423 | /* List of Discrete_interval objects */ | 
| 424 | class Discrete_intervals_list { | 
| 425 | private: | 
| 426 |   Discrete_interval        *head; | 
| 427 |   Discrete_interval        *tail; | 
| 428 |   /* | 
| 429 |     When many intervals are provided at the beginning of the execution of a | 
| 430 |     statement (in a replication slave or SET INSERT_ID), "current" points to | 
| 431 |     the interval being consumed by the thread now (so "current" goes from | 
| 432 |     "head" to "tail" then to NULL). | 
| 433 |   */ | 
| 434 |   Discrete_interval        *current; | 
| 435 |   uint                  elements; // number of elements | 
| 436 |   void set_members(Discrete_interval *h, Discrete_interval *t, | 
| 437 |                    Discrete_interval *c, uint el) | 
| 438 |   {   | 
| 439 |     head= h; | 
| 440 |     tail= t; | 
| 441 |     current= c; | 
| 442 |     elements= el; | 
| 443 |   } | 
| 444 |   void operator=(Discrete_intervals_list &);  /* prevent use of these */ | 
| 445 |   Discrete_intervals_list(const Discrete_intervals_list &); | 
| 446 |  | 
| 447 | public: | 
| 448 |   Discrete_intervals_list() : head(NULL), current(NULL), elements(0) {}; | 
| 449 |   void empty_no_free() | 
| 450 |   { | 
| 451 |     set_members(NULL, NULL, NULL, 0); | 
| 452 |   } | 
| 453 |   void empty() | 
| 454 |   { | 
| 455 |     for (Discrete_interval *i= head; i;) | 
| 456 |     { | 
| 457 |       Discrete_interval *next= i->next; | 
| 458 |       delete i; | 
| 459 |       i= next; | 
| 460 |     } | 
| 461 |     empty_no_free(); | 
| 462 |   } | 
| 463 |   void copy_shallow(const Discrete_intervals_list * dli) | 
| 464 |   { | 
| 465 |     head= dli->get_head(); | 
| 466 |     tail= dli->get_tail(); | 
| 467 |     current= dli->get_current(); | 
| 468 |     elements= dli->nb_elements(); | 
| 469 |   } | 
| 470 |   void swap (Discrete_intervals_list * dli) | 
| 471 |   { | 
| 472 |     Discrete_interval *h, *t, *c; | 
| 473 |     uint el; | 
| 474 |     h= dli->get_head(); | 
| 475 |     t= dli->get_tail(); | 
| 476 |     c= dli->get_current(); | 
| 477 |     el= dli->nb_elements(); | 
| 478 |     dli->copy_shallow(this); | 
| 479 |     set_members(h, t, c, el); | 
| 480 |   } | 
| 481 |   const Discrete_interval* get_next() | 
| 482 |   { | 
| 483 |     Discrete_interval *tmp= current; | 
| 484 |     if (current != NULL) | 
| 485 |       current= current->next; | 
| 486 |     return tmp; | 
| 487 |   } | 
| 488 |   ~Discrete_intervals_list() { empty(); }; | 
| 489 |   bool append(ulonglong start, ulonglong val, ulonglong incr); | 
| 490 |   bool append(Discrete_interval *interval); | 
| 491 |   ulonglong minimum()     const { return (head ? head->minimum() : 0); }; | 
| 492 |   ulonglong maximum()     const { return (head ? tail->maximum() : 0); }; | 
| 493 |   uint      nb_elements() const { return elements; } | 
| 494 |   Discrete_interval* get_head() const { return head; }; | 
| 495 |   Discrete_interval* get_tail() const { return tail; }; | 
| 496 |   Discrete_interval* get_current() const { return current; }; | 
| 497 | }; | 
| 498 |  | 
| 499 |  | 
| 500 | /* | 
| 501 |   DDL options: | 
| 502 |   - CREATE IF NOT EXISTS | 
| 503 |   - DROP IF EXISTS | 
| 504 |   - CREATE LIKE | 
| 505 |   - REPLACE | 
| 506 | */ | 
| 507 | struct DDL_options_st | 
| 508 | { | 
| 509 | public: | 
| 510 |   enum Options | 
| 511 |   { | 
| 512 |     OPT_NONE= 0, | 
| 513 |     OPT_IF_NOT_EXISTS= 2,              // CREATE TABLE IF NOT EXISTS | 
| 514 |     OPT_LIKE= 4,                       // CREATE TABLE LIKE | 
| 515 |     OPT_OR_REPLACE= 16,                // CREATE OR REPLACE TABLE | 
| 516 |     OPT_OR_REPLACE_SLAVE_GENERATED= 32,// REPLACE was added on slave, it was | 
| 517 |                                        // not in the original query on master. | 
| 518 |     OPT_IF_EXISTS= 64 | 
| 519 |   }; | 
| 520 |  | 
| 521 | private: | 
| 522 |   Options m_options; | 
| 523 |  | 
| 524 | public: | 
| 525 |   Options create_like_options() const | 
| 526 |   { | 
| 527 |     return (DDL_options_st::Options) | 
| 528 |            (((uint) m_options) & (OPT_IF_NOT_EXISTS | OPT_OR_REPLACE)); | 
| 529 |   } | 
| 530 |   void init() { m_options= OPT_NONE; } | 
| 531 |   void init(Options options) { m_options= options; } | 
| 532 |   void set(Options other) | 
| 533 |   { | 
| 534 |     m_options= other; | 
| 535 |   } | 
| 536 |   void set(const DDL_options_st other) | 
| 537 |   { | 
| 538 |     m_options= other.m_options; | 
| 539 |   } | 
| 540 |   bool if_not_exists() const { return m_options & OPT_IF_NOT_EXISTS; } | 
| 541 |   bool or_replace() const { return m_options & OPT_OR_REPLACE; } | 
| 542 |   bool or_replace_slave_generated() const | 
| 543 |   { return m_options & OPT_OR_REPLACE_SLAVE_GENERATED; } | 
| 544 |   bool like() const { return m_options & OPT_LIKE; } | 
| 545 |   bool if_exists() const { return m_options & OPT_IF_EXISTS; } | 
| 546 |   void add(const DDL_options_st::Options other) | 
| 547 |   { | 
| 548 |     m_options= (Options) ((uint) m_options | (uint) other); | 
| 549 |   } | 
| 550 |   void add(const DDL_options_st &other) | 
| 551 |   { | 
| 552 |     add(other.m_options); | 
| 553 |   } | 
| 554 |   DDL_options_st operator|(const DDL_options_st &other) | 
| 555 |   { | 
| 556 |     add(other.m_options); | 
| 557 |     return *this; | 
| 558 |   } | 
| 559 |   DDL_options_st operator|=(DDL_options_st::Options other) | 
| 560 |   { | 
| 561 |     add(other); | 
| 562 |     return *this; | 
| 563 |   } | 
| 564 | }; | 
| 565 |  | 
| 566 |  | 
| 567 | class DDL_options: public DDL_options_st | 
| 568 | { | 
| 569 | public: | 
| 570 |   DDL_options() { init(); } | 
| 571 |   DDL_options(Options options) { init(options); } | 
| 572 |   DDL_options(const DDL_options_st &options) | 
| 573 |   { DDL_options_st::operator=(options); } | 
| 574 | }; | 
| 575 |  | 
| 576 |  | 
| 577 | struct Lex_length_and_dec_st | 
| 578 | { | 
| 579 | private: | 
| 580 |   const char *m_length; | 
| 581 |   const char *m_dec; | 
| 582 | public: | 
| 583 |   void set(const char *length, const char *dec) | 
| 584 |   { | 
| 585 |     m_length= length; | 
| 586 |     m_dec= dec; | 
| 587 |   } | 
| 588 |   const char *length() const { return m_length; } | 
| 589 |   const char *dec() const { return m_dec; } | 
| 590 | }; | 
| 591 |  | 
| 592 |  | 
| 593 | struct Lex_field_type_st: public Lex_length_and_dec_st | 
| 594 | { | 
| 595 | private: | 
| 596 |   const Type_handler *m_handler; | 
| 597 |   void set(const Type_handler *handler, const char *length, const char *dec) | 
| 598 |   { | 
| 599 |     m_handler= handler; | 
| 600 |     Lex_length_and_dec_st::set(length, dec); | 
| 601 |   } | 
| 602 | public: | 
| 603 |   void set(const Type_handler *handler, Lex_length_and_dec_st length_and_dec) | 
| 604 |   { | 
| 605 |     m_handler= handler; | 
| 606 |     Lex_length_and_dec_st::operator=(length_and_dec); | 
| 607 |   } | 
| 608 |   void set(const Type_handler *handler, const char *length) | 
| 609 |   { | 
| 610 |     set(handler, length, 0); | 
| 611 |   } | 
| 612 |   void set(const Type_handler *handler) | 
| 613 |   { | 
| 614 |     set(handler, 0, 0); | 
| 615 |   } | 
| 616 |   const Type_handler *type_handler() const { return m_handler; } | 
| 617 | }; | 
| 618 |  | 
| 619 |  | 
| 620 | struct Lex_dyncol_type_st: public Lex_length_and_dec_st | 
| 621 | { | 
| 622 | private: | 
| 623 |   int m_type; // enum_dynamic_column_type is not visible here, so use int | 
| 624 | public: | 
| 625 |   void set(int type, const char *length, const char *dec) | 
| 626 |   { | 
| 627 |     m_type= type; | 
| 628 |     Lex_length_and_dec_st::set(length, dec); | 
| 629 |   } | 
| 630 |   void set(int type, Lex_length_and_dec_st length_and_dec) | 
| 631 |   { | 
| 632 |     m_type= type; | 
| 633 |     Lex_length_and_dec_st::operator=(length_and_dec); | 
| 634 |   } | 
| 635 |   void set(int type, const char *length) | 
| 636 |   { | 
| 637 |     set(type, length, 0); | 
| 638 |   } | 
| 639 |   void set(int type) | 
| 640 |   { | 
| 641 |     set(type, 0, 0); | 
| 642 |   } | 
| 643 |   int dyncol_type() const { return m_type; } | 
| 644 | }; | 
| 645 |  | 
| 646 |  | 
| 647 | struct Lex_spblock_handlers_st | 
| 648 | { | 
| 649 | public: | 
| 650 |   int hndlrs; | 
| 651 |   void init(int count) { hndlrs= count; } | 
| 652 | }; | 
| 653 |  | 
| 654 |  | 
| 655 | struct Lex_spblock_st: public Lex_spblock_handlers_st | 
| 656 | { | 
| 657 | public: | 
| 658 |   int vars; | 
| 659 |   int conds; | 
| 660 |   int curs; | 
| 661 |   void init() | 
| 662 |   { | 
| 663 |     vars= conds= hndlrs= curs= 0; | 
| 664 |   } | 
| 665 |   void init_using_vars(uint nvars) | 
| 666 |   { | 
| 667 |     vars= nvars; | 
| 668 |     conds= hndlrs= curs= 0; | 
| 669 |   } | 
| 670 |   void join(const Lex_spblock_st &b1, const Lex_spblock_st &b2) | 
| 671 |   { | 
| 672 |     vars= b1.vars + b2.vars; | 
| 673 |     conds= b1.conds + b2.conds; | 
| 674 |     hndlrs= b1.hndlrs + b2.hndlrs; | 
| 675 |     curs= b1.curs + b2.curs; | 
| 676 |   } | 
| 677 | }; | 
| 678 |  | 
| 679 |  | 
| 680 | class Lex_spblock: public Lex_spblock_st | 
| 681 | { | 
| 682 | public: | 
| 683 |   Lex_spblock() { init(); } | 
| 684 |   Lex_spblock(const Lex_spblock_handlers_st &other) | 
| 685 |   { | 
| 686 |     vars= conds= curs= 0; | 
| 687 |     hndlrs= other.hndlrs; | 
| 688 |   } | 
| 689 | }; | 
| 690 |  | 
| 691 |  | 
| 692 | struct Lex_for_loop_bounds_st | 
| 693 | { | 
| 694 | public: | 
| 695 |   class sp_assignment_lex *m_index; | 
| 696 |   class sp_assignment_lex *m_upper_bound; | 
| 697 |   int8 m_direction; | 
| 698 |   bool m_implicit_cursor; | 
| 699 |   bool is_for_loop_cursor() const { return m_upper_bound == NULL; } | 
| 700 | }; | 
| 701 |  | 
| 702 |  | 
| 703 | struct Lex_for_loop_st | 
| 704 | { | 
| 705 | public: | 
| 706 |   class sp_variable *m_index; | 
| 707 |   class sp_variable *m_upper_bound; | 
| 708 |   int m_cursor_offset; | 
| 709 |   int8 m_direction; | 
| 710 |   bool m_implicit_cursor; | 
| 711 |   void init() | 
| 712 |   { | 
| 713 |     m_index= 0; | 
| 714 |     m_upper_bound= 0; | 
| 715 |     m_direction= 0; | 
| 716 |     m_implicit_cursor= false; | 
| 717 |   } | 
| 718 |   void init(const Lex_for_loop_st &other) | 
| 719 |   { | 
| 720 |     *this= other; | 
| 721 |   } | 
| 722 |   bool is_for_loop_cursor() const { return m_upper_bound == NULL; } | 
| 723 | }; | 
| 724 |  | 
| 725 |  | 
| 726 | enum trim_spec { TRIM_LEADING, TRIM_TRAILING, TRIM_BOTH }; | 
| 727 |  | 
| 728 | struct Lex_trim_st | 
| 729 | { | 
| 730 |   Item *m_remove; | 
| 731 |   Item *m_source; | 
| 732 |   trim_spec m_spec; | 
| 733 | public: | 
| 734 |   void set(trim_spec spec, Item *remove, Item *source) | 
| 735 |   { | 
| 736 |     m_spec= spec; | 
| 737 |     m_remove= remove; | 
| 738 |     m_source= source; | 
| 739 |   } | 
| 740 |   void set(trim_spec spec, Item *source) | 
| 741 |   { | 
| 742 |     set(spec, NULL, source); | 
| 743 |   } | 
| 744 |   Item *make_item_func_trim_std(THD *thd) const; | 
| 745 |   Item *make_item_func_trim_oracle(THD *thd) const; | 
| 746 |   Item *make_item_func_trim(THD *thd) const; | 
| 747 | }; | 
| 748 |  | 
| 749 |  | 
| 750 | class Lex_trim: public Lex_trim_st | 
| 751 | { | 
| 752 | public: | 
| 753 |   Lex_trim(trim_spec spec, Item *source) { set(spec, source); } | 
| 754 | }; | 
| 755 |  | 
| 756 |  | 
| 757 | class Load_data_param | 
| 758 | { | 
| 759 | protected: | 
| 760 |   CHARSET_INFO *m_charset;   // Character set of the file | 
| 761 |   ulonglong m_fixed_length;  // Sum of target field lengths for fixed format | 
| 762 |   bool m_is_fixed_length; | 
| 763 |   bool m_use_blobs; | 
| 764 | public: | 
| 765 |   Load_data_param(CHARSET_INFO *cs, bool is_fixed_length): | 
| 766 |     m_charset(cs), | 
| 767 |     m_fixed_length(0), | 
| 768 |     m_is_fixed_length(is_fixed_length), | 
| 769 |     m_use_blobs(false) | 
| 770 |   { } | 
| 771 |   bool add_outvar_field(THD *thd, const Field *field); | 
| 772 |   bool add_outvar_user_var(THD *thd); | 
| 773 |   CHARSET_INFO *charset() const { return m_charset; } | 
| 774 |   bool is_fixed_length() const { return m_is_fixed_length; } | 
| 775 |   bool use_blobs() const { return m_use_blobs; } | 
| 776 | }; | 
| 777 |  | 
| 778 |  | 
| 779 | class Load_data_outvar | 
| 780 | { | 
| 781 | public: | 
| 782 |   virtual ~Load_data_outvar() {} | 
| 783 |   virtual bool load_data_set_null(THD *thd, const Load_data_param *param)= 0; | 
| 784 |   virtual bool load_data_set_value(THD *thd, const char *pos, uint length, | 
| 785 |                                    const Load_data_param *param)= 0; | 
| 786 |   virtual bool load_data_set_no_data(THD *thd, const Load_data_param *param)= 0; | 
| 787 |   virtual void load_data_print_for_log_event(THD *thd, class String *to) const= 0; | 
| 788 |   virtual bool load_data_add_outvar(THD *thd, Load_data_param *param) const= 0; | 
| 789 |   virtual uint load_data_fixed_length() const= 0; | 
| 790 | }; | 
| 791 |  | 
| 792 |  | 
| 793 | #endif /* STRUCTS_INCLUDED */ | 
| 794 |  |