summaryrefslogtreecommitdiff
path: root/storage/innobase/include/row0sel.h
diff options
context:
space:
mode:
Diffstat (limited to 'storage/innobase/include/row0sel.h')
-rw-r--r--storage/innobase/include/row0sel.h348
1 files changed, 348 insertions, 0 deletions
diff --git a/storage/innobase/include/row0sel.h b/storage/innobase/include/row0sel.h
new file mode 100644
index 00000000000..8d5187bfc1c
--- /dev/null
+++ b/storage/innobase/include/row0sel.h
@@ -0,0 +1,348 @@
+/******************************************************
+Select
+
+(c) 1997 Innobase Oy
+
+Created 12/19/1997 Heikki Tuuri
+*******************************************************/
+
+#ifndef row0sel_h
+#define row0sel_h
+
+#include "univ.i"
+#include "data0data.h"
+#include "que0types.h"
+#include "dict0types.h"
+#include "trx0types.h"
+#include "row0types.h"
+#include "que0types.h"
+#include "pars0sym.h"
+#include "btr0pcur.h"
+#include "read0read.h"
+#include "row0mysql.h"
+
+/*************************************************************************
+Creates a select node struct. */
+
+sel_node_t*
+sel_node_create(
+/*============*/
+ /* out, own: select node struct */
+ mem_heap_t* heap); /* in: memory heap where created */
+/*************************************************************************
+Frees the memory private to a select node when a query graph is freed,
+does not free the heap where the node was originally created. */
+
+void
+sel_node_free_private(
+/*==================*/
+ sel_node_t* node); /* in: select node struct */
+/*************************************************************************
+Frees a prefetch buffer for a column, including the dynamically allocated
+memory for data stored there. */
+
+void
+sel_col_prefetch_buf_free(
+/*======================*/
+ sel_buf_t* prefetch_buf); /* in, own: prefetch buffer */
+/*************************************************************************
+Gets the plan node for the nth table in a join. */
+UNIV_INLINE
+plan_t*
+sel_node_get_nth_plan(
+/*==================*/
+ sel_node_t* node,
+ ulint i);
+/**************************************************************************
+Performs a select step. This is a high-level function used in SQL execution
+graphs. */
+
+que_thr_t*
+row_sel_step(
+/*=========*/
+ /* out: query thread to run next or NULL */
+ que_thr_t* thr); /* in: query thread */
+/**************************************************************************
+Performs an execution step of an open or close cursor statement node. */
+UNIV_INLINE
+que_thr_t*
+open_step(
+/*======*/
+ /* out: query thread to run next or NULL */
+ que_thr_t* thr); /* in: query thread */
+/**************************************************************************
+Performs a fetch for a cursor. */
+
+que_thr_t*
+fetch_step(
+/*=======*/
+ /* out: query thread to run next or NULL */
+ que_thr_t* thr); /* in: query thread */
+/***************************************************************
+Prints a row in a select result. */
+
+que_thr_t*
+row_printf_step(
+/*============*/
+ /* out: query thread to run next or NULL */
+ que_thr_t* thr); /* in: query thread */
+/********************************************************************
+Converts a key value stored in MySQL format to an Innobase dtuple. The last
+field of the key value may be just a prefix of a fixed length field: hence
+the parameter key_len. But currently we do not allow search keys where the
+last field is only a prefix of the full key field len and print a warning if
+such appears. */
+
+void
+row_sel_convert_mysql_key_to_innobase(
+/*==================================*/
+ dtuple_t* tuple, /* in: tuple where to build;
+ NOTE: we assume that the type info
+ in the tuple is already according
+ to index! */
+ byte* buf, /* in: buffer to use in field
+ conversions */
+ ulint buf_len, /* in: buffer length */
+ dict_index_t* index, /* in: index of the key value */
+ byte* key_ptr, /* in: MySQL key value */
+ ulint key_len, /* in: MySQL key value length */
+ trx_t* trx); /* in: transaction */
+/************************************************************************
+Searches for rows in the database. This is used in the interface to
+MySQL. This function opens a cursor, and also implements fetch next
+and fetch prev. NOTE that if we do a search with a full key value
+from a unique index (ROW_SEL_EXACT), then we will not store the cursor
+position and fetch next or fetch prev must not be tried to the cursor! */
+
+ulint
+row_search_for_mysql(
+/*=================*/
+ /* out: DB_SUCCESS,
+ DB_RECORD_NOT_FOUND,
+ DB_END_OF_INDEX, DB_DEADLOCK,
+ DB_LOCK_TABLE_FULL,
+ or DB_TOO_BIG_RECORD */
+ byte* buf, /* in/out: buffer for the fetched
+ row in the MySQL format */
+ ulint mode, /* in: search mode PAGE_CUR_L, ... */
+ row_prebuilt_t* prebuilt, /* in: prebuilt struct for the
+ table handle; this contains the info
+ of search_tuple, index; if search
+ tuple contains 0 fields then we
+ position the cursor at the start or
+ the end of the index, depending on
+ 'mode' */
+ ulint match_mode, /* in: 0 or ROW_SEL_EXACT or
+ ROW_SEL_EXACT_PREFIX */
+ ulint direction); /* in: 0 or ROW_SEL_NEXT or
+ ROW_SEL_PREV; NOTE: if this is != 0,
+ then prebuilt must have a pcur
+ with stored position! In opening of a
+ cursor 'direction' should be 0. */
+/***********************************************************************
+Checks if MySQL at the moment is allowed for this table to retrieve a
+consistent read result, or store it to the query cache. */
+
+ibool
+row_search_check_if_query_cache_permitted(
+/*======================================*/
+ /* out: TRUE if storing or retrieving
+ from the query cache is permitted */
+ trx_t* trx, /* in: transaction object */
+ const char* norm_name); /* in: concatenation of database name,
+ '/' char, table name */
+
+
+/* A structure for caching column values for prefetched rows */
+struct sel_buf_struct{
+ byte* data; /* data, or NULL; if not NULL, this field
+ has allocated memory which must be explicitly
+ freed; can be != NULL even when len is
+ UNIV_SQL_NULL */
+ ulint len; /* data length or UNIV_SQL_NULL */
+ ulint val_buf_size;
+ /* size of memory buffer allocated for data:
+ this can be more than len; this is defined
+ when data != NULL */
+};
+
+struct plan_struct{
+ dict_table_t* table; /* table struct in the dictionary
+ cache */
+ dict_index_t* index; /* table index used in the search */
+ btr_pcur_t pcur; /* persistent cursor used to search
+ the index */
+ ibool asc; /* TRUE if cursor traveling upwards */
+ ibool pcur_is_open; /* TRUE if pcur has been positioned
+ and we can try to fetch new rows */
+ ibool cursor_at_end; /* TRUE if the cursor is open but
+ we know that there are no more
+ qualifying rows left to retrieve from
+ the index tree; NOTE though, that
+ there may still be unprocessed rows in
+ the prefetch stack; always FALSE when
+ pcur_is_open is FALSE */
+ ibool stored_cursor_rec_processed;
+ /* TRUE if the pcur position has been
+ stored and the record it is positioned
+ on has already been processed */
+ que_node_t** tuple_exps; /* array of expressions which are used
+ to calculate the field values in the
+ search tuple: there is one expression
+ for each field in the search tuple */
+ dtuple_t* tuple; /* search tuple */
+ ulint mode; /* search mode: PAGE_CUR_G, ... */
+ ulint n_exact_match; /* number of first fields in the search
+ tuple which must be exactly matched */
+ ibool unique_search; /* TRUE if we are searching an
+ index record with a unique key */
+ ulint n_rows_fetched; /* number of rows fetched using pcur
+ after it was opened */
+ ulint n_rows_prefetched;/* number of prefetched rows cached
+ for fetch: fetching several rows in
+ the same mtr saves CPU time */
+ ulint first_prefetched;/* index of the first cached row in
+ select buffer arrays for each column */
+ ibool no_prefetch; /* no prefetch for this table */
+ ibool mixed_index; /* TRUE if index is a clustered index
+ in a mixed cluster */
+ sym_node_list_t columns; /* symbol table nodes for the columns
+ to retrieve from the table */
+ UT_LIST_BASE_NODE_T(func_node_t)
+ end_conds; /* conditions which determine the
+ fetch limit of the index segment we
+ have to look at: when one of these
+ fails, the result set has been
+ exhausted for the cursor in this
+ index; these conditions are normalized
+ so that in a comparison the column
+ for this table is the first argument */
+ UT_LIST_BASE_NODE_T(func_node_t)
+ other_conds; /* the rest of search conditions we can
+ test at this table in a join */
+ ibool must_get_clust; /* TRUE if index is a non-clustered
+ index and we must also fetch the
+ clustered index record; this is the
+ case if the non-clustered record does
+ not contain all the needed columns, or
+ if this is a single-table explicit
+ cursor, or a searched update or
+ delete */
+ ulint* clust_map; /* map telling how clust_ref is built
+ from the fields of a non-clustered
+ record */
+ dtuple_t* clust_ref; /* the reference to the clustered
+ index entry is built here if index is
+ a non-clustered index */
+ btr_pcur_t clust_pcur; /* if index is non-clustered, we use
+ this pcur to search the clustered
+ index */
+ mem_heap_t* old_vers_heap; /* memory heap used in building an old
+ version of a row, or NULL */
+};
+
+struct sel_node_struct{
+ que_common_t common; /* node type: QUE_NODE_SELECT */
+ ulint state; /* node state */
+ que_node_t* select_list; /* select list */
+ sym_node_t* into_list; /* variables list or NULL */
+ sym_node_t* table_list; /* table list */
+ ibool asc; /* TRUE if the rows should be fetched
+ in an ascending order */
+ ibool set_x_locks; /* TRUE if the cursor is for update or
+ delete, which means that a row x-lock
+ should be placed on the cursor row */
+ ibool select_will_do_update;
+ /* TRUE if the select is for a searched
+ update which can be performed in-place:
+ in this case the select will take care
+ of the update */
+ ulint latch_mode; /* BTR_SEARCH_LEAF, or BTR_MODIFY_LEAF
+ if select_will_do_update is TRUE */
+ ulint row_lock_mode; /* LOCK_X or LOCK_S */
+ ulint n_tables; /* number of tables */
+ ulint fetch_table; /* number of the next table to access
+ in the join */
+ plan_t* plans; /* array of n_tables many plan nodes
+ containing the search plan and the
+ search data structures */
+ que_node_t* search_cond; /* search condition */
+ read_view_t* read_view; /* if the query is a non-locking
+ consistent read, its read view is
+ placed here, otherwise NULL */
+ ibool consistent_read;/* TRUE if the select is a consistent,
+ non-locking read */
+ order_node_t* order_by; /* order by column definition, or
+ NULL */
+ ibool is_aggregate; /* TRUE if the select list consists of
+ aggregate functions */
+ ibool aggregate_already_fetched;
+ /* TRUE if the aggregate row has
+ already been fetched for the current
+ cursor */
+ ibool can_get_updated;/* this is TRUE if the select is in a
+ single-table explicit cursor which can
+ get updated within the stored procedure,
+ or in a searched update or delete;
+ NOTE that to determine of an explicit
+ cursor if it can get updated, the
+ parser checks from a stored procedure
+ if it contains positioned update or
+ delete statements */
+ sym_node_t* explicit_cursor;/* not NULL if an explicit cursor */
+ UT_LIST_BASE_NODE_T(sym_node_t)
+ copy_variables; /* variables whose values we have to
+ copy when an explicit cursor is opened,
+ so that they do not change between
+ fetches */
+};
+
+/* Select node states */
+#define SEL_NODE_CLOSED 0 /* it is a declared cursor which is not
+ currently open */
+#define SEL_NODE_OPEN 1 /* intention locks not yet set on
+ tables */
+#define SEL_NODE_FETCH 2 /* intention locks have been set */
+#define SEL_NODE_NO_MORE_ROWS 3 /* cursor has reached the result set
+ end */
+
+/* Fetch statement node */
+struct fetch_node_struct{
+ que_common_t common; /* type: QUE_NODE_FETCH */
+ sel_node_t* cursor_def; /* cursor definition */
+ sym_node_t* into_list; /* variables to set */
+};
+
+/* Open or close cursor statement node */
+struct open_node_struct{
+ que_common_t common; /* type: QUE_NODE_OPEN */
+ ulint op_type; /* ROW_SEL_OPEN_CURSOR or
+ ROW_SEL_CLOSE_CURSOR */
+ sel_node_t* cursor_def; /* cursor definition */
+};
+
+/* Row printf statement node */
+struct row_printf_node_struct{
+ que_common_t common; /* type: QUE_NODE_ROW_PRINTF */
+ sel_node_t* sel_node; /* select */
+};
+
+#define ROW_SEL_OPEN_CURSOR 0
+#define ROW_SEL_CLOSE_CURSOR 1
+
+/* Flags for the MySQL interface */
+#define ROW_SEL_NEXT 1
+#define ROW_SEL_PREV 2
+
+#define ROW_SEL_EXACT 1 /* search using a complete key value */
+#define ROW_SEL_EXACT_PREFIX 2 /* search using a key prefix which
+ must match to rows: the prefix may
+ contain an incomplete field (the
+ last field in prefix may be just
+ a prefix of a fixed length column) */
+
+#ifndef UNIV_NONINL
+#include "row0sel.ic"
+#endif
+
+#endif