00001 /****************************************************** 00002 Select 00003 00004 (c) 1997 Innobase Oy 00005 00006 Created 12/19/1997 Heikki Tuuri 00007 *******************************************************/ 00008 00009 #ifndef row0sel_h 00010 #define row0sel_h 00011 00012 #include "univ.i" 00013 #include "data0data.h" 00014 #include "que0types.h" 00015 #include "dict0types.h" 00016 #include "trx0types.h" 00017 #include "row0types.h" 00018 #include "que0types.h" 00019 #include "pars0sym.h" 00020 #include "btr0pcur.h" 00021 #include "read0read.h" 00022 #include "row0mysql.h" 00023 00024 /************************************************************************* 00025 Creates a select node struct. */ 00026 00027 sel_node_t* 00028 sel_node_create( 00029 /*============*/ 00030 /* out, own: select node struct */ 00031 mem_heap_t* heap); /* in: memory heap where created */ 00032 /************************************************************************* 00033 Frees the memory private to a select node when a query graph is freed, 00034 does not free the heap where the node was originally created. */ 00035 00036 void 00037 sel_node_free_private( 00038 /*==================*/ 00039 sel_node_t* node); /* in: select node struct */ 00040 /************************************************************************* 00041 Frees a prefetch buffer for a column, including the dynamically allocated 00042 memory for data stored there. */ 00043 00044 void 00045 sel_col_prefetch_buf_free( 00046 /*======================*/ 00047 sel_buf_t* prefetch_buf); /* in, own: prefetch buffer */ 00048 /************************************************************************* 00049 Gets the plan node for the nth table in a join. */ 00050 UNIV_INLINE 00051 plan_t* 00052 sel_node_get_nth_plan( 00053 /*==================*/ 00054 sel_node_t* node, 00055 ulint i); 00056 /************************************************************************** 00057 Performs a select step. This is a high-level function used in SQL execution 00058 graphs. */ 00059 00060 que_thr_t* 00061 row_sel_step( 00062 /*=========*/ 00063 /* out: query thread to run next or NULL */ 00064 que_thr_t* thr); /* in: query thread */ 00065 /************************************************************************** 00066 Performs an execution step of an open or close cursor statement node. */ 00067 UNIV_INLINE 00068 que_thr_t* 00069 open_step( 00070 /*======*/ 00071 /* out: query thread to run next or NULL */ 00072 que_thr_t* thr); /* in: query thread */ 00073 /************************************************************************** 00074 Performs a fetch for a cursor. */ 00075 00076 que_thr_t* 00077 fetch_step( 00078 /*=======*/ 00079 /* out: query thread to run next or NULL */ 00080 que_thr_t* thr); /* in: query thread */ 00081 /******************************************************************** 00082 Sample callback function for fetch that prints each row.*/ 00083 00084 void* 00085 row_fetch_print( 00086 /*============*/ 00087 /* out: always returns non-NULL */ 00088 void* row, /* in: sel_node_t* */ 00089 void* user_arg); /* in: not used */ 00090 /******************************************************************** 00091 Callback function for fetch that stores an unsigned 4 byte integer to the 00092 location pointed. The column's type must be DATA_INT, DATA_UNSIGNED, length 00093 = 4. */ 00094 00095 void* 00096 row_fetch_store_uint4( 00097 /*==================*/ 00098 /* out: always returns NULL */ 00099 void* row, /* in: sel_node_t* */ 00100 void* user_arg); /* in: data pointer */ 00101 /*************************************************************** 00102 Prints a row in a select result. */ 00103 00104 que_thr_t* 00105 row_printf_step( 00106 /*============*/ 00107 /* out: query thread to run next or NULL */ 00108 que_thr_t* thr); /* in: query thread */ 00109 /******************************************************************** 00110 Converts a key value stored in MySQL format to an Innobase dtuple. The last 00111 field of the key value may be just a prefix of a fixed length field: hence 00112 the parameter key_len. But currently we do not allow search keys where the 00113 last field is only a prefix of the full key field len and print a warning if 00114 such appears. */ 00115 00116 void 00117 row_sel_convert_mysql_key_to_innobase( 00118 /*==================================*/ 00119 dtuple_t* tuple, /* in: tuple where to build; 00120 NOTE: we assume that the type info 00121 in the tuple is already according 00122 to index! */ 00123 byte* buf, /* in: buffer to use in field 00124 conversions */ 00125 ulint buf_len, /* in: buffer length */ 00126 dict_index_t* index, /* in: index of the key value */ 00127 byte* key_ptr, /* in: MySQL key value */ 00128 ulint key_len, /* in: MySQL key value length */ 00129 trx_t* trx); /* in: transaction */ 00130 /************************************************************************ 00131 Searches for rows in the database. This is used in the interface to 00132 MySQL. This function opens a cursor, and also implements fetch next 00133 and fetch prev. NOTE that if we do a search with a full key value 00134 from a unique index (ROW_SEL_EXACT), then we will not store the cursor 00135 position and fetch next or fetch prev must not be tried to the cursor! */ 00136 00137 ulint 00138 row_search_for_mysql( 00139 /*=================*/ 00140 /* out: DB_SUCCESS, 00141 DB_RECORD_NOT_FOUND, 00142 DB_END_OF_INDEX, DB_DEADLOCK, 00143 DB_LOCK_TABLE_FULL, 00144 or DB_TOO_BIG_RECORD */ 00145 byte* buf, /* in/out: buffer for the fetched 00146 row in the MySQL format */ 00147 ulint mode, /* in: search mode PAGE_CUR_L, ... */ 00148 row_prebuilt_t* prebuilt, /* in: prebuilt struct for the 00149 table handle; this contains the info 00150 of search_tuple, index; if search 00151 tuple contains 0 fields then we 00152 position the cursor at the start or 00153 the end of the index, depending on 00154 'mode' */ 00155 ulint match_mode, /* in: 0 or ROW_SEL_EXACT or 00156 ROW_SEL_EXACT_PREFIX */ 00157 ulint direction); /* in: 0 or ROW_SEL_NEXT or 00158 ROW_SEL_PREV; NOTE: if this is != 0, 00159 then prebuilt must have a pcur 00160 with stored position! In opening of a 00161 cursor 'direction' should be 0. */ 00162 /*********************************************************************** 00163 Checks if MySQL at the moment is allowed for this table to retrieve a 00164 consistent read result, or store it to the query cache. */ 00165 00166 ibool 00167 row_search_check_if_query_cache_permitted( 00168 /*======================================*/ 00169 /* out: TRUE if storing or retrieving 00170 from the query cache is permitted */ 00171 trx_t* trx, /* in: transaction object */ 00172 const char* norm_name); /* in: concatenation of database name, 00173 '/' char, table name */ 00174 00175 00176 /* A structure for caching column values for prefetched rows */ 00177 struct sel_buf_struct{ 00178 byte* data; /* data, or NULL; if not NULL, this field 00179 has allocated memory which must be explicitly 00180 freed; can be != NULL even when len is 00181 UNIV_SQL_NULL */ 00182 ulint len; /* data length or UNIV_SQL_NULL */ 00183 ulint val_buf_size; 00184 /* size of memory buffer allocated for data: 00185 this can be more than len; this is defined 00186 when data != NULL */ 00187 }; 00188 00189 struct plan_struct{ 00190 dict_table_t* table; /* table struct in the dictionary 00191 cache */ 00192 dict_index_t* index; /* table index used in the search */ 00193 btr_pcur_t pcur; /* persistent cursor used to search 00194 the index */ 00195 ibool asc; /* TRUE if cursor traveling upwards */ 00196 ibool pcur_is_open; /* TRUE if pcur has been positioned 00197 and we can try to fetch new rows */ 00198 ibool cursor_at_end; /* TRUE if the cursor is open but 00199 we know that there are no more 00200 qualifying rows left to retrieve from 00201 the index tree; NOTE though, that 00202 there may still be unprocessed rows in 00203 the prefetch stack; always FALSE when 00204 pcur_is_open is FALSE */ 00205 ibool stored_cursor_rec_processed; 00206 /* TRUE if the pcur position has been 00207 stored and the record it is positioned 00208 on has already been processed */ 00209 que_node_t** tuple_exps; /* array of expressions which are used 00210 to calculate the field values in the 00211 search tuple: there is one expression 00212 for each field in the search tuple */ 00213 dtuple_t* tuple; /* search tuple */ 00214 ulint mode; /* search mode: PAGE_CUR_G, ... */ 00215 ulint n_exact_match; /* number of first fields in the search 00216 tuple which must be exactly matched */ 00217 ibool unique_search; /* TRUE if we are searching an 00218 index record with a unique key */ 00219 ulint n_rows_fetched; /* number of rows fetched using pcur 00220 after it was opened */ 00221 ulint n_rows_prefetched;/* number of prefetched rows cached 00222 for fetch: fetching several rows in 00223 the same mtr saves CPU time */ 00224 ulint first_prefetched;/* index of the first cached row in 00225 select buffer arrays for each column */ 00226 ibool no_prefetch; /* no prefetch for this table */ 00227 sym_node_list_t columns; /* symbol table nodes for the columns 00228 to retrieve from the table */ 00229 UT_LIST_BASE_NODE_T(func_node_t) 00230 end_conds; /* conditions which determine the 00231 fetch limit of the index segment we 00232 have to look at: when one of these 00233 fails, the result set has been 00234 exhausted for the cursor in this 00235 index; these conditions are normalized 00236 so that in a comparison the column 00237 for this table is the first argument */ 00238 UT_LIST_BASE_NODE_T(func_node_t) 00239 other_conds; /* the rest of search conditions we can 00240 test at this table in a join */ 00241 ibool must_get_clust; /* TRUE if index is a non-clustered 00242 index and we must also fetch the 00243 clustered index record; this is the 00244 case if the non-clustered record does 00245 not contain all the needed columns, or 00246 if this is a single-table explicit 00247 cursor, or a searched update or 00248 delete */ 00249 ulint* clust_map; /* map telling how clust_ref is built 00250 from the fields of a non-clustered 00251 record */ 00252 dtuple_t* clust_ref; /* the reference to the clustered 00253 index entry is built here if index is 00254 a non-clustered index */ 00255 btr_pcur_t clust_pcur; /* if index is non-clustered, we use 00256 this pcur to search the clustered 00257 index */ 00258 mem_heap_t* old_vers_heap; /* memory heap used in building an old 00259 version of a row, or NULL */ 00260 }; 00261 00262 struct sel_node_struct{ 00263 que_common_t common; /* node type: QUE_NODE_SELECT */ 00264 ulint state; /* node state */ 00265 que_node_t* select_list; /* select list */ 00266 sym_node_t* into_list; /* variables list or NULL */ 00267 sym_node_t* table_list; /* table list */ 00268 ibool asc; /* TRUE if the rows should be fetched 00269 in an ascending order */ 00270 ibool set_x_locks; /* TRUE if the cursor is for update or 00271 delete, which means that a row x-lock 00272 should be placed on the cursor row */ 00273 ibool select_will_do_update; 00274 /* TRUE if the select is for a searched 00275 update which can be performed in-place: 00276 in this case the select will take care 00277 of the update */ 00278 ulint latch_mode; /* BTR_SEARCH_LEAF, or BTR_MODIFY_LEAF 00279 if select_will_do_update is TRUE */ 00280 ulint row_lock_mode; /* LOCK_X or LOCK_S */ 00281 ulint n_tables; /* number of tables */ 00282 ulint fetch_table; /* number of the next table to access 00283 in the join */ 00284 plan_t* plans; /* array of n_tables many plan nodes 00285 containing the search plan and the 00286 search data structures */ 00287 que_node_t* search_cond; /* search condition */ 00288 read_view_t* read_view; /* if the query is a non-locking 00289 consistent read, its read view is 00290 placed here, otherwise NULL */ 00291 ibool consistent_read;/* TRUE if the select is a consistent, 00292 non-locking read */ 00293 order_node_t* order_by; /* order by column definition, or 00294 NULL */ 00295 ibool is_aggregate; /* TRUE if the select list consists of 00296 aggregate functions */ 00297 ibool aggregate_already_fetched; 00298 /* TRUE if the aggregate row has 00299 already been fetched for the current 00300 cursor */ 00301 ibool can_get_updated;/* this is TRUE if the select is in a 00302 single-table explicit cursor which can 00303 get updated within the stored procedure, 00304 or in a searched update or delete; 00305 NOTE that to determine of an explicit 00306 cursor if it can get updated, the 00307 parser checks from a stored procedure 00308 if it contains positioned update or 00309 delete statements */ 00310 sym_node_t* explicit_cursor;/* not NULL if an explicit cursor */ 00311 UT_LIST_BASE_NODE_T(sym_node_t) 00312 copy_variables; /* variables whose values we have to 00313 copy when an explicit cursor is opened, 00314 so that they do not change between 00315 fetches */ 00316 }; 00317 00318 /* Select node states */ 00319 #define SEL_NODE_CLOSED 0 /* it is a declared cursor which is not 00320 currently open */ 00321 #define SEL_NODE_OPEN 1 /* intention locks not yet set on 00322 tables */ 00323 #define SEL_NODE_FETCH 2 /* intention locks have been set */ 00324 #define SEL_NODE_NO_MORE_ROWS 3 /* cursor has reached the result set 00325 end */ 00326 00327 /* Fetch statement node */ 00328 struct fetch_node_struct{ 00329 que_common_t common; /* type: QUE_NODE_FETCH */ 00330 sel_node_t* cursor_def; /* cursor definition */ 00331 sym_node_t* into_list; /* variables to set */ 00332 00333 pars_user_func_t* 00334 func; /* User callback function or NULL. 00335 The first argument to the function 00336 is a sel_node_t*, containing the 00337 results of the SELECT operation for 00338 one row. If the function returns 00339 NULL, it is not interested in 00340 further rows and the cursor is 00341 modified so (cursor % NOTFOUND) is 00342 true. If it returns not-NULL, 00343 continue normally. See 00344 row_fetch_print() for an example 00345 (and a useful debugging tool). */ 00346 }; 00347 00348 /* Open or close cursor statement node */ 00349 struct open_node_struct{ 00350 que_common_t common; /* type: QUE_NODE_OPEN */ 00351 ulint op_type; /* ROW_SEL_OPEN_CURSOR or 00352 ROW_SEL_CLOSE_CURSOR */ 00353 sel_node_t* cursor_def; /* cursor definition */ 00354 }; 00355 00356 /* Row printf statement node */ 00357 struct row_printf_node_struct{ 00358 que_common_t common; /* type: QUE_NODE_ROW_PRINTF */ 00359 sel_node_t* sel_node; /* select */ 00360 }; 00361 00362 #define ROW_SEL_OPEN_CURSOR 0 00363 #define ROW_SEL_CLOSE_CURSOR 1 00364 00365 /* Flags for the MySQL interface */ 00366 #define ROW_SEL_NEXT 1 00367 #define ROW_SEL_PREV 2 00368 00369 #define ROW_SEL_EXACT 1 /* search using a complete key value */ 00370 #define ROW_SEL_EXACT_PREFIX 2 /* search using a key prefix which 00371 must match to rows: the prefix may 00372 contain an incomplete field (the 00373 last field in prefix may be just 00374 a prefix of a fixed length column) */ 00375 00376 #ifndef UNIV_NONINL 00377 #include "row0sel.ic" 00378 #endif 00379 00380 #endif
1.4.7

