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

📄 pars0opt.c

📁 这是linux下运行的mysql软件包,可用于linux 下安装 php + mysql + apach 的网络配置
💻 C
📖 第 1 页 / 共 3 页
字号:
	} else if (op == '>') {		ut_a(asc);		return(PAGE_CUR_G);	} else if (op == PARS_GE_TOKEN) {		ut_a(asc);		return(PAGE_CUR_GE);	} else if (op == PARS_LE_TOKEN) {		ut_a(!asc);		return(PAGE_CUR_LE);	} else {		ut_error;	}	return(0);}/***********************************************************************Determines if a node is an argument node of a function node. */staticiboolopt_is_arg(/*=======*/					/* out: TRUE if is an argument */	que_node_t*	arg_node,	/* in: possible argument node */	func_node_t*	func_node)	/* in: function node */{	que_node_t*	arg;	arg = func_node->args;	while (arg) {		if (arg == arg_node) {			return(TRUE);		}		arg = que_node_get_next(arg);	}	return(FALSE);}/***********************************************************************Decides if the fetching of rows should be made in a descending order, andalso checks that the chosen query plan produces a result which satisfiesthe order-by. */staticvoidopt_check_order_by(/*===============*/	sel_node_t*	sel_node)	/* in: select node; asserts an error					if the plan does not agree with the					order-by */{	order_node_t*	order_node;	dict_table_t*	order_table;	ulint		order_col_no;	plan_t*		plan;	ulint		i;	if (!sel_node->order_by) {		return;	}	order_node = sel_node->order_by;	order_col_no = order_node->column->col_no;	order_table = order_node->column->table;	/* If there is an order-by clause, the first non-exactly matched field	in the index used for the last table in the table list should be the	column defined in the order-by clause, and for all the other tables	we should get only at most a single row, otherwise we cannot presently	calculate the order-by, as we have no sort utility */			for (i = 0; i < sel_node->n_tables; i++) {			plan = sel_node_get_nth_plan(sel_node, i);		if (i < sel_node->n_tables - 1) {			ut_a(dict_index_get_n_unique(plan->index)						<= plan->n_exact_match);		} else {			ut_a(plan->table == order_table);			ut_a((dict_index_get_n_unique(plan->index)						<= plan->n_exact_match)			     || (dict_index_get_nth_col_no(plan->index,			     				plan->n_exact_match)			   			== order_col_no));		}	}}/***********************************************************************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. */staticvoidopt_search_plan_for_table(/*======================*/	sel_node_t*	sel_node,	/* in: parsed select node */	ulint		i,		/* in: this is the ith table */	dict_table_t*	table)		/* in: table */{	plan_t*		plan;	dict_index_t*	index;	dict_index_t*	best_index;	ulint		n_fields;	ulint		goodness;	ulint		last_op		= 75946965;	/* Eliminate a Purify							warning */	ulint		best_goodness;	ulint		best_last_op = 0; /* remove warning */	ulint		mix_id_pos;	que_node_t*	index_plan[256];	que_node_t*	best_index_plan[256];	plan = sel_node_get_nth_plan(sel_node, i);	plan->table = table;	plan->asc = sel_node->asc;	plan->pcur_is_open = FALSE;	plan->cursor_at_end = FALSE;	/* Calculate goodness for each index of the table */	index = dict_table_get_first_index(table);	best_index = index; /* Eliminate compiler warning */	best_goodness = 0;		/* should be do ... until ? comment by Jani */	while (index) {		goodness = opt_calc_index_goodness(index, sel_node, i,						index_plan, &last_op);		if (goodness > best_goodness) {			best_index = index;			best_goodness = goodness;			n_fields = opt_calc_n_fields_from_goodness(goodness);			ut_memcpy(best_index_plan, index_plan,						n_fields * sizeof(void*));			best_last_op = last_op;		}		index = dict_table_get_next_index(index);	}		plan->index = best_index;	n_fields = opt_calc_n_fields_from_goodness(best_goodness);	if (n_fields == 0) {		plan->tuple = NULL;		plan->n_exact_match = 0;	} else {		plan->tuple = dtuple_create(pars_sym_tab_global->heap,								n_fields);		dict_index_copy_types(plan->tuple, plan->index, n_fields);				plan->tuple_exps = mem_heap_alloc(pars_sym_tab_global->heap,						n_fields * sizeof(void*));		ut_memcpy(plan->tuple_exps, best_index_plan,				  		n_fields * sizeof(void*));		if (best_last_op == '=') {			plan->n_exact_match = n_fields;		} else {			plan->n_exact_match = n_fields - 1;		}					plan->mode = opt_op_to_search_mode(sel_node->asc,								best_last_op);	}	if ((best_index->type & DICT_CLUSTERED)	    && (plan->n_exact_match >= dict_index_get_n_unique(best_index))) {		plan->unique_search = TRUE;	} else {		plan->unique_search = FALSE;	}	if ((table->type != DICT_TABLE_ORDINARY)	    			&& (best_index->type & DICT_CLUSTERED)) {	    	plan->mixed_index = TRUE;	    	mix_id_pos = table->mix_len;	    	if (mix_id_pos < n_fields) {	    		/* We have to add the mix id as a (string) literal			expression to the tuple_exps */			plan->tuple_exps[mix_id_pos] =				sym_tab_add_str_lit(pars_sym_tab_global,							table->mix_id_buf,							table->mix_id_len);	    	}	} else {		plan->mixed_index = FALSE;	}		plan->old_vers_heap = NULL;	btr_pcur_init(&(plan->pcur));	btr_pcur_init(&(plan->clust_pcur));}/***********************************************************************Looks at a comparison condition and decides if it can, and need, be tested fora table AFTER the table has been accessed. */staticulintopt_classify_comparison(/*====================*/					/* out: OPT_NOT_COND if not for this					table, else OPT_END_COND,					OPT_TEST_COND, or OPT_SCROLL_COND,					where the last means that the					condition need not be tested, except					when scroll cursors are used */	sel_node_t*	sel_node,	/* in: select node */	ulint		i,		/* in: ith table in the join */	func_node_t*	cond)		/* in: comparison condition */{	plan_t*	plan;	ulint	n_fields;	ulint	op;	ulint	j;	ut_ad(cond && sel_node);	plan = sel_node_get_nth_plan(sel_node, i);	/* Check if the condition is determined after the ith table has been	accessed, but not after the i - 1:th */	if (!opt_check_exp_determined_before(cond, sel_node, i + 1)) {		return(OPT_NOT_COND);	}	if ((i > 0) && opt_check_exp_determined_before(cond, sel_node, i)) {		return(OPT_NOT_COND);	}	/* If the condition is an exact match condition used in constructing	the search tuple, it is classified as OPT_END_COND */	if (plan->tuple) {		n_fields = dtuple_get_n_fields(plan->tuple);	} else {		n_fields = 0;	}	for (j = 0; j < plan->n_exact_match; j++) {		if (opt_is_arg(plan->tuple_exps[j], cond)) {			return(OPT_END_COND);		}	}	/* If the condition is an non-exact match condition used in	constructing the search tuple, it is classified as OPT_SCROLL_COND.	When the cursor is positioned, and if a non-scroll cursor is used,	there is no need to test this condition; if a scroll cursor is used	the testing is necessary when the cursor is reversed. */	if ((n_fields > plan->n_exact_match)	    	&& opt_is_arg(plan->tuple_exps[n_fields - 1], cond)) {	    	return(OPT_SCROLL_COND);	}	/* If the condition is a non-exact match condition on the first field	in index for which there is no exact match, and it limits the search	range from the opposite side of the search tuple already BEFORE we	access the table, it is classified as OPT_END_COND */	if ((dict_index_get_n_fields(plan->index) > plan->n_exact_match)	    && opt_look_for_col_in_comparison_before(				OPT_COMPARISON,	    			dict_index_get_nth_col_no(plan->index,	    						plan->n_exact_match),	    			cond, sel_node, i, &op)) {	    						if (sel_node->asc && ((op == '<') || (op == PARS_LE_TOKEN))) {			return(OPT_END_COND);		}		if (!sel_node->asc && ((op == '>') || (op == PARS_GE_TOKEN))) {			return(OPT_END_COND);		}	}	/* Otherwise, cond is classified as OPT_TEST_COND */	return(OPT_TEST_COND);}/***********************************************************************Recursively looks for test conditions for a table in a join. */staticvoidopt_find_test_conds(/*================*/	sel_node_t*	sel_node,	/* in: select node */	ulint		i,		/* in: ith table in the join */	func_node_t*	cond)		/* in: conjunction of search					conditions or NULL */{	func_node_t*	new_cond;	ulint		class;	plan_t*		plan;	if (cond == NULL) {		return;	}	if (cond->func == PARS_AND_TOKEN) {		new_cond = cond->args;		opt_find_test_conds(sel_node, i, new_cond);		new_cond = que_node_get_next(new_cond);				opt_find_test_conds(sel_node, i, new_cond);		return;	}	plan = sel_node_get_nth_plan(sel_node, i);	class = opt_classify_comparison(sel_node, i, cond);	if (class == OPT_END_COND) {		UT_LIST_ADD_LAST(cond_list, plan->end_conds, cond);	} else if (class == OPT_TEST_COND) {		UT_LIST_ADD_LAST(cond_list, plan->other_conds, cond);	}}/***********************************************************************Normalizes a list of comparison conditions so that a column of the tableappears on the left side of the comparison if possible. This is accomplishedby switching the arguments of the operator. */staticvoidopt_normalize_cmp_conds(/*====================*/	func_node_t*	cond,	/* in: first in a list of comparison				conditions, or NULL */	dict_table_t*	table)	/* in: table */{	que_node_t*	arg1;	que_node_t*	arg2;	sym_node_t*	sym_node;	while (cond) {		arg1 = cond->args;		arg2 = que_node_get_next(arg1);		if (que_node_get_type(arg2) == QUE_NODE_SYMBOL) {			sym_node = arg2;			if ((sym_node->token_type == SYM_COLUMN)					&& (sym_node->table == table)) {				/* Switch the order of the arguments */				cond->args = arg2;				que_node_list_add_last(NULL, arg2);				que_node_list_add_last(arg2, arg1);				/* Invert the operator */				cond->func = opt_invert_cmp_op(cond->func);			}		}		cond = UT_LIST_GET_NEXT(cond_list, cond);	}}	/***********************************************************************Finds out the search condition conjuncts we can, and need, to test as the ithtable in a join is accessed. The search tuple can eliminate the need to testsome conjuncts. */staticvoidopt_determine_and_normalize_test_conds(/*===================================*/	sel_node_t*	sel_node,	/* in: select node */	ulint		i)		/* in: ith table in the join */{	plan_t*	plan;	plan = sel_node_get_nth_plan(sel_node, i);	UT_LIST_INIT(plan->end_conds);	UT_LIST_INIT(plan->other_conds);		/* Recursively go through the conjuncts and classify them */	opt_find_test_conds(sel_node, i, sel_node->search_cond);	opt_normalize_cmp_conds(UT_LIST_GET_FIRST(plan->end_conds),								plan->table);

⌨️ 快捷键说明

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