1 /* Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
2 
3    This program is free software; you can redistribute it and/or modify
4    it under the terms of the GNU General Public License, version 2.0,
5    as published by the Free Software Foundation.
6 
7    This program is also distributed with certain software (including
8    but not limited to OpenSSL) that is licensed under separate terms,
9    as designated in a particular file or component or in included license
10    documentation.  The authors of MySQL hereby grant you an additional
11    permission to link the program and your derivative works with the
12    separately licensed software that they have included with MySQL.
13 
14    This program is distributed in the hope that it will be useful,
15    but WITHOUT ANY WARRANTY; without even the implied warranty of
16    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17    GNU General Public License, version 2.0, for more details.
18 
19    You should have received a copy of the GNU General Public License
20    along with this program; if not, write to the Free Software
21    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301  USA */
22 
23 /*
24   Parse tree node classes for optimizer hint syntax
25 */
26 
27 
28 #ifndef PARSE_TREE_HINTS_INCLUDED
29 #define PARSE_TREE_HINTS_INCLUDED
30 
31 #include "my_config.h"
32 #include "parse_tree_node_base.h"
33 #include "sql_alloc.h"
34 #include "sql_list.h"
35 #include "mem_root_array.h"
36 #include "sql_string.h"
37 #include "sql_show.h"
38 #include "opt_hints.h"
39 
40 struct LEX;
41 
42 
43 struct Hint_param_table
44 {
45   LEX_CSTRING table;
46   LEX_CSTRING opt_query_block;
47 };
48 
49 
50 typedef Mem_root_array_YY<LEX_CSTRING, true> Hint_param_index_list;
51 typedef Mem_root_array_YY<Hint_param_table, true> Hint_param_table_list;
52 
53 
54 /**
55   The class is a base class for representation of the
56   different types of the hints. For the complex hints
57   it is also used as a container for additional argumnets.
58 */
59 class PT_hint : public Parse_tree_node
60 {
61   opt_hints_enum hint_type; // Hint type
62   bool state;                    // true if hints is on, false otherwise
63 public:
PT_hint(opt_hints_enum hint_type_arg,bool switch_state_arg)64   PT_hint(opt_hints_enum hint_type_arg, bool switch_state_arg)
65     : hint_type(hint_type_arg), state(switch_state_arg)
66   {}
67 
type()68   opt_hints_enum type() const { return hint_type; }
switch_on()69   bool switch_on() const { return state; }
70   /**
71     Print warning issuing in processing of the hint.
72 
73     @param thd             Pointer to THD object
74     @param err_code        Error code
75     @param qb_name_arg     QB name
76     @param table_name_arg  table name
77     @param key_name_arg    key name
78     @param hint            Pointer to hint object
79   */
80   virtual void print_warn(THD *thd, uint err_code,
81                           const LEX_CSTRING *qb_name_arg,
82                           LEX_CSTRING *table_name_arg,
83                           LEX_CSTRING *key_name_arg,
84                           PT_hint *hint) const;
85   /**
86     Append additional hint arguments.
87 
88     @param thd             Pointer to THD object
89     @param str             Pointer to String object
90   */
append_args(THD * thd,String * str)91   virtual void append_args(THD *thd, String *str) const {}
92 };
93 
94 
95 class PT_hint_list : public Parse_tree_node
96 {
97   typedef Parse_tree_node super;
98 
99   Mem_root_array<PT_hint *, true> hints;
100 
101 public:
PT_hint_list(MEM_ROOT * mem_root)102   explicit PT_hint_list(MEM_ROOT *mem_root) : hints(mem_root) {}
103 
104   /**
105     Function handles list of the hints we get after
106     parse procedure. It also creates query block hint
107     object(Opt_hints_qb) if it does not exists.
108 
109     @param pc   Pointer to Parse_context object
110 
111     @return  true in case of error,
112              false otherwise
113   */
114   virtual bool contextualize(Parse_context *pc);
115 
push_back(PT_hint * hint)116   bool push_back(PT_hint *hint) { return hints.push_back(hint); }
117 };
118 
119 
120 /**
121   Parse tree hint object for query block level hints.
122 */
123 class PT_qb_level_hint : public PT_hint
124 {
125   const LEX_CSTRING qb_name;  //< Name of query block
126   uint args;                  //< Bit mask of arguments to hint
127 
128   typedef PT_hint super;
129 public:
PT_qb_level_hint(const LEX_CSTRING qb_name_arg,bool switch_state_arg,enum opt_hints_enum hint_type_arg,uint arg)130   PT_qb_level_hint(const LEX_CSTRING qb_name_arg, bool switch_state_arg,
131                    enum opt_hints_enum hint_type_arg, uint arg)
132     : PT_hint(hint_type_arg, switch_state_arg),
133       qb_name(qb_name_arg), args(arg)
134   {}
135 
get_args()136   uint get_args() const { return args; }
137 
138   /**
139     Function handles query block level hint. It also creates query block hint
140     object (Opt_hints_qb) if it does not exist.
141 
142     @param pc  Pointer to Parse_context object
143 
144     @return  true in case of error,
145              false otherwise
146   */
147   virtual bool contextualize(Parse_context *pc);
148 
149   /**
150     Append hint arguments to given string
151 
152     @param thd             Pointer to THD object
153     @param str             Pointer to String object
154   */
155   virtual void append_args(THD *thd, String *str) const;
156 };
157 
158 
159 /**
160   Parse tree hint object for table level hints.
161 */
162 
163 class PT_table_level_hint : public PT_hint
164 {
165   const LEX_CSTRING qb_name;
166   Hint_param_table_list table_list;
167 
168   typedef PT_hint super;
169 public:
PT_table_level_hint(const LEX_CSTRING qb_name_arg,const Hint_param_table_list & table_list_arg,bool switch_state_arg,opt_hints_enum hint_type_arg)170   PT_table_level_hint(const LEX_CSTRING qb_name_arg,
171                       const Hint_param_table_list &table_list_arg,
172                       bool switch_state_arg,
173                       opt_hints_enum hint_type_arg)
174     : PT_hint(hint_type_arg, switch_state_arg),
175       qb_name(qb_name_arg), table_list(table_list_arg)
176   {}
177 
178   /**
179     Function handles table level hint. It also creates
180     table hint object (Opt_hints_table) if it does not
181     exist.
182 
183     @param pc  Pointer to Parse_context object
184 
185     @return  true in case of error,
186              false otherwise
187   */
188   virtual bool contextualize(Parse_context *pc);
189 };
190 
191 
192 /**
193   Parse tree hint object for key level hints.
194 */
195 
196 class PT_key_level_hint : public PT_hint
197 {
198   Hint_param_table table_name;
199   Hint_param_index_list key_list;
200 
201   typedef PT_hint super;
202 public:
PT_key_level_hint(Hint_param_table & table_name_arg,const Hint_param_index_list & key_list_arg,bool switch_state_arg,opt_hints_enum hint_type_arg)203   PT_key_level_hint(Hint_param_table &table_name_arg,
204                     const Hint_param_index_list &key_list_arg,
205                     bool switch_state_arg,
206                     opt_hints_enum hint_type_arg)
207     : PT_hint(hint_type_arg, switch_state_arg),
208       table_name(table_name_arg), key_list(key_list_arg)
209   {}
210 
211   /**
212     Function handles key level hint.
213     It also creates key hint object
214     (Opt_hints_key) if it does not
215     exist.
216 
217     @param pc  Pointer to Parse_context object
218 
219     @return  true in case of error,
220              false otherwise
221   */
222   virtual bool contextualize(Parse_context *pc);
223 };
224 
225 
226 /**
227   Parse tree hint object for QB_NAME hint.
228 */
229 
230 class PT_hint_qb_name : public PT_hint
231 {
232   const LEX_CSTRING qb_name;
233 
234   typedef PT_hint super;
235 public:
PT_hint_qb_name(const LEX_CSTRING qb_name_arg)236   PT_hint_qb_name(const LEX_CSTRING qb_name_arg)
237     : PT_hint(QB_NAME_HINT_ENUM, true), qb_name(qb_name_arg)
238   {}
239 
240   /**
241     Function sets query block name.
242 
243     @param pc  Pointer to Parse_context object
244 
245     @return  true in case of error,
246              false otherwise
247   */
248   virtual bool contextualize(Parse_context *pc);
append_args(THD * thd,String * str)249   virtual void append_args(THD *thd, String *str) const
250   {
251     append_identifier(thd, str, qb_name.str, qb_name.length);
252   }
253 
254 };
255 
256 
257 /**
258   Parse tree hint object for MAX_EXECUTION_TIME hint.
259 */
260 
261 class PT_hint_max_execution_time : public PT_hint
262 {
263   typedef PT_hint super;
264 public:
265   ulong milliseconds;
266 
PT_hint_max_execution_time(ulong milliseconds_arg)267   explicit PT_hint_max_execution_time(ulong milliseconds_arg)
268     : PT_hint(MAX_EXEC_TIME_HINT_ENUM, true), milliseconds(milliseconds_arg)
269   {}
270   /**
271     Function initializes MAX_EXECUTION_TIME hint
272 
273     @param pc   Pointer to Parse_context object
274 
275     @return  true in case of error,
276              false otherwise
277   */
278   virtual bool contextualize(Parse_context *pc);
append_args(THD * thd,String * str)279   virtual void append_args(THD *thd, String *str) const
280   {
281     str->append_ulonglong(milliseconds);
282   }
283 };
284 
285 
286 #endif /* PARSE_TREE_HINTS_INCLUDED */
287