1 /* Copyright (c) 2016, 2020, 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 #ifndef SQL_DD_SHOW_QUERY_BUILDER_H
24 #define SQL_DD_SHOW_QUERY_BUILDER_H
25 
26 #include "lex_string.h"
27 #include "sql/mem_root_array.h"
28 
29 class Item;
30 class PT_derived_table;
31 class PT_order_list;
32 class PT_select_item_list;
33 class PT_table_reference;
34 class SELECT_LEX;
35 class String;
36 class THD;
37 struct YYLTYPE;
38 
39 typedef YYLTYPE POS;
40 
41 namespace dd {
42 namespace info_schema {
43 
44 /**
45   This class provide framework to build a SELECT_LEX using ParseTree
46   nodes.
47 
48   Note that this class is designed to help build queries that are
49   required to implement SHOW commands over data dictionary tables. It
50   does not provide complete framework, e.g., you cannot add a GROUP BY
51   node for now, mainly because that is not needed to implement SHOW
52   command.
53 
54   This class is used by implementation of SHOW command in
55   sql/dd/show.cc. The class enables code re-usability.
56 
57   One can build SELECT_LEX that represents following,
58 
59   ...
60     SELECT star_select_item, select_item1, select_item2, ...
61       FROM from_item OR FROM PT_derived_table
62       WHERE condition AND condition AND ...
63       ORDER BY order_by_field1, order_by_field2 , ...
64   ...
65 
66   Where as, a 'condition' can be one of,
67     field_name = "value"
68     field_name LIKE "value%"
69 
70   One can think of enhancing this framework on need basis.
71 
72   Note to server general team: This framework can be used by
73   sql/sql_show_status.* implementation. For now, this file is kept
74   inside sql/dd, but we can think of moving it out to sql/.
75 
76   The memory used while building the this Parse Tree is thd->mem_root.
77 */
78 
79 class Select_lex_builder {
80  public:
81   Select_lex_builder(const POS *pc, THD *thd);
82 
83   /**
84     Add item representing star in "SELECT '*' ...".
85 
86     @return false on success.
87             true  on failure.
88   */
89 
90   bool add_star_select_item();
91 
92   /**
93     Add item representing a column as,
94     @code
95     SELECT <field_name> AS <alias>, ...
96     @endcode
97 
98     The item will be appended to existing list of select items
99     for this query.
100 
101     @return false on success.
102             true  on failure.
103   */
104 
105   bool add_select_item(const LEX_CSTRING &field_name, const LEX_CSTRING &alias);
106 
107   /**
108     Add expression as an item tree, with an alias to name the resulting column.
109 
110     The item will be appended to existing list of select items
111     for this query block.
112 
113     @return false on success.
114             true  on failure.
115   */
116 
117   bool add_select_expr(Item *select_list_item, const LEX_CSTRING &alias);
118 
119   /**
120     Add item representing a FROM clause table as,
121     @code
122     SELECT ... FROM <schema_name>.<table_name> ...
123     @endcode
124 
125     Only single table can be added. We cannot build a query with
126     JOIN clause for now.
127 
128     @return false on success.
129             true  on failure.
130   */
131 
132   bool add_from_item(const LEX_CSTRING &schema_name,
133                      const LEX_CSTRING &table_name);
134 
135   /**
136     Add item representing a FROM clause table as,
137     @code
138     SELECT ... FROM <sub query or derived table> ...
139     @endcode
140 
141     Only single table can be added. We cannot build a query with
142     JOIN clause for now.
143 
144     @return false on success.
145             true  on failure.
146   */
147 
148   bool add_from_item(PT_derived_table *dt);
149 
150   /**
151     Prepare item representing a LIKE condition,
152     @code
153     SELECT ... WHERE <field_name> LIKE <value%> ...
154     @endcode
155 
156     This item should be intern added to Select_lex_builder using
157     add_condition() method.
158 
159     @return pointer to Item* on success.
160             nullptr on failure.
161   */
162 
163   Item *prepare_like_item(const LEX_CSTRING &field_name, const String *wild);
164 
165   /**
166     Prepare item representing a equal to comparision condition,
167     @code
168     SELECT ... WHERE <field_name> = <value> ...
169     @endcode
170 
171     This item should be intern added to Select_lex_builder using
172     add_condition() method.
173 
174     @return pointer to Item* on success.
175             nullptr on failure.
176   */
177 
178   Item *prepare_equal_item(const LEX_CSTRING &field_name,
179                            const LEX_CSTRING &value);
180 
181   /**
182     Add a WHERE clause condition to Select_lex_builder.
183     @code
184     SELECT ... WHERE ... AND <condition> ...
185     @endcode
186 
187     If there are existing conditions, then the new condition is
188     append to the WHERE clause conditions with a 'AND' condition.
189 
190     @return false on success.
191             true  on failure.
192   */
193 
194   bool add_condition(Item *a);
195 
196   /**
197     Add a ORDER BY clause field to Select_lex_builder.
198     @code
199     SELECT ... ORDER BY <field_name>, ...
200     @endcode
201 
202     If there are existing ORDER BY field, then we append a new
203     field to the ORDER BY clause. All the fields are added to be
204     order in ascending order.
205 
206     @return false on success.
207             true  on failure.
208   */
209 
210   bool add_order_by(const LEX_CSTRING &field_name);
211 
212   /**
213     This function build ParseTree node that represents this
214     Select_lex_builder as sub-query. This enables us to build a
215     SELECT_LEX containing a sub-query in its FROM clause. This
216     sub-query is represented by ParseTree node PT_derived_table.
217     @code
218     SELECT ... FROM <PT_dervied_table>, ...
219     @endcode
220 
221     @return pointer to PT_derived_table on success.
222             nullptr on failure.
223   */
224 
225   PT_derived_table *prepare_derived_table(const LEX_CSTRING &table_alias);
226 
227   /**
228     Prepare a SELECT_LEX using all the information information
229     added to this Select_lex_builder.
230 
231     @return pointer to SELECT_LEX* on success.
232             nullptr on failure.
233   */
234 
235   SELECT_LEX *prepare_select_lex();
236 
237  private:
238   /**
239     Prepare a list of expression used to build select items for
240     the query being built.
241 
242     @return false on success.
243             true  on failure.
244   */
245 
246   bool add_to_select_item_list(Item *expr);
247 
248  private:
249   // Parser current position represented by YYLTYPE
250   const POS *m_pos;
251 
252   // Current thread
253   THD *m_thd;
254 
255   // List of select_items for the query.
256   PT_select_item_list *m_select_item_list;
257 
258   // Table reference in FROM clause for the query.
259   Mem_root_array_YY<PT_table_reference *> m_table_reference_list;
260 
261   // Expression representing a WHERE clause.
262   Item *m_where_clause;
263 
264   // List of order by clause elements.
265   PT_order_list *m_order_by_list;
266 };
267 
268 }  // namespace info_schema
269 }  // namespace dd
270 
271 #endif /* SQL_DD_SHOW_QUERY_BUILDER_H */
272