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