1 /* Copyright (c) 2017, 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 TABLE_FUNCTION_INCLUDED 24 #define TABLE_FUNCTION_INCLUDED 25 26 #include <sys/types.h> 27 #include <array> // std::array 28 29 #include "my_dbug.h" 30 #include "my_inttypes.h" 31 #include "my_table_map.h" 32 #include "sql/create_field.h" 33 #include "sql/enum_query_type.h" 34 #include "sql/json_dom.h" // Json_wrapper 35 #include "sql/json_path.h" // Json_path 36 #include "sql/mem_root_array.h" 37 #include "sql/psi_memory_key.h" // key_memory_JSON 38 #include "sql/sql_const.h" // Item_processor, enum_walk 39 #include "sql/sql_list.h" // List 40 #include "sql/table.h" // TABLE 41 42 class Field; 43 class Item; 44 class String; 45 class Table_function_json; 46 class THD; 47 48 /** 49 Class representing a table function. 50 */ 51 52 class Table_function { 53 protected: 54 /// Thread handler 55 THD *thd; 56 /// Table function's result table 57 TABLE *table; 58 /// Whether the table funciton was already initialized 59 bool inited; 60 61 public: Table_function(THD * thd_arg)62 explicit Table_function(THD *thd_arg) 63 : thd(thd_arg), table(nullptr), inited(false) {} 64 ~Table_function()65 virtual ~Table_function() {} 66 /** 67 Create, but not instantiate the result table 68 69 @param options options to create table 70 @param table_alias table's alias 71 72 @returns 73 true on error 74 false on success 75 */ 76 bool create_result_table(ulonglong options, const char *table_alias); 77 /** 78 Write current record to the result table and handle overflow to disk 79 80 @returns 81 true on error 82 false on success 83 */ 84 bool write_row(); 85 86 /** 87 Returns a field with given index 88 89 @param i field's index 90 91 @returns 92 field with given index 93 */ get_field(uint i)94 Field *get_field(uint i) { 95 DBUG_ASSERT(i < table->s->fields); 96 return table->field[i]; 97 } 98 /** 99 Delete all rows in the table 100 */ 101 void empty_table(); 102 103 /** 104 Set the default row 105 */ default_row()106 void default_row() {} 107 /** 108 Initialize table function 109 @returns 110 true on error 111 false on success 112 */ 113 virtual bool init() = 0; 114 /** 115 Initialize table function after the result table has been created 116 @returns 117 true on error 118 false on success 119 */ 120 virtual bool init_args(); 121 /** 122 Execute the table function - fill the result table 123 @returns 124 true on error 125 false on success 126 */ 127 virtual bool fill_result_table() = 0; 128 /** 129 Returns table function's name 130 */ 131 virtual const char *func_name() const = 0; 132 /** 133 Return table_map of tables used by the function 134 */ used_tables()135 virtual table_map used_tables() { return 0; } 136 /** 137 Print table function 138 139 @param str string to print to 140 @param query_type type of the query 141 142 @returns 143 true on error 144 false on success 145 */ 146 virtual bool print(String *str, enum_query_type query_type) const = 0; 147 /** 148 Clean up table function 149 */ cleanup()150 void cleanup() { 151 do_cleanup(); 152 table = nullptr; 153 inited = false; 154 } 155 156 virtual bool walk(Item_processor processor, enum_walk walk, uchar *arg) = 0; 157 158 private: 159 /** 160 Get the list of fields to create the result table 161 */ 162 virtual List<Create_field> *get_field_list() = 0; 163 /** 164 Initialize table function's arguments 165 166 @returns 167 true on error 168 false on success 169 */ 170 virtual bool do_init_args() = 0; 171 friend bool TABLE_LIST::setup_table_function(THD *thd); do_cleanup()172 virtual void do_cleanup() {} 173 }; 174 175 /**************************************************************************** 176 JSON_TABLE function 177 ****************************************************************************/ 178 179 /// Type of columns for JSON_TABLE function 180 enum class enum_jt_column { 181 JTC_ORDINALITY, 182 JTC_PATH, 183 JTC_EXISTS, 184 JTC_NESTED_PATH 185 }; 186 187 /// Types of ON EMPTY/ON ERROR clauses for JSON_TABLE and JSON_VALUE. 188 /// @note uint16 enum base limitation is necessary for YYSTYPE. 189 enum class Json_on_response_type : uint16 { 190 ERROR, 191 NULL_VALUE, 192 DEFAULT, 193 IMPLICIT 194 }; 195 196 /** 197 JT_data_source is used as a data source. It's assigned to each NESTED PATH 198 node. 199 */ 200 201 class JT_data_source { 202 public: 203 /// Vector of found values 204 Json_wrapper_vector v; 205 /// Iterator for vector above 206 Json_wrapper_vector::iterator it; 207 /// JSON data to seek columns' paths in 208 Json_wrapper jdata; 209 /// Current m_rowid, used for ORDINALITY columns 210 uint m_rowid; 211 /** 212 true <=> NESTED PATH associated with this element is producing records. 213 Used to turn off (set to null) sibling NESTED PATHs, when one of them is 214 used to fill result table. 215 */ 216 bool producing_records; 217 JT_data_source()218 JT_data_source() : v(key_memory_JSON), producing_records(false) {} ~JT_data_source()219 ~JT_data_source() {} 220 221 void cleanup(); 222 }; 223 224 /** 225 Reason for skipping a NESTED PATH 226 */ 227 enum jt_skip_reason { 228 JTS_NONE = 0, // NESTED PATH isn't skipped 229 JTS_EOD, // No more data 230 JTS_SIBLING // Skipped due to other sibling NESTED PATH is running 231 }; 232 233 /// Column description for JSON_TABLE function 234 class Json_table_column : public Create_field { 235 public: 236 /// Column type 237 enum_jt_column m_jtc_type; 238 /// Type of ON ERROR clause 239 Json_on_response_type m_on_error{Json_on_response_type::IMPLICIT}; 240 /// Type of ON EMPTY clause 241 Json_on_response_type m_on_empty{Json_on_response_type::IMPLICIT}; 242 /// Default value string for ON EMPTY clause 243 Item *m_default_empty_string{nullptr}; 244 /// Parsed JSON for default value of ON MISSING clause 245 Json_wrapper m_default_empty_json; 246 /// Default value string for ON ERROR clause 247 Item *m_default_error_string{nullptr}; 248 /// Parsed JSON string for ON ERROR clause 249 Json_wrapper m_default_error_json; 250 /// List of nested columns, valid only for NESTED PATH 251 List<Json_table_column> *m_nested_columns{nullptr}; 252 /// Nested path 253 Item *m_path_string{nullptr}; 254 /// parsed nested path 255 Json_path m_path_json; 256 /// An element in table function's data source array 257 JT_data_source *m_jds_elt{nullptr}; 258 /** 259 Element in table function's data source array to feed data to child 260 nodes. Valid only for NESTED PATH. 261 */ 262 JT_data_source *m_child_jds_elt{nullptr}; 263 /// Next sibling NESTED PATH 264 Json_table_column *m_next_nested{nullptr}; 265 /// Previous sibling NESTED PATH 266 Json_table_column *m_prev_nested{nullptr}; 267 /// Index of field in the result table 268 int m_field_idx{-1}; 269 270 public: Json_table_column(enum_jt_column type)271 explicit Json_table_column(enum_jt_column type) : m_jtc_type(type) {} Json_table_column(enum_jt_column col_type,Item * path,Json_on_response_type on_err,Item * error_default,Json_on_response_type on_miss,Item * missing_default)272 Json_table_column(enum_jt_column col_type, Item *path, 273 Json_on_response_type on_err, Item *error_default, 274 Json_on_response_type on_miss, Item *missing_default) 275 : m_jtc_type(col_type), 276 m_on_error(on_err), 277 m_on_empty(on_miss), 278 m_default_empty_string(missing_default), 279 m_default_error_string(error_default), 280 m_path_string(path) {} Json_table_column(Item * path,List<Json_table_column> * cols)281 Json_table_column(Item *path, List<Json_table_column> *cols) 282 : m_jtc_type(enum_jt_column::JTC_NESTED_PATH), 283 m_nested_columns(cols), 284 m_path_string(path) {} 285 void cleanup(); 286 287 /** 288 Process JSON_TABLE's column 289 290 @param table_function the JSON table function 291 @param[out] skip whether current NESTED PATH column should be 292 completely skipped 293 @returns 294 true on error 295 false on success 296 */ 297 bool fill_column(Table_function_json *table_function, jt_skip_reason *skip); 298 }; 299 300 #define MAX_NESTED_PATH 16 301 302 class Table_function_json final : public Table_function { 303 /// Array of JSON Data Source for each NESTED PATH clause 304 std::array<JT_data_source, MAX_NESTED_PATH> m_jds; 305 /// List of fields for tmp table creation 306 List<Json_table_column> m_vt_list; 307 /// Tree of COLUMN clauses 308 List<Json_table_column> *m_columns; 309 /// Array of all columns - the flattened tree above 310 Mem_root_array<Json_table_column *> m_all_columns; 311 /// JSON_TABLE's alias, for error reporting 312 const char *m_table_alias; 313 314 /** Whether source data has been parsed. */ 315 bool is_source_parsed; 316 /// JSON_TABLE's data source expression 317 Item *source; 318 319 public: 320 Table_function_json(THD *thd_arg, const char *alias, Item *a, 321 List<Json_table_column> *cols); 322 323 /** 324 Returns function's name 325 */ func_name()326 const char *func_name() const override { return "json_table"; } 327 /** 328 Initialize the table function before creation of result table 329 330 @returns 331 true on error 332 false on success 333 */ 334 bool init() override; 335 336 /** 337 Execute table function 338 339 @returns 340 true on error 341 false on success 342 */ 343 bool fill_result_table() override; 344 345 /** 346 Return table_map of tables used by function's data source 347 */ 348 table_map used_tables() override; 349 350 /** 351 JSON_TABLE printout 352 353 @param str string to print to 354 @param query_type type of query 355 356 @returns 357 true on error 358 false on success 359 */ 360 bool print(String *str, enum_query_type query_type) const override; 361 362 bool walk(Item_processor processor, enum_walk walk, uchar *arg) override; 363 364 private: 365 /** 366 Fill the result table 367 368 @returns 369 true on error 370 false on success 371 */ 372 bool fill_json_table(); 373 374 /** 375 Prepare lists used to create tmp table and function execution 376 377 @param nest_idx index of parent's element in the nesting data array 378 @param parent Parent of the NESTED PATH clause being initialized 379 380 @returns 381 true on error 382 false on success 383 */ 384 bool init_json_table_col_lists(uint *nest_idx, Json_table_column *parent); 385 /** 386 Set all underlying columns of a NESTED PATH to nullptr 387 388 @param root root NESTED PATH column 389 @param [out] last last column which belongs to the given NESTED PATH 390 */ 391 void set_subtree_to_null(Json_table_column *root, Json_table_column **last); 392 393 /** 394 Return list of fields to create result table from 395 */ 396 List<Create_field> *get_field_list() override; 397 bool do_init_args() override; 398 void do_cleanup() override; 399 }; 400 401 /** 402 Print ON EMPTY or ON ERROR clauses. 403 404 @param thd thread handler 405 @param str the string to print to 406 @param query_type formatting options 407 @param on_empty true for ON EMPTY, false for ON ERROR 408 @param response_type the type of the ON ERROR/ON EMPTY response 409 @param default_string the default string in case of DEFAULT type 410 */ 411 void print_on_empty_or_error(const THD *thd, String *str, 412 enum_query_type query_type, bool on_empty, 413 Json_on_response_type response_type, 414 const Item *default_string); 415 #endif /* TABLE_FUNCTION_INCLUDED */ 416