⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 pars0opt.c

📁 这是linux下运行的mysql软件包,可用于linux 下安装 php + mysql + apach 的网络配置
💻 C
📖 第 1 页 / 共 3 页
字号:
	ut_a(UT_LIST_GET_LEN(plan->end_conds) >= plan->n_exact_match);}/***********************************************************************Looks for occurrences of the columns of the table in the query subgraph andadds them to the list of columns if an occurrence of the same column does notalready exist in the list. If the column is already in the list, puts a valueindirection to point to the occurrence in the column list, except if thecolumn occurrence we are looking at is in the column list, in which casenothing is done. */voidopt_find_all_cols(/*==============*/	ibool		copy_val,	/* in: if TRUE, new found columns are					added as columns to copy */	dict_index_t*	index,		/* in: index of the table to use */	sym_node_list_t* col_list,	/* in: base node of a list where					to add new found columns */	plan_t*		plan,		/* in: plan or NULL */	que_node_t*	exp)		/* in: expression or condition or					NULL */{	func_node_t*	func_node;	que_node_t*	arg;	sym_node_t*	sym_node;	sym_node_t*	col_node;	ulint		col_pos;	if (exp == NULL) {		return;	}		if (que_node_get_type(exp) == QUE_NODE_FUNC) {		func_node = exp;		arg = func_node->args;		while (arg) {			opt_find_all_cols(copy_val, index, col_list, plan,									arg);			arg = que_node_get_next(arg);		}		return;	}	ut_a(que_node_get_type(exp) == QUE_NODE_SYMBOL);	sym_node = exp;	if (sym_node->token_type != SYM_COLUMN) {		return;	}	if (sym_node->table != index->table) {		return;	}	/* Look for an occurrence of the same column in the plan column	list */	col_node = UT_LIST_GET_FIRST(*col_list);	while (col_node) {		if (col_node->col_no == sym_node->col_no) {			if (col_node == sym_node) {				/* sym_node was already in a list: do				nothing */				return;			}			/* Put an indirection */			sym_node->indirection = col_node;			sym_node->alias = col_node;			return;		}		col_node = UT_LIST_GET_NEXT(col_var_list, col_node);	}	/* The same column did not occur in the list: add it */	UT_LIST_ADD_LAST(col_var_list, *col_list, sym_node);	sym_node->copy_val = copy_val;	/* Fill in the field_no fields in sym_node */		sym_node->field_nos[SYM_CLUST_FIELD_NO]				= dict_index_get_nth_col_pos(				dict_table_get_first_index(index->table),							sym_node->col_no);	if (!(index->type & DICT_CLUSTERED)) {			ut_a(plan);		col_pos = dict_index_get_nth_col_pos(index, sym_node->col_no);		if (col_pos == ULINT_UNDEFINED) {			plan->must_get_clust = TRUE;		}				sym_node->field_nos[SYM_SEC_FIELD_NO] = col_pos;	}}/***********************************************************************Looks for occurrences of the columns of the table in conditions which arenot yet determined AFTER the join operation has fetched a row in the ithtable. The values for these column must be copied to dynamic memory forlater use. */staticvoidopt_find_copy_cols(/*===============*/	sel_node_t*	sel_node,	/* in: select node */	ulint		i,		/* in: ith table in the join */	func_node_t*	search_cond)	/* in: search condition or NULL */{	func_node_t*	new_cond;	plan_t*		plan;	if (search_cond == NULL) {		return;	}		ut_ad(que_node_get_type(search_cond) == QUE_NODE_FUNC);	if (search_cond->func == PARS_AND_TOKEN) {		new_cond = search_cond->args;		opt_find_copy_cols(sel_node, i, new_cond);				new_cond = que_node_get_next(new_cond);				opt_find_copy_cols(sel_node, i, new_cond);		return;	}	if (!opt_check_exp_determined_before(search_cond, sel_node, i + 1)) {		/* Any ith table columns occurring in search_cond should be		copied, as this condition cannot be tested already on the		fetch from the ith table */		plan = sel_node_get_nth_plan(sel_node, i);				opt_find_all_cols(TRUE, plan->index, &(plan->columns), plan,								search_cond);	}}/***********************************************************************Classifies the table columns according to whether we use the column only whileholding the latch on the page, or whether we have to copy the column value todynamic memory. Puts the first occurrence of a column to either list in theplan node, and puts indirections to later occurrences of the column. */staticvoidopt_classify_cols(/*==============*/	sel_node_t*	sel_node,	/* in: select node */	ulint		i)		/* in: ith table in the join */{	plan_t*		plan;	que_node_t*	exp;	plan = sel_node_get_nth_plan(sel_node, i);	/* The final value of the following field will depend on the	environment of the select statement: */	plan->must_get_clust = FALSE;	UT_LIST_INIT(plan->columns);	/* All select list columns should be copied: therefore TRUE as the	first argument */	exp = sel_node->select_list;	while (exp) {		opt_find_all_cols(TRUE, plan->index, &(plan->columns), plan,									exp);		exp = que_node_get_next(exp);	}	opt_find_copy_cols(sel_node, i, sel_node->search_cond);	/* All remaining columns in the search condition are temporary	columns: therefore FALSE */		opt_find_all_cols(FALSE, plan->index, &(plan->columns), plan,						sel_node->search_cond);}/***********************************************************************Fills in the info in plan which is used in accessing a clustered indexrecord. The columns must already be classified for the plan node. */staticvoidopt_clust_access(/*=============*/	sel_node_t*	sel_node,	/* in: select node */	ulint		n)		/* in: nth table in select */{	plan_t*		plan;	dict_table_t*	table;	dict_index_t*	clust_index;	dict_index_t*	index;	dfield_t*	dfield;	mem_heap_t*	heap;	ulint		n_fields;	ulint		pos;	ulint		i;	plan = sel_node_get_nth_plan(sel_node, n);	index = plan->index;		/* The final value of the following field depends on the environment	of the select statement: */			plan->no_prefetch = FALSE;	if (index->type & DICT_CLUSTERED) {		plan->clust_map = NULL;		plan->clust_ref = NULL;		return;	}	table = index->table;	clust_index = dict_table_get_first_index(table);	n_fields = dict_index_get_n_unique(clust_index);	heap = pars_sym_tab_global->heap;	plan->clust_ref = dtuple_create(heap, n_fields);	dict_index_copy_types(plan->clust_ref, clust_index, n_fields);		plan->clust_map = mem_heap_alloc(heap, n_fields * sizeof(ulint));		for (i = 0; i < n_fields; i++) {		pos = dict_index_get_nth_field_pos(index, clust_index, i);		ut_a(pos != ULINT_UNDEFINED);		/* We optimize here only queries to InnoDB's internal system		tables, and they should not contain column prefix indexes. */		if (dict_index_get_nth_field(index, pos)->prefix_len != 0		    || dict_index_get_nth_field(clust_index, i)							->prefix_len != 0) {			fprintf(stderr,"InnoDB: Error in pars0opt.c: table %s has prefix_len != 0\n",				index->table_name);		}		*(plan->clust_map + i) = pos;		ut_ad((pos != ULINT_UNDEFINED)			|| ((table->type == DICT_TABLE_CLUSTER_MEMBER)				 		&& (i == table->mix_len)));	}	if (table->type == DICT_TABLE_CLUSTER_MEMBER) {				/* Preset the mix id field to the mix id constant */				dfield = dtuple_get_nth_field(plan->clust_ref, table->mix_len);				dfield_set_data(dfield, mem_heap_alloc(heap,							table->mix_id_len),							table->mix_id_len);		ut_memcpy(dfield_get_data(dfield), table->mix_id_buf,							table->mix_id_len);	}}/***********************************************************************Optimizes a select. Decides which indexes to tables to use. The tablesare accessed in the order that they were written to the FROM part in theselect statement. */voidopt_search_plan(/*============*/	sel_node_t*	sel_node)	/* in: parsed select node */{	sym_node_t*	table_node;	dict_table_t*	table;	order_node_t*	order_by;	ulint		i;		sel_node->plans = mem_heap_alloc(pars_sym_tab_global->heap,					sel_node->n_tables * sizeof(plan_t));	/* Analyze the search condition to find out what we know at each	join stage about the conditions that the columns of a table should	satisfy */	table_node = sel_node->table_list;	if (sel_node->order_by == NULL) {		sel_node->asc = TRUE;	} else {		order_by = sel_node->order_by;		sel_node->asc = order_by->asc;	}		for (i = 0; i < sel_node->n_tables; i++) {		table = table_node->table;		/* Choose index through which to access the table */			opt_search_plan_for_table(sel_node, i, table);		/* Determine the search condition conjuncts we can test at		this table; normalize the end conditions */			opt_determine_and_normalize_test_conds(sel_node, i);		table_node = que_node_get_next(table_node);	}	table_node = sel_node->table_list;	for (i = 0; i < sel_node->n_tables; i++) {		/* Classify the table columns into those we only need to access		but not copy, and to those we must copy to dynamic memory */		opt_classify_cols(sel_node, i);		/* Calculate possible info for accessing the clustered index		record */		opt_clust_access(sel_node, i);		table_node = que_node_get_next(table_node);	}		/* Check that the plan obeys a possible order-by clause: if not,	an assertion error occurs */		opt_check_order_by(sel_node);#ifdef UNIV_SQL_DEBUG	opt_print_query_plan(sel_node);#endif}/************************************************************************Prints info of a query plan. */voidopt_print_query_plan(/*=================*/	sel_node_t*	sel_node)	/* in: select node */{	plan_t*	plan;	ulint	n_fields;	ulint	i;	fputs("QUERY PLAN FOR A SELECT NODE\n", stderr);	fputs(sel_node->asc ? "Asc. search; " : "Desc. search; ", stderr);	if (sel_node->set_x_locks) {		fputs("sets row x-locks; ", stderr);		ut_a(sel_node->row_lock_mode == LOCK_X);		ut_a(!sel_node->consistent_read);	} else if (sel_node->consistent_read) {		fputs("consistent read; ", stderr);	} else {		ut_a(sel_node->row_lock_mode == LOCK_S);		fputs("sets row s-locks; ", stderr);	}	putc('\n', stderr);	for (i = 0; i < sel_node->n_tables; i++) {		plan = sel_node_get_nth_plan(sel_node, i);		if (plan->tuple) {			n_fields = dtuple_get_n_fields(plan->tuple);		} else {			n_fields = 0;		}		fputs("Table ", stderr);		dict_index_name_print(stderr, NULL, plan->index);		fprintf(stderr,"; exact m. %lu, match %lu, end conds %lu\n",		        (unsigned long) plan->n_exact_match,		        (unsigned long) n_fields,			(unsigned long) UT_LIST_GET_LEN(plan->end_conds));	}}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -