/****************************************************** Query graph (c) 1996 Innobase Oy Created 5/27/1996 Heikki Tuuri *******************************************************/ #ifndef que0que_h #define que0que_h #include "univ.i" #include "data0data.h" #include "dict0types.h" #include "trx0trx.h" #include "srv0srv.h" #include "usr0types.h" #include "que0types.h" #include "row0types.h" #include "pars0types.h" /* If the following flag is set TRUE, the module will print trace info of SQL execution in the UNIV_SQL_DEBUG version */ extern ibool que_trace_on; /*************************************************************************** Adds a query graph to the session's list of graphs. */ void que_graph_publish( /*==============*/ que_t* graph, /* in: graph */ sess_t* sess); /* in: session */ /*************************************************************************** Creates a query graph fork node. */ que_fork_t* que_fork_create( /*============*/ /* out, own: fork node */ que_t* graph, /* in: graph, if NULL then this fork node is assumed to be the graph root */ que_node_t* parent, /* in: parent node */ ulint fork_type, /* in: fork type */ mem_heap_t* heap); /* in: memory heap where created */ /*************************************************************************** Gets the first thr in a fork. */ UNIV_INLINE que_thr_t* que_fork_get_first_thr( /*===================*/ que_fork_t* fork); /* in: query fork */ /*************************************************************************** Gets the child node of the first thr in a fork. */ UNIV_INLINE que_node_t* que_fork_get_child( /*===============*/ que_fork_t* fork); /* in: query fork */ /*************************************************************************** Sets the parent of a graph node. */ UNIV_INLINE void que_node_set_parent( /*================*/ que_node_t* node, /* in: graph node */ que_node_t* parent);/* in: parent */ /*************************************************************************** Creates a query graph thread node. */ que_thr_t* que_thr_create( /*===========*/ /* out, own: query thread node */ que_fork_t* parent, /* in: parent node, i.e., a fork node */ mem_heap_t* heap); /* in: memory heap where created */ /************************************************************************** Checks if the query graph is in a state where it should be freed, and frees it in that case. If the session is in a state where it should be closed, also this is done. */ ibool que_graph_try_free( /*===============*/ /* out: TRUE if freed */ que_t* graph); /* in: query graph */ /************************************************************************** Frees a query graph, but not the heap where it was created. Does not free explicit cursor declarations, they are freed in que_graph_free. */ void que_graph_free_recursive( /*=====================*/ que_node_t* node); /* in: query graph node */ /************************************************************************** Frees a query graph. */ void que_graph_free( /*===========*/ que_t* graph); /* in: query graph; we assume that the memory heap where this graph was created is private to this graph: if not, then use que_graph_free_recursive and free the heap afterwards! */ /************************************************************************** Stops a query thread if graph or trx is in a state requiring it. The conditions are tested in the order (1) graph, (2) trx. The kernel mutex has to be reserved. */ ibool que_thr_stop( /*=========*/ /* out: TRUE if stopped */ que_thr_t* thr); /* in: query thread */ /************************************************************************** Moves a thread from another state to the QUE_THR_RUNNING state. Increments the n_active_thrs counters of the query graph and transaction. */ void que_thr_move_to_run_state_for_mysql( /*================================*/ que_thr_t* thr, /* in: an query thread */ trx_t* trx); /* in: transaction */ /************************************************************************** A patch for MySQL used to 'stop' a dummy query thread used in MySQL select, when there is no error or lock wait. */ void que_thr_stop_for_mysql_no_error( /*============================*/ que_thr_t* thr, /* in: query thread */ trx_t* trx); /* in: transaction */ /************************************************************************** A patch for MySQL used to 'stop' a dummy query thread used in MySQL select. */ void que_thr_stop_for_mysql( /*===================*/ que_thr_t* thr); /* in: query thread */ /************************************************************************** Runs query threads. Note that the individual query thread which is run within this function may change if, e.g., the OS thread executing this function uses a threshold amount of resources. */ void que_run_threads( /*============*/ que_thr_t* thr); /* in: query thread which is run initially */ /************************************************************************** After signal handling is finished, returns control to a query graph error handling routine. (Currently, just returns the control to the root of the graph so that the graph can communicate an error message to the client.) */ void que_fork_error_handle( /*==================*/ trx_t* trx, /* in: trx */ que_t* fork); /* in: query graph which was run before signal handling started, NULL not allowed */ /************************************************************************** Handles an SQL error noticed during query thread execution. At the moment, does nothing! */ void que_thr_handle_error( /*=================*/ que_thr_t* thr, /* in: query thread */ ulint err_no, /* in: error number */ byte* err_str,/* in, own: error string or NULL; NOTE: the function will take care of freeing of the string! */ ulint err_len);/* in: error string length */ /************************************************************************** Moves a suspended query thread to the QUE_THR_RUNNING state and releases a single worker thread to execute it. This function should be used to end the wait state of a query thread waiting for a lock or a stored procedure completion. */ void que_thr_end_wait( /*=============*/ que_thr_t* thr, /* in: query thread in the QUE_THR_LOCK_WAIT, or QUE_THR_PROCEDURE_WAIT, or QUE_THR_SIG_REPLY_WAIT state */ que_thr_t** next_thr); /* in/out: next query thread to run; if the value which is passed in is a pointer to a NULL pointer, then the calling function can start running a new query thread */ /************************************************************************** Same as que_thr_end_wait, but no parameter next_thr available. */ void que_thr_end_wait_no_next_thr( /*=========================*/ que_thr_t* thr); /* in: query thread in the QUE_THR_LOCK_WAIT, or QUE_THR_PROCEDURE_WAIT, or QUE_THR_SIG_REPLY_WAIT state */ /************************************************************************** Starts execution of a command in a query fork. Picks a query thread which is not in the QUE_THR_RUNNING state and moves it to that state. If none can be chosen, a situation which may arise in parallelized fetches, NULL is returned. */ que_thr_t* que_fork_start_command( /*===================*/ /* out: a query thread of the graph moved to QUE_THR_RUNNING state, or NULL; the query thread should be executed by que_run_threads by the caller */ que_fork_t* fork, /* in: a query fork */ ulint command,/* in: command SESS_COMM_FETCH_NEXT, ... */ ulint param); /* in: possible parameter to the command */ /*************************************************************************** Gets the trx of a query thread. */ UNIV_INLINE trx_t* thr_get_trx( /*========*/ que_thr_t* thr); /* in: query thread */ /*************************************************************************** Gets the type of a graph node. */ UNIV_INLINE ulint que_node_get_type( /*==============*/ que_node_t* node); /* in: graph node */ /*************************************************************************** Gets pointer to the value data type field of a graph node. */ UNIV_INLINE dtype_t* que_node_get_data_type( /*===================*/ que_node_t* node); /* in: graph node */ /*************************************************************************** Gets pointer to the value dfield of a graph node. */ UNIV_INLINE dfield_t* que_node_get_val( /*=============*/ que_node_t* node); /* in: graph node */ /*************************************************************************** Gets the value buffer size of a graph node. */ UNIV_INLINE ulint que_node_get_val_buf_size( /*======================*/ /* out: val buffer size, not defined if val.data == NULL in node */ que_node_t* node); /* in: graph node */ /*************************************************************************** Sets the value buffer size of a graph node. */ UNIV_INLINE void que_node_set_val_buf_size( /*======================*/ que_node_t* node, /* in: graph node */ ulint size); /* in: size */ /************************************************************************* Gets the next list node in a list of query graph nodes. */ UNIV_INLINE que_node_t* que_node_get_next( /*==============*/ que_node_t* node); /* in: node in a list */ /************************************************************************* Gets the parent node of a query graph node. */ UNIV_INLINE que_node_t* que_node_get_parent( /*================*/ /* out: parent node or NULL */ que_node_t* node); /* in: node */ /************************************************************************* Catenates a query graph node to a list of them, possible empty list. */ UNIV_INLINE que_node_t* que_node_list_add_last( /*===================*/ /* out: one-way list of nodes */ que_node_t* node_list, /* in: node list, or NULL */ que_node_t* node); /* in: node */ /************************************************************************* Gets a query graph node list length. */ UNIV_INLINE ulint que_node_list_get_len( /*==================*/ /* out: length, for NULL list 0 */ que_node_t* node_list); /* in: node list, or NULL */ /************************************************************************** Checks if graph, trx, or session is in a state where the query thread should be stopped. */ UNIV_INLINE ibool que_thr_peek_stop( /*==============*/ /* out: TRUE if should be stopped; NOTE that if the peek is made without reserving the kernel mutex, then another peek with the mutex reserved is necessary before deciding the actual stopping */ que_thr_t* thr); /* in: query thread */ /*************************************************************************** Returns TRUE if the query graph is for a SELECT statement. */ UNIV_INLINE ibool que_graph_is_select( /*================*/ /* out: TRUE if a select */ que_t* graph); /* in: graph */ /************************************************************************** Prints info of an SQL query graph node. */ void que_node_print_info( /*================*/ que_node_t* node); /* in: query graph node */ /* Query graph query thread node: the fields are protected by the kernel mutex with the exceptions named below */ struct que_thr_struct{ que_common_t common; /* type: QUE_NODE_THR */ ulint magic_n; /* magic number to catch memory corruption */ que_node_t* child; /* graph child node */ que_t* graph; /* graph where this node belongs */ ibool is_active; /* TRUE if the thread has been set to the run state in que_thr_move_to_run_state, but not deactivated in que_thr_dec_reference_count */ ulint state; /* state of the query thread */ UT_LIST_NODE_T(que_thr_t) thrs; /* list of thread nodes of the fork node */ UT_LIST_NODE_T(que_thr_t) trx_thrs; /* lists of threads in wait list of the trx */ UT_LIST_NODE_T(que_thr_t) queue; /* list of runnable thread nodes in the server task queue */ /*------------------------------*/ /* The following fields are private to the OS thread executing the query thread, and are not protected by the kernel mutex: */ que_node_t* run_node; /* pointer to the node where the subgraph down from this node is currently executed */ que_node_t* prev_node; /* pointer to the node from which the control came */ ulint resource; /* resource usage of the query thread thus far */ }; #define QUE_THR_MAGIC_N 8476583 #define QUE_THR_MAGIC_FREED 123461526 /* Query graph fork node: its fields are protected by the kernel mutex */ struct que_fork_struct{ que_common_t common; /* type: QUE_NODE_FORK */ que_t* graph; /* query graph of this node */ ulint fork_type; /* fork type */ ulint n_active_thrs; /* if this is the root of a graph, the number query threads that have been started in que_thr_move_to_run_state but for which que_thr_dec_refer_count has not yet been called */ trx_t* trx; /* transaction: this is set only in the root node */ ulint state; /* state of the fork node */ que_thr_t* caller; /* pointer to a possible calling query thread */ UT_LIST_BASE_NODE_T(que_thr_t) thrs; /* list of query threads */ /*------------------------------*/ /* The fields in this section are defined only in the root node */ sym_tab_t* sym_tab; /* symbol table of the query, generated by the parser, or NULL if the graph was created 'by hand' */ ulint id; /* id of this query graph */ ulint command; /* command currently executed in the graph */ ulint param; /* possible command parameter */ /* The following cur_... fields are relevant only in a select graph */ ulint cur_end; /* QUE_CUR_NOT_DEFINED, QUE_CUR_START, QUE_CUR_END */ ulint cur_pos; /* if there are n rows in the result set, values 0 and n + 1 mean before first row, or after last row, depending on cur_end; values 1...n mean a row index */ ibool cur_on_row; /* TRUE if cursor is on a row, i.e., it is not before the first row or after the last row */ dulint n_inserts; /* number of rows inserted */ dulint n_updates; /* number of rows updated */ dulint n_deletes; /* number of rows deleted */ sel_node_t* last_sel_node; /* last executed select node, or NULL if none */ UT_LIST_NODE_T(que_fork_t) graphs; /* list of query graphs of a session or a stored procedure */ /*------------------------------*/ mem_heap_t* heap; /* memory heap where the fork was created */ }; /* Query fork (or graph) types */ #define QUE_FORK_SELECT_NON_SCROLL 1 /* forward-only cursor */ #define QUE_FORK_SELECT_SCROLL 2 /* scrollable cursor */ #define QUE_FORK_INSERT 3 #define QUE_FORK_UPDATE 4 #define QUE_FORK_ROLLBACK 5 /* This is really the undo graph used in rollback, no signal-sending roll_node in this graph */ #define QUE_FORK_PURGE 6 #define QUE_FORK_EXECUTE 7 #define QUE_FORK_PROCEDURE 8 #define QUE_FORK_PROCEDURE_CALL 9 #define QUE_FORK_MYSQL_INTERFACE 10 #define QUE_FORK_RECOVERY 11 /* Query fork (or graph) states */ #define QUE_FORK_ACTIVE 1 #define QUE_FORK_COMMAND_WAIT 2 #define QUE_FORK_INVALID 3 #define QUE_FORK_BEING_FREED 4 /* Flag which is ORed to control structure statement node types */ #define QUE_NODE_CONTROL_STAT 1024 /* Query graph node types */ #define QUE_NODE_LOCK 1 #define QUE_NODE_INSERT 2 #define QUE_NODE_UPDATE 4 #define QUE_NODE_CURSOR 5 #define QUE_NODE_SELECT 6 #define QUE_NODE_AGGREGATE 7 #define QUE_NODE_FORK 8 #define QUE_NODE_THR 9 #define QUE_NODE_UNDO 10 #define QUE_NODE_COMMIT 11 #define QUE_NODE_ROLLBACK 12 #define QUE_NODE_PURGE 13 #define QUE_NODE_CREATE_TABLE 14 #define QUE_NODE_CREATE_INDEX 15 #define QUE_NODE_SYMBOL 16 #define QUE_NODE_RES_WORD 17 #define QUE_NODE_FUNC 18 #define QUE_NODE_ORDER 19 #define QUE_NODE_PROC (20 + QUE_NODE_CONTROL_STAT) #define QUE_NODE_IF (21 + QUE_NODE_CONTROL_STAT) #define QUE_NODE_WHILE (22 + QUE_NODE_CONTROL_STAT) #define QUE_NODE_ASSIGNMENT 23 #define QUE_NODE_FETCH 24 #define QUE_NODE_OPEN 25 #define QUE_NODE_COL_ASSIGNMENT 26 #define QUE_NODE_FOR (27 + QUE_NODE_CONTROL_STAT) #define QUE_NODE_RETURN 28 #define QUE_NODE_ROW_PRINTF 29 #define QUE_NODE_ELSIF 30 #define QUE_NODE_CALL 31 /* Query thread states */ #define QUE_THR_RUNNING 1 #define QUE_THR_PROCEDURE_WAIT 2 #define QUE_THR_COMPLETED 3 /* in selects this means that the thread is at the end of its result set (or start, in case of a scroll cursor); in other statements, this means the thread has done its task */ #define QUE_THR_COMMAND_WAIT 4 #define QUE_THR_LOCK_WAIT 5 #define QUE_THR_SIG_REPLY_WAIT 6 #define QUE_THR_SUSPENDED 7 #define QUE_THR_ERROR 8 /* From where the cursor position is counted */ #define QUE_CUR_NOT_DEFINED 1 #define QUE_CUR_START 2 #define QUE_CUR_END 3 #ifndef UNIV_NONINL #include "que0que.ic" #endif #endif