1 /* Copyright (c) 2013, 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 #ifndef PARSE_TREE_NODE_INCLUDED 24 #define PARSE_TREE_NODE_INCLUDED 25 26 #include "my_config.h" 27 #include <cstdlib> 28 #include <cstring> 29 #include "my_sys.h" 30 #include "sql_const.h" 31 32 #include "parse_location.h" 33 34 class THD; 35 class st_select_lex; 36 37 // uncachable cause 38 #define UNCACHEABLE_DEPENDENT 1 39 #define UNCACHEABLE_RAND 2 40 #define UNCACHEABLE_SIDEEFFECT 4 41 /* For uncorrelated SELECT in an UNION with some correlated SELECTs */ 42 #define UNCACHEABLE_UNITED 8 43 #define UNCACHEABLE_CHECKOPTION 16 44 45 /** 46 Names for different query parse tree parts 47 */ 48 49 enum enum_parsing_context 50 { 51 CTX_NONE= 0, ///< Empty value 52 CTX_MESSAGE, ///< "No tables used" messages etc. 53 CTX_TABLE, ///< for single-table UPDATE/DELETE/INSERT/REPLACE 54 CTX_SELECT_LIST, ///< SELECT (subquery), (subquery)... 55 CTX_UPDATE_VALUE_LIST, ///< UPDATE ... SET field=(subquery)... 56 CTX_JOIN, 57 CTX_QEP_TAB, 58 CTX_MATERIALIZATION, 59 CTX_DUPLICATES_WEEDOUT, 60 CTX_DERIVED, ///< "Derived" subquery 61 CTX_WHERE, ///< Subquery in WHERE clause item tree 62 CTX_ON, ///< ON clause context 63 CTX_HAVING, ///< Subquery in HAVING clause item tree 64 CTX_ORDER_BY, ///< ORDER BY clause execution context 65 CTX_GROUP_BY, ///< GROUP BY clause execution context 66 CTX_SIMPLE_ORDER_BY, ///< ORDER BY clause execution context 67 CTX_SIMPLE_GROUP_BY, ///< GROUP BY clause execution context 68 CTX_DISTINCT, ///< DISTINCT clause execution context 69 CTX_SIMPLE_DISTINCT, ///< DISTINCT clause execution context 70 CTX_BUFFER_RESULT, ///< see SQL_BUFFER_RESULT in the manual 71 CTX_ORDER_BY_SQ, ///< Subquery in ORDER BY clause item tree 72 CTX_GROUP_BY_SQ, ///< Subquery in GROUP BY clause item tree 73 CTX_OPTIMIZED_AWAY_SUBQUERY, ///< Subquery executed once during optimization 74 CTX_UNION, 75 CTX_UNION_RESULT, ///< Pseudo-table context for UNION result 76 CTX_QUERY_SPEC ///< Inner SELECTs of UNION expression 77 }; 78 79 /* 80 Note: YYLTYPE doesn't overload a default constructor (as well an underlying 81 Symbol_location). 82 OTOH if we need a zero-initialized POS, YYLTYPE or Symbol_location object, 83 we can simply call POS(), YYLTYPE() or Symbol_location(): C++ does 84 value-initialization in that case. 85 */ 86 typedef YYLTYPE POS; 87 88 /** 89 Environment data for the contextualization phase 90 */ 91 struct Parse_context { 92 THD * const thd; ///< Current thread handler 93 MEM_ROOT *mem_root; ///< Current MEM_ROOT 94 st_select_lex * select; ///< Current SELECT_LEX object 95 96 Parse_context(THD *thd, st_select_lex *select); 97 }; 98 99 100 // defined in sql_parse.cc: 101 bool check_stack_overrun(THD *thd, long margin, uchar *dummy); 102 103 104 /** 105 Base class for parse tree nodes 106 */ 107 class Parse_tree_node 108 { 109 friend class Item; // for direct access to the "contextualized" field 110 111 Parse_tree_node(const Parse_tree_node &); // undefined 112 void operator=(const Parse_tree_node &); // undefined 113 114 #ifndef DBUG_OFF 115 private: 116 bool contextualized; // true if the node object is contextualized 117 bool transitional; // TODO: remove that after parser refactoring 118 #endif//DBUG_OFF 119 120 public: new(size_t size,MEM_ROOT * mem_root)121 static void *operator new(size_t size, MEM_ROOT *mem_root) throw () 122 { return alloc_root(mem_root, size); } delete(void * ptr,size_t size)123 static void operator delete(void *ptr,size_t size) { TRASH(ptr, size); } delete(void * ptr,MEM_ROOT * mem_root)124 static void operator delete(void *ptr, MEM_ROOT *mem_root) {} 125 126 protected: Parse_tree_node()127 Parse_tree_node() 128 { 129 #ifndef DBUG_OFF 130 contextualized= false; 131 transitional= false; 132 #endif//DBUG_OFF 133 } 134 135 public: ~Parse_tree_node()136 virtual ~Parse_tree_node() {} 137 138 #ifndef DBUG_OFF is_contextualized()139 bool is_contextualized() const { return contextualized; } 140 #endif//DBUG_OFF 141 142 /** 143 Do all context-sensitive things and mark the node as contextualized 144 145 @param pc current parse context 146 147 @retval false success 148 @retval true syntax/OOM/etc error 149 */ contextualize(Parse_context * pc)150 virtual bool contextualize(Parse_context *pc) 151 { 152 #ifndef DBUG_OFF 153 if (transitional) 154 { 155 DBUG_ASSERT(contextualized); 156 return false; 157 } 158 #endif//DBUG_OFF 159 160 uchar dummy; 161 if (check_stack_overrun(pc->thd, STACK_MIN_SIZE, &dummy)) 162 return true; 163 164 #ifndef DBUG_OFF 165 DBUG_ASSERT(!contextualized); 166 contextualized= true; 167 #endif//DBUG_OFF 168 169 return false; 170 } 171 172 /** 173 Intermediate version of the contextualize() function 174 175 This function is intended to resolve parser grammar loops. 176 177 During the step-by-step refactoring of the parser grammar we wrap 178 each context-sensitive semantic action with 3 calls: 179 1. Parse_tree_node() context-independent constructor call, 180 2. contextualize_() function call to evaluate all context-sensitive things 181 from the former context-sensitive semantic action code. 182 3. Call of dummy contextualize() function. 183 184 Then we lift the contextualize() function call to outer grammar rules but 185 save the contextualize_() function call untouched. 186 187 When all loops in the grammar rules are resolved (i.e. transformed 188 as described above) we: 189 a. remove all contextualize_() function calls and 190 b. rename all contextualize_() function definitions to contextualize() 191 function definitions. 192 193 Note: it's not necessary to transform the whole grammar and remove 194 this function calls in one pass: it's possible to transform the 195 grammar statement by statement in a way described above. 196 197 Note: remove this function together with Item::contextualize_(). 198 */ contextualize_(Parse_context * pc)199 virtual bool contextualize_(Parse_context *pc) 200 { 201 #ifndef DBUG_OFF 202 DBUG_ASSERT(!contextualized && !transitional); 203 transitional= true; 204 contextualized= true; 205 #endif//DBUG_OFF 206 return false; 207 } 208 209 void error(Parse_context *pc, 210 const POS &position, 211 const char * msg= NULL) const; 212 }; 213 214 #endif /* PARSE_TREE_NODE_INCLUDED */ 215