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-1335 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 */
find_set(TYPELIB * lib,const char * str,size_t length,CHARSET_INFO * cs,char ** err_pos,uint * err_len,bool * set_warning)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; /* total length of user defined key parts */
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 key_part_map ext_key_part_map;
113 LEX_CSTRING name;
114 uint block_size;
find_type(const TYPELIB * lib,const char * find,size_t length,bool part_match)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 TABLE *table;
152 LEX_CSTRING comment;
153 /** reference to the list of options or NULL */
154 engine_option_value *option_list;
155 ha_index_option_struct *option_struct; /* structure with parsed options */
find_type2(const TYPELIB * typelib,const char * x,size_t length,CHARSET_INFO * cs)156
157 double actual_rec_per_key(uint i);
158
159 } KEY;
160
161
162 struct st_join_table;
163
164 typedef struct st_reginfo { /* Extra info about reg */
165 struct st_join_table *join_tab; /* Used by SELECT() */
166 enum thr_lock_type lock_type; /* How database is used */
167 bool not_exists_optimize;
168 /*
169 TRUE <=> range optimizer found that there is no rows satisfying
170 table conditions.
171 */
172 bool impossible_range;
173 } REGINFO;
174
175
176 /*
177 Originally MySQL used MYSQL_TIME structure inside server only, but since
178 4.1 it's exported to user in the new client API. Define aliases for
179 new names to keep existing code simple.
180 */
181
182 typedef enum enum_mysql_timestamp_type timestamp_type;
183
184
185 typedef struct {
186 ulong year,month,day,hour;
187 ulonglong minute,second,second_part;
188 bool neg;
189 } INTERVAL;
190
191
192 typedef struct st_known_date_time_format {
193 const char *format_name;
unhex_type2(TYPELIB * interval)194 const char *date_format;
195 const char *datetime_format;
196 const char *time_format;
197 } KNOWN_DATE_TIME_FORMAT;
198
199 extern const char *show_comp_option_name[];
200
201 typedef int *(*update_var)(THD *, struct st_mysql_show_var *);
202
203
204 struct AUTHID
205 {
206 LEX_CSTRING user, host;
207 void init() { memset(this, 0, sizeof(*this)); }
208 void copy(MEM_ROOT *root, const LEX_CSTRING *usr, const LEX_CSTRING *host);
209 bool is_role() const { return user.str[0] && !host.str[0]; }
210 void set_lex_string(LEX_CSTRING *l, char *buf)
211 {
212 if (is_role())
213 *l= user;
214 else
215 {
216 l->str= buf;
217 l->length= strxmov(buf, user.str, "@", host.str, NullS) - buf;
218 }
219 }
220 void parse(const char *str, size_t length);
221 bool read_from_mysql_proc_row(THD *thd, TABLE *table);
222 };
223
224
225 struct LEX_USER: public AUTHID
226 {
227 LEX_CSTRING plugin, auth;
228 LEX_CSTRING pwtext, pwhash;
229 void reset_auth()
230 {
231 pwtext.length= pwhash.length= plugin.length= auth.length= 0;
232 pwtext.str= pwhash.str= 0;
233 plugin.str= auth.str= "";
check_word(TYPELIB * lib,const char * val,const char * end,const char ** end_of_word)234 }
235 };
236
237 /*
238 This structure specifies the maximum amount of resources which
239 can be consumed by each account. Zero value of a member means
240 there is no limit.
241 */
242 typedef struct user_resources {
243 /* Maximum number of queries/statements per hour. */
244 uint questions;
245 /*
246 Maximum number of updating statements per hour (which statements are
247 updating is defined by sql_command_flags array).
248 */
249 uint updates;
250 /* Maximum number of connections established per hour. */
251 uint conn_per_hour;
252 /*
253 Maximum number of concurrent connections. If -1 then no new
254 connections allowed
255 */
256 int user_conn;
257 /* Max query timeout */
258 double max_statement_time;
259
260 /*
261 Values of this enum and specified_limits member are used by the
262 parser to store which user limits were specified in GRANT statement.
263 */
264 enum {QUERIES_PER_HOUR= 1, UPDATES_PER_HOUR= 2, CONNECTIONS_PER_HOUR= 4,
265 USER_CONNECTIONS= 8, MAX_STATEMENT_TIME= 16};
266 uint specified_limits;
267 } USER_RESOURCES;
268
strconvert(CHARSET_INFO * from_cs,const char * from,size_t from_length,CHARSET_INFO * to_cs,char * to,size_t to_length,uint * errors)269
270 /*
271 This structure is used for counting resources consumed and for checking
272 them against specified user limits.
273 */
274 typedef struct user_conn {
275 /*
276 Pointer to user+host key (pair separated by '\0') defining the entity
277 for which resources are counted (By default it is user account thus
278 priv_user/priv_host pair is used. If --old-style-user-limits option
279 is enabled, resources are counted for each user+host separately).
280 */
281 char *user;
282 /* Pointer to host part of the key. */
283 char *host;
284 /**
285 The moment of time when per hour counters were reset last time
286 (i.e. start of "hour" for conn_per_hour, updates, questions counters).
287 */
288 ulonglong reset_utime;
289 /* Total length of the key. */
290 uint len;
291 /* Current amount of concurrent connections for this account. */
292 int connections;
293 /*
294 Current number of connections per hour, number of updating statements
295 per hour and total number of statements per hour for this account.
296 */
297 uint conn_per_hour, updates, questions;
298 /* Maximum amount of resources which account is allowed to consume. */
299 USER_RESOURCES user_resources;
300 } USER_CONN;
301
302 typedef struct st_user_stats
303 {
304 char user[MY_MAX(USERNAME_LENGTH, LIST_PROCESS_HOST_LEN) + 1];
305 // Account name the user is mapped to when this is a user from mapped_user.
306 // Otherwise, the same value as user.
307 char priv_user[MY_MAX(USERNAME_LENGTH, LIST_PROCESS_HOST_LEN) + 1];
308 uint user_name_length;
309 uint total_connections;
310 uint total_ssl_connections;
311 uint concurrent_connections;
312 time_t connected_time; // in seconds
313 ha_rows rows_read, rows_sent;
314 ha_rows rows_updated, rows_deleted, rows_inserted;
315 ulonglong bytes_received;
316 ulonglong bytes_sent;
317 ulonglong binlog_bytes_written;
318 ulonglong select_commands, update_commands, other_commands;
319 ulonglong commit_trans, rollback_trans;
320 ulonglong denied_connections, lost_connections, max_statement_time_exceeded;
321 ulonglong access_denied_errors;
322 ulonglong empty_queries;
323 double busy_time; // in seconds
324 double cpu_time; // in seconds
325 } USER_STATS;
326
327 typedef struct st_table_stats
328 {
329 char table[NAME_LEN * 2 + 2]; // [db] + '\0' + [table] + '\0'
330 size_t table_name_length;
331 ulonglong rows_read, rows_changed;
332 ulonglong rows_changed_x_indexes;
333 /* Stores enum db_type, but forward declarations cannot be done */
334 int engine_type;
find_string_in_array(LEX_CSTRING * const haystack,LEX_CSTRING * const needle,CHARSET_INFO * const cs)335 } TABLE_STATS;
336
337 typedef struct st_index_stats
338 {
339 // [db] + '\0' + [table] + '\0' + [index] + '\0'
340 char index[NAME_LEN * 3 + 3];
341 size_t index_name_length; /* Length of 'index' */
342 ulonglong rows_read;
343 } INDEX_STATS;
344
345
346 /* Bits in form->update */
347 #define REG_MAKE_DUPP 1U /* Make a copy of record when read */
348 #define REG_NEW_RECORD 2U /* Write a new record if not found */
set_to_string(THD * thd,LEX_CSTRING * result,ulonglong set,const char * lib[])349 #define REG_UPDATE 4U /* Uppdate record */
350 #define REG_DELETE 8U /* Delete found record */
351 #define REG_PROG 16U /* User is updating database */
352 #define REG_CLEAR_AFTER_WRITE 32U
353 #define REG_MAY_BE_UPDATED 64U
354 #define REG_AUTO_UPDATE 64U /* Used in D-forms for scroll-tables */
355 #define REG_OVERWRITE 128U
356 #define REG_SKIP_DUP 256U
357
358 /* Bits in form->status */
359 #define STATUS_NO_RECORD (1U+2U) /* Record isn't usable */
360 #define STATUS_GARBAGE 1U
361 #define STATUS_NOT_FOUND 2U /* No record in database when needed */
362 #define STATUS_NO_PARENT 4U /* Parent record wasn't found */
363 #define STATUS_NOT_READ 8U /* Record isn't read */
364 #define STATUS_UPDATED 16U /* Record is updated by formula */
365 #define STATUS_NULL_ROW 32U /* table->null_row is set */
366 #define STATUS_DELETED 64U
367
368 /*
369 Such interval is "discrete": it is the set of
370 { auto_inc_interval_min + k * increment,
371 0 <= k <= (auto_inc_interval_values-1) }
372 Where "increment" is maintained separately by the user of this class (and is
373 currently only thd->variables.auto_increment_increment).
374 It mustn't derive from Sql_alloc, because SET INSERT_ID needs to
375 allocate memory which must stay allocated for use by the next statement.
376 */
377 class Discrete_interval {
378 private:
379 ulonglong interval_min;
380 ulonglong interval_values;
381 ulonglong interval_max; // excluded bound. Redundant.
382 public:
383 Discrete_interval *next; // used when linked into Discrete_intervals_list
384 void replace(ulonglong start, ulonglong val, ulonglong incr)
385 {
386 interval_min= start;
387 interval_values= val;
388 interval_max= (val == ULONGLONG_MAX) ? val : start + val * incr;
389 }
390 Discrete_interval(ulonglong start, ulonglong val, ulonglong incr) :
391 next(NULL) { replace(start, val, incr); };
392 Discrete_interval() : next(NULL) { replace(0, 0, 0); };
393 ulonglong minimum() const { return interval_min; };
394 ulonglong values() const { return interval_values; };
395 ulonglong maximum() const { return interval_max; };
396 /*
397 If appending [3,5] to [1,2], we merge both in [1,5] (they should have the
398 same increment for that, user of the class has to ensure that). That is
399 just a space optimization. Returns 0 if merge succeeded.
400 */
401 bool merge_if_contiguous(ulonglong start, ulonglong val, ulonglong incr)
402 {
403 if (interval_max == start)
404 {
405 if (val == ULONGLONG_MAX)
406 {
407 interval_values= interval_max= val;
408 }
409 else
410 {
411 interval_values+= val;
412 interval_max= start + val * incr;
413 }
414 return 0;
415 }
416 return 1;
417 };
418 };
419
420 /* List of Discrete_interval objects */
421 class Discrete_intervals_list {
422 private:
423 Discrete_interval *head;
424 Discrete_interval *tail;
425 /*
426 When many intervals are provided at the beginning of the execution of a
427 statement (in a replication slave or SET INSERT_ID), "current" points to
428 the interval being consumed by the thread now (so "current" goes from
429 "head" to "tail" then to NULL).
430 */
431 Discrete_interval *current;
432 uint elements; // number of elements
433 void set_members(Discrete_interval *h, Discrete_interval *t,
434 Discrete_interval *c, uint el)
435 {
436 head= h;
437 tail= t;
438 current= c;
439 elements= el;
440 }
441 void operator=(Discrete_intervals_list &); /* prevent use of these */
442 Discrete_intervals_list(const Discrete_intervals_list &);
443
444 public:
445 Discrete_intervals_list() : head(NULL), current(NULL), elements(0) {};
446 void empty_no_free()
447 {
448 set_members(NULL, NULL, NULL, 0);
449 }
450 void empty()
451 {
452 for (Discrete_interval *i= head; i;)
453 {
454 Discrete_interval *next= i->next;
455 delete i;
456 i= next;
457 }
458 empty_no_free();
459 }
460 void copy_shallow(const Discrete_intervals_list * dli)
461 {
462 head= dli->get_head();
463 tail= dli->get_tail();
464 current= dli->get_current();
465 elements= dli->nb_elements();
466 }
467 void swap (Discrete_intervals_list * dli)
468 {
469 Discrete_interval *h, *t, *c;
470 uint el;
471 h= dli->get_head();
472 t= dli->get_tail();
473 c= dli->get_current();
474 el= dli->nb_elements();
475 dli->copy_shallow(this);
476 set_members(h, t, c, el);
477 }
478 const Discrete_interval* get_next()
479 {
480 Discrete_interval *tmp= current;
481 if (current != NULL)
482 current= current->next;
483 return tmp;
484 }
485 ~Discrete_intervals_list() { empty(); };
486 bool append(ulonglong start, ulonglong val, ulonglong incr);
487 bool append(Discrete_interval *interval);
488 ulonglong minimum() const { return (head ? head->minimum() : 0); };
489 ulonglong maximum() const { return (head ? tail->maximum() : 0); };
490 uint nb_elements() const { return elements; }
491 Discrete_interval* get_head() const { return head; };
492 Discrete_interval* get_tail() const { return tail; };
493 Discrete_interval* get_current() const { return current; };
494 };
495
496
497 /*
498 DDL options:
499 - CREATE IF NOT EXISTS
500 - DROP IF EXISTS
501 - CREATE LIKE
502 - REPLACE
503 */
504 struct DDL_options_st
505 {
506 public:
507 enum Options
508 {
509 OPT_NONE= 0,
510 OPT_IF_NOT_EXISTS= 2, // CREATE TABLE IF NOT EXISTS
511 OPT_LIKE= 4, // CREATE TABLE LIKE
512 OPT_OR_REPLACE= 16, // CREATE OR REPLACE TABLE
513 OPT_OR_REPLACE_SLAVE_GENERATED= 32,// REPLACE was added on slave, it was
514 // not in the original query on master.
515 OPT_IF_EXISTS= 64
516 };
517
518 private:
519 Options m_options;
520
521 public:
522 Options create_like_options() const
523 {
524 return (DDL_options_st::Options)
525 (((uint) m_options) & (OPT_IF_NOT_EXISTS | OPT_OR_REPLACE));
526 }
527 void init() { m_options= OPT_NONE; }
528 void init(Options options) { m_options= options; }
529 void set(Options other)
530 {
531 m_options= other;
532 }
533 void set(const DDL_options_st other)
534 {
535 m_options= other.m_options;
536 }
537 bool if_not_exists() const { return m_options & OPT_IF_NOT_EXISTS; }
538 bool or_replace() const { return m_options & OPT_OR_REPLACE; }
539 bool or_replace_slave_generated() const
540 { return m_options & OPT_OR_REPLACE_SLAVE_GENERATED; }
541 bool like() const { return m_options & OPT_LIKE; }
542 bool if_exists() const { return m_options & OPT_IF_EXISTS; }
543 void add(const DDL_options_st::Options other)
544 {
545 m_options= (Options) ((uint) m_options | (uint) other);
546 }
547 void add(const DDL_options_st &other)
548 {
549 add(other.m_options);
550 }
551 DDL_options_st operator|(const DDL_options_st &other)
552 {
553 add(other.m_options);
554 return *this;
555 }
556 DDL_options_st operator|=(DDL_options_st::Options other)
557 {
558 add(other);
559 return *this;
560 }
561 };
562
563
564 class DDL_options: public DDL_options_st
565 {
566 public:
567 DDL_options() { init(); }
568 DDL_options(Options options) { init(options); }
569 DDL_options(const DDL_options_st &options)
570 { DDL_options_st::operator=(options); }
571 };
572
573
574 struct Lex_length_and_dec_st
575 {
576 private:
577 const char *m_length;
578 const char *m_dec;
579 public:
580 void set(const char *length, const char *dec)
581 {
582 m_length= length;
583 m_dec= dec;
584 }
585 const char *length() const { return m_length; }
586 const char *dec() const { return m_dec; }
587 };
588
589
590 struct Lex_field_type_st: public Lex_length_and_dec_st
591 {
592 private:
593 const Type_handler *m_handler;
594 void set(const Type_handler *handler, const char *length, const char *dec)
595 {
596 m_handler= handler;
597 Lex_length_and_dec_st::set(length, dec);
598 }
599 public:
600 void set(const Type_handler *handler, Lex_length_and_dec_st length_and_dec)
601 {
602 m_handler= handler;
603 Lex_length_and_dec_st::operator=(length_and_dec);
604 }
605 void set(const Type_handler *handler, const char *length)
606 {
607 set(handler, length, 0);
608 }
609 void set(const Type_handler *handler)
610 {
611 set(handler, 0, 0);
612 }
613 void set_handler(const Type_handler *handler)
614 {
615 m_handler= handler;
616 }
617 const Type_handler *type_handler() const { return m_handler; }
618 };
619
620
621 struct Lex_dyncol_type_st: public Lex_length_and_dec_st
622 {
623 private:
624 int m_type; // enum_dynamic_column_type is not visible here, so use int
625 public:
626 void set(int type, const char *length, const char *dec)
627 {
628 m_type= type;
629 Lex_length_and_dec_st::set(length, dec);
630 }
631 void set(int type, Lex_length_and_dec_st length_and_dec)
632 {
633 m_type= type;
634 Lex_length_and_dec_st::operator=(length_and_dec);
635 }
636 void set(int type, const char *length)
637 {
638 set(type, length, 0);
639 }
640 void set(int type)
641 {
642 set(type, 0, 0);
643 }
644 int dyncol_type() const { return m_type; }
645 };
646
647
648 struct Lex_spblock_handlers_st
649 {
650 public:
651 int hndlrs;
652 void init(int count) { hndlrs= count; }
653 };
654
655
656 struct Lex_spblock_st: public Lex_spblock_handlers_st
657 {
658 public:
659 int vars;
660 int conds;
661 int curs;
662 void init()
663 {
664 vars= conds= hndlrs= curs= 0;
665 }
666 void init_using_vars(uint nvars)
667 {
668 vars= nvars;
669 conds= hndlrs= curs= 0;
670 }
671 void join(const Lex_spblock_st &b1, const Lex_spblock_st &b2)
672 {
673 vars= b1.vars + b2.vars;
674 conds= b1.conds + b2.conds;
675 hndlrs= b1.hndlrs + b2.hndlrs;
676 curs= b1.curs + b2.curs;
677 }
678 };
679
680
681 class Lex_spblock: public Lex_spblock_st
682 {
683 public:
684 Lex_spblock() { init(); }
685 Lex_spblock(const Lex_spblock_handlers_st &other)
686 {
687 vars= conds= curs= 0;
688 hndlrs= other.hndlrs;
689 }
690 };
691
692
693 struct Lex_for_loop_bounds_st
694 {
695 public:
696 class sp_assignment_lex *m_index; // The first iteration value (or cursor)
697 class sp_assignment_lex *m_target_bound; // The last iteration value
698 int8 m_direction;
699 bool m_implicit_cursor;
700 bool is_for_loop_cursor() const { return m_target_bound == NULL; }
701 };
702
703
704 class Lex_for_loop_bounds_intrange: public Lex_for_loop_bounds_st
705 {
706 public:
707 Lex_for_loop_bounds_intrange(int8 direction,
708 class sp_assignment_lex *left_expr,
709 class sp_assignment_lex *right_expr)
710 {
711 m_direction= direction;
712 m_index= direction > 0 ? left_expr : right_expr;
713 m_target_bound= direction > 0 ? right_expr : left_expr;
714 m_implicit_cursor= false;
715 }
716 };
717
718
719 struct Lex_for_loop_st
720 {
721 public:
722 class sp_variable *m_index; // The first iteration value (or cursor)
723 class sp_variable *m_target_bound; // The last iteration value
724 int m_cursor_offset;
725 int8 m_direction;
726 bool m_implicit_cursor;
727 void init()
728 {
729 m_index= 0;
730 m_target_bound= 0;
731 m_direction= 0;
732 m_implicit_cursor= false;
733 }
734 void init(const Lex_for_loop_st &other)
735 {
736 *this= other;
737 }
738 bool is_for_loop_cursor() const { return m_target_bound == NULL; }
739 bool is_for_loop_explicit_cursor() const
740 {
741 return is_for_loop_cursor() && !m_implicit_cursor;
742 }
743 };
744
745
746 enum trim_spec { TRIM_LEADING, TRIM_TRAILING, TRIM_BOTH };
747
748 struct Lex_trim_st
749 {
750 Item *m_remove;
751 Item *m_source;
752 trim_spec m_spec;
753 public:
754 void set(trim_spec spec, Item *remove, Item *source)
755 {
756 m_spec= spec;
757 m_remove= remove;
758 m_source= source;
759 }
760 void set(trim_spec spec, Item *source)
761 {
762 set(spec, NULL, source);
763 }
764 Item *make_item_func_trim_std(THD *thd) const;
765 Item *make_item_func_trim_oracle(THD *thd) const;
766 Item *make_item_func_trim(THD *thd) const;
767 };
768
769
770 class Lex_trim: public Lex_trim_st
771 {
772 public:
773 Lex_trim(trim_spec spec, Item *source) { set(spec, source); }
774 };
775
776
777 class Load_data_param
778 {
779 protected:
780 CHARSET_INFO *m_charset; // Character set of the file
781 ulonglong m_fixed_length; // Sum of target field lengths for fixed format
782 bool m_is_fixed_length;
783 bool m_use_blobs;
784 public:
785 Load_data_param(CHARSET_INFO *cs, bool is_fixed_length):
786 m_charset(cs),
787 m_fixed_length(0),
788 m_is_fixed_length(is_fixed_length),
789 m_use_blobs(false)
790 { }
791 bool add_outvar_field(THD *thd, const Field *field);
792 bool add_outvar_user_var(THD *thd);
793 CHARSET_INFO *charset() const { return m_charset; }
794 bool is_fixed_length() const { return m_is_fixed_length; }
795 bool use_blobs() const { return m_use_blobs; }
796 };
797
798
799 class Load_data_outvar
800 {
801 public:
802 virtual ~Load_data_outvar() {}
803 virtual bool load_data_set_null(THD *thd, const Load_data_param *param)= 0;
804 virtual bool load_data_set_value(THD *thd, const char *pos, uint length,
805 const Load_data_param *param)= 0;
806 virtual bool load_data_set_no_data(THD *thd, const Load_data_param *param)= 0;
807 virtual void load_data_print_for_log_event(THD *thd, class String *to) const= 0;
808 virtual bool load_data_add_outvar(THD *thd, Load_data_param *param) const= 0;
809 virtual uint load_data_fixed_length() const= 0;
810 };
811
812
813 #endif /* STRUCTS_INCLUDED */
814