1/***************************************************************************** 2 3Copyright (c) 1997, 2018, Oracle and/or its affiliates. All Rights Reserved. 4 5This program is free software; you can redistribute it and/or modify it under 6the terms of the GNU General Public License, version 2.0, as published by the 7Free Software Foundation. 8 9This program is also distributed with certain software (including but not 10limited to OpenSSL) that is licensed under separate terms, as designated in a 11particular file or component or in included license documentation. The authors 12of MySQL hereby grant you an additional permission to link the program and 13your derivative works with the separately licensed software that they have 14included with MySQL. 15 16This program is distributed in the hope that it will be useful, but WITHOUT 17ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS 18FOR A PARTICULAR PURPOSE. See the GNU General Public License, version 2.0, 19for more details. 20 21You should have received a copy of the GNU General Public License along with 22this program; if not, write to the Free Software Foundation, Inc., 2351 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 24 25*****************************************************************************/ 26 27/** @file include/row0sel.ic 28 Select 29 30 Created 12/19/1997 Heikki Tuuri 31 *******************************************************/ 32 33#include "que0que.h" 34 35/** Gets the plan node for the nth table in a join. 36 @return plan node */ 37UNIV_INLINE 38plan_t *sel_node_get_nth_plan(sel_node_t *node, /*!< in: select node */ 39 ulint i) /*!< in: get ith plan node */ 40{ 41 ut_ad(i < node->n_tables); 42 43 return (node->plans + i); 44} 45 46/** Resets the cursor defined by sel_node to the SEL_NODE_OPEN state, which 47 means that it will start fetching from the start of the result set again, 48 regardless of where it was before, and it will set intention locks on the 49 tables. */ 50UNIV_INLINE 51void sel_node_reset_cursor(sel_node_t *node) /*!< in: select node */ 52{ 53 node->state = SEL_NODE_OPEN; 54} 55 56/** Performs an execution step of an open or close cursor statement node. 57 @return query thread to run next or NULL */ 58UNIV_INLINE 59que_thr_t *open_step(que_thr_t *thr) /*!< in: query thread */ 60{ 61 sel_node_t *sel_node; 62 open_node_t *node; 63 ulint err; 64 65 ut_ad(thr); 66 67 node = (open_node_t *)thr->run_node; 68 ut_ad(que_node_get_type(node) == QUE_NODE_OPEN); 69 70 sel_node = node->cursor_def; 71 72 err = DB_SUCCESS; 73 74 if (node->op_type == ROW_SEL_OPEN_CURSOR) { 75 /* if (sel_node->state == SEL_NODE_CLOSED) { */ 76 77 sel_node_reset_cursor(sel_node); 78 /* } else { 79 err = DB_ERROR; 80 } */ 81 } else { 82 if (sel_node->state != SEL_NODE_CLOSED) { 83 sel_node->state = SEL_NODE_CLOSED; 84 } else { 85 err = DB_ERROR; 86 } 87 } 88 89 if (err != DB_SUCCESS) { 90 /* SQL error detected */ 91 fprintf(stderr, "SQL error %lu\n", (ulong)err); 92 93 ut_error; 94 } 95 96 thr->run_node = que_node_get_parent(node); 97 98 return (thr); 99} 100 101/** Searches for rows in the database. This is used in the interface to 102MySQL. This function opens a cursor, and also implements fetch next 103and fetch prev. NOTE that if we do a search with a full key value 104from a unique index (ROW_SEL_EXACT), then we will not store the cursor 105position and fetch next or fetch prev must not be tried to the cursor! 106 107@param[out] buf buffer for the fetched row in MySQL format 108@param[in] mode search mode PAGE_CUR_L 109@param[in,out] prebuilt prebuilt struct for the table handler; 110 this contains the info to search_tuple, 111 index; if search tuple contains 0 field then 112 we position the cursor at start or the end of 113 index, depending on 'mode' 114@param[in] match_mode 0 or ROW_SEL_EXACT or ROW_SEL_EXACT_PREFIX 115@param[in] direction 0 or ROW_SEL_NEXT or ROW_SEL_PREV; 116 Note: if this is != 0, then prebuilt must has a 117 pcur with stored position! In opening of a 118 cursor 'direction' should be 0. 119@return DB_SUCCESS, DB_RECORD_NOT_FOUND, DB_END_OF_INDEX, DB_DEADLOCK, 120DB_LOCK_TABLE_FULL, DB_CORRUPTION, or DB_TOO_BIG_RECORD */ 121UNIV_INLINE 122dberr_t row_search_for_mysql(byte *buf, page_cur_mode_t mode, 123 row_prebuilt_t *prebuilt, ulint match_mode, 124 ulint direction) { 125 if (!prebuilt->table->is_intrinsic()) { 126 return (row_search_mvcc(buf, mode, prebuilt, match_mode, direction)); 127 } else { 128 return (row_search_no_mvcc(buf, mode, prebuilt, match_mode, direction)); 129 } 130} 131