/**********************************************************************//**
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.
@return 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_thr_t*
que_fork_start_command( /*===================*/
que_fork_t* fork) /*!< in: a query fork */
{
fork->state = QUE_FORK_ACTIVE;
fork->last_sel_node = NULL;
que_thr_t* thr = UT_LIST_GET_FIRST(fork->thrs);
if (thr) {
ut_ad(thr->state == QUE_THR_COMPLETED);
que_thr_init_command(thr);
}
return(thr);
}
/**********************************************************************//**
Calls que_graph_free_recursive for statements in a statement list. */ static void
que_graph_free_stat_list( /*=====================*/
que_node_t* node) /*!< in: first query graph node in the list */
{ while (node) {
que_node_t* next = que_node_get_next(node);
que_graph_free_recursive(node);
node = next;
}
}
/**********************************************************************//**
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 */
{
que_fork_t* fork;
que_thr_t* thr;
undo_node_t* undo;
sel_node_t* sel;
ins_node_t* ins;
upd_node_t* upd;
tab_node_t* cre_tab;
ind_node_t* cre_ind;
purge_node_t* purge;
if (node == NULL) { return;
}
switch (que_node_get_type(node)) {
case QUE_NODE_FORK:
fork = static_cast<que_fork_t*>(node);
thr = UT_LIST_GET_FIRST(fork->thrs);
while (thr) {
que_graph_free_recursive(thr);
thr = UT_LIST_GET_NEXT(thrs, thr);
}
break; case QUE_NODE_THR:
thr = static_cast<que_thr_t*>(node);
que_graph_free_recursive(thr->child); break; case QUE_NODE_UNDO:
undo = static_cast<undo_node_t*>(node);
mem_heap_free(undo->heap);
break; case QUE_NODE_SELECT:
sel = static_cast<sel_node_t*>(node);
sel_node_free_private(sel);
break; case QUE_NODE_INSERT:
ins = static_cast<ins_node_t*>(node);
que_graph_free_recursive(ins->select);
ins->~ins_node_t(); break; case QUE_NODE_PURGE:
purge = static_cast<purge_node_t*>(node);
mem_heap_free(purge->heap);
purge->~purge_node_t(); break;
case QUE_NODE_UPDATE:
upd = static_cast<upd_node_t*>(node);
break; case QUE_NODE_PROC:
que_graph_free_stat_list(((proc_node_t*) node)->stat_list);
break; case QUE_NODE_IF:
que_graph_free_stat_list(((if_node_t*) node)->stat_list);
que_graph_free_stat_list(((if_node_t*) node)->else_part);
que_graph_free_stat_list(((if_node_t*) node)->elsif_list);
break; case QUE_NODE_ELSIF:
que_graph_free_stat_list(((elsif_node_t*) node)->stat_list);
break; case QUE_NODE_WHILE:
que_graph_free_stat_list(((while_node_t*) node)->stat_list);
break; case QUE_NODE_FOR:
que_graph_free_stat_list(((for_node_t*) node)->stat_list);
break;
case QUE_NODE_ASSIGNMENT: case QUE_NODE_EXIT: case QUE_NODE_RETURN: case QUE_NODE_COMMIT: case QUE_NODE_ROLLBACK: case QUE_NODE_LOCK: case QUE_NODE_FUNC: case QUE_NODE_ORDER: case QUE_NODE_ROW_PRINTF: case QUE_NODE_OPEN: case QUE_NODE_FETCH: /* No need to do anything */
break; default:
ut_error;
}
}
/**********************************************************************//**
Frees a query graph. */ void
que_graph_free( /*===========*/
que_t* graph) /*!< in: query graph; we assume that the memory heapwherethisgraphwascreatedisprivate tothisgraph:ifnot,thenuse que_graph_free_recursiveandfreetheheap
afterwards! */
{
ut_ad(graph);
if (graph->sym_tab) { /* The following call frees dynamic memory allocated forvariablesetc.duringexecution.Freesalsoexplicit
cursor definitions. */
sym_tab_free_private(graph->sym_tab);
}
if (graph->info) {
pars_info_free(graph->info);
}
que_graph_free_recursive(graph);
mem_heap_free(graph->heap);
}
/****************************************************************//**
Performs an execution step on a thr node.
@return query thread to run next, or NULL if none */ static
que_thr_t*
que_thr_node_step( /*==============*/
que_thr_t* thr) /*!< in: query thread where run_node must
be the thread node itself */
{
ut_ad(thr->run_node == thr);
if (thr->prev_node == thr->common.parent) { /* If control to the node came from above, it is just passed
on */
/****************************************************************//**
Get the first containing loop node (e.g. while_node_t or for_node_t) for the
given node, or NULL if the node is not within a loop.
@return containing loop node, or NULL. */
que_node_t*
que_node_get_containing_loop_node( /*==============================*/
que_node_t* node) /*!< in: node */
{
ut_ad(node);
/**********************************************************************//**
Performs an execution step on a query thread.
@return query thread to run next: it may differ from the input
parameter if, e.g., a subprocedure call is made */
UNIV_INLINE
que_thr_t*
que_thr_step( /*=========*/
que_thr_t* thr) /*!< in: query thread */
{
que_node_t* node;
que_thr_t* old_thr;
trx_t* trx;
ulint type;
if (thr) {
ut_a(thr_get_trx(thr)->error_state == DB_SUCCESS);
}
return(thr);
}
/**********************************************************************//**
Run a query thread until it finishes or encounters e.g. a lock wait. */ static void
que_run_threads_low( /*================*/
que_thr_t* thr) /*!< in: query thread */
{
ut_ad(thr->state == QUE_THR_RUNNING);
/* cumul_resource counts how much resources the OS thread (NOT the
query thread) has spent in this function */
for (trx_t* trx = thr_get_trx(thr);;) {
ut_ad(!trx->mutex_is_owner());
ut_a(trx->error_state == DB_SUCCESS); /* Check that there is enough space in the log to accommodate possiblelogentriesbythisquerystep;iftheoperationcan touchmorethanabout4pages,checksmustbemadealsowithin
the query step! */
log_free_check();
/* Perform the actual query step: note that the query thread
may change if, e.g., a subprocedure call is made */
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.