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

📄 pars0pars.c

📁 这是linux下运行的mysql软件包,可用于linux 下安装 php + mysql + apach 的网络配置
💻 C
📖 第 1 页 / 共 3 页
字号:
/******************************************************SQL parser(c) 1996 Innobase OyCreated 11/19/1996 Heikki Tuuri*******************************************************//* Historical note: Innobase executed its first SQL string (CREATE TABLE)on 1/27/1998 */#include "pars0pars.h"#ifdef UNIV_NONINL#include "pars0pars.ic"#endif#include "row0sel.h"#include "row0ins.h"#include "row0upd.h"#include "dict0dict.h"#include "dict0mem.h"#include "dict0crea.h"#include "que0que.h"#include "pars0grm.h"#include "pars0opt.h"#include "data0data.h"#include "data0type.h"#include "trx0trx.h"#include "trx0roll.h"#include "lock0lock.h"#include "eval0eval.h"#ifdef UNIV_SQL_DEBUG/* If the following is set TRUE, the lexer will print the SQL stringas it tokenizes it */ibool	pars_print_lexed	= FALSE;#endif /* UNIV_SQL_DEBUG *//* Global variable used while parsing a single procedure or query : the code isNOT re-entrant */sym_tab_t*	pars_sym_tab_global;/* Global variables used to denote certain reserved words, used inconstructing the parsing tree */pars_res_word_t	pars_to_char_token = {PARS_TO_CHAR_TOKEN};pars_res_word_t	pars_to_number_token = {PARS_TO_NUMBER_TOKEN};pars_res_word_t	pars_to_binary_token = {PARS_TO_BINARY_TOKEN};pars_res_word_t	pars_binary_to_number_token = {PARS_BINARY_TO_NUMBER_TOKEN};pars_res_word_t	pars_substr_token = {PARS_SUBSTR_TOKEN};pars_res_word_t	pars_replstr_token = {PARS_REPLSTR_TOKEN};pars_res_word_t	pars_concat_token = {PARS_CONCAT_TOKEN};pars_res_word_t	pars_instr_token = {PARS_INSTR_TOKEN};pars_res_word_t	pars_length_token = {PARS_LENGTH_TOKEN};pars_res_word_t	pars_sysdate_token = {PARS_SYSDATE_TOKEN};pars_res_word_t	pars_printf_token = {PARS_PRINTF_TOKEN};pars_res_word_t	pars_assert_token = {PARS_ASSERT_TOKEN};pars_res_word_t	pars_rnd_token = {PARS_RND_TOKEN};pars_res_word_t	pars_rnd_str_token = {PARS_RND_STR_TOKEN};pars_res_word_t	pars_count_token = {PARS_COUNT_TOKEN};pars_res_word_t	pars_sum_token = {PARS_SUM_TOKEN};pars_res_word_t	pars_distinct_token = {PARS_DISTINCT_TOKEN};pars_res_word_t	pars_int_token = {PARS_INT_TOKEN};pars_res_word_t	pars_char_token = {PARS_CHAR_TOKEN};pars_res_word_t	pars_float_token = {PARS_FLOAT_TOKEN};pars_res_word_t	pars_update_token = {PARS_UPDATE_TOKEN};pars_res_word_t	pars_asc_token = {PARS_ASC_TOKEN};pars_res_word_t	pars_desc_token = {PARS_DESC_TOKEN};pars_res_word_t	pars_open_token = {PARS_OPEN_TOKEN};pars_res_word_t	pars_close_token = {PARS_CLOSE_TOKEN};pars_res_word_t	pars_consistent_token = {PARS_CONSISTENT_TOKEN};pars_res_word_t	pars_unique_token = {PARS_UNIQUE_TOKEN};pars_res_word_t	pars_clustered_token = {PARS_CLUSTERED_TOKEN};/* Global variable used to denote the '*' in SELECT * FROM.. */#define PARS_STAR_DENOTER	12345678ulint	pars_star_denoter	= PARS_STAR_DENOTER;/*************************************************************************Determines the class of a function code. */staticulintpars_func_get_class(/*================*/			/* out: function class: PARS_FUNC_ARITH, ... */	int	func)	/* in: function code: '=', PARS_GE_TOKEN, ... */{	if ((func == '+') || (func == '-') || (func == '*') || (func == '/')) {		return(PARS_FUNC_ARITH);	} else if ((func == '=') || (func == '<') || (func == '>')		   || (func == PARS_GE_TOKEN) || (func == PARS_LE_TOKEN)		   || (func == PARS_NE_TOKEN)) {		return(PARS_FUNC_CMP);	} else if ((func == PARS_AND_TOKEN) || (func == PARS_OR_TOKEN)		   || (func == PARS_NOT_TOKEN)) {		return(PARS_FUNC_LOGICAL);	} else if ((func == PARS_COUNT_TOKEN) || (func == PARS_SUM_TOKEN)) {		return(PARS_FUNC_AGGREGATE);	} else if ((func == PARS_TO_CHAR_TOKEN)		   || (func == PARS_TO_NUMBER_TOKEN)		   || (func == PARS_TO_BINARY_TOKEN)		   || (func == PARS_BINARY_TO_NUMBER_TOKEN)		   || (func == PARS_SUBSTR_TOKEN)		   || (func == PARS_CONCAT_TOKEN)		   || (func == PARS_LENGTH_TOKEN)		   || (func == PARS_INSTR_TOKEN)		   || (func == PARS_SYSDATE_TOKEN)		   || (func == PARS_NOTFOUND_TOKEN)		   || (func == PARS_PRINTF_TOKEN)		   || (func == PARS_ASSERT_TOKEN)		   || (func == PARS_RND_TOKEN)		   || (func == PARS_RND_STR_TOKEN)		   || (func == PARS_REPLSTR_TOKEN)) {		return(PARS_FUNC_PREDEFINED);	} else {		return(PARS_FUNC_OTHER);	}}	/*************************************************************************Parses an operator or predefined function expression. */staticfunc_node_t*pars_func_low(/*==========*/				/* out, own: function node in a query tree */	int		func,	/* in: function token code */	que_node_t*	arg)	/* in: first argument in the argument list */{	func_node_t*	node;	node = mem_heap_alloc(pars_sym_tab_global->heap, sizeof(func_node_t));	node->common.type = QUE_NODE_FUNC;	dfield_set_data(&(node->common.val), NULL, 0);	node->common.val_buf_size = 0;		node->func = func;	node->class = pars_func_get_class(func);	node->args = arg;	UT_LIST_ADD_LAST(func_node_list, pars_sym_tab_global->func_node_list,								node);	return(node);}/*************************************************************************Parses a function expression. */func_node_t*pars_func(/*======*/				/* out, own: function node in a query tree */	que_node_t* 	res_word,/* in: function name reserved word */	que_node_t*	arg)	/* in: first argument in the argument list */{	return(pars_func_low(((pars_res_word_t*)res_word)->code, arg));}/*************************************************************************Parses an operator expression. */func_node_t*pars_op(/*====*/				/* out, own: function node in a query tree */	int		func,	/* in: operator token code */	que_node_t*	arg1,	/* in: first argument */	que_node_t*	arg2)	/* in: second argument or NULL for an unary				operator */{	que_node_list_add_last(NULL, arg1);	if (arg2) {		que_node_list_add_last(arg1, arg2);	}	return(pars_func_low(func, arg1));}/*************************************************************************Parses an ORDER BY clause. Order by a single column only is supported. */order_node_t*pars_order_by(/*==========*/				/* out, own: order-by node in a query tree */	sym_node_t*	column,	/* in: column name */	pars_res_word_t* asc)	/* in: &pars_asc_token or pars_desc_token */{	order_node_t*	node;	node = mem_heap_alloc(pars_sym_tab_global->heap, sizeof(order_node_t));	node->common.type = QUE_NODE_ORDER;		node->column = column;	if (asc == &pars_asc_token) {		node->asc = TRUE;	} else {		ut_a(asc == &pars_desc_token);		node->asc = FALSE;	}	return(node);}/*************************************************************************Resolves the data type of a function in an expression. The argument datatypes must already be resolved. */staticvoidpars_resolve_func_data_type(/*========================*/	func_node_t*	node)	/* in: function node */{	que_node_t*	arg;	ulint		func;	ut_a(que_node_get_type(node) == QUE_NODE_FUNC);		arg = node->args;	func = node->func;	if ((func == PARS_SUM_TOKEN)	    		|| (func == '+') || (func == '-') || (func == '*')			|| (func == '/') || (func == '+')) {			/* Inherit the data type from the first argument (which must		not be the SQL null literal whose type is DATA_ERROR) */		dtype_copy(que_node_get_data_type(node),					que_node_get_data_type(arg));		ut_a(dtype_get_mtype(que_node_get_data_type(node))								== DATA_INT);	} else if (func == PARS_COUNT_TOKEN) {		ut_a(arg);		dtype_set(que_node_get_data_type(node), DATA_INT, 0, 4, 0);			} else if (func == PARS_TO_CHAR_TOKEN) {		ut_a(dtype_get_mtype(que_node_get_data_type(arg)) == DATA_INT);		dtype_set(que_node_get_data_type(node), DATA_VARCHAR,							DATA_ENGLISH, 0, 0);	} else if (func == PARS_TO_BINARY_TOKEN) {		if (dtype_get_mtype(que_node_get_data_type(arg)) == DATA_INT) {			dtype_set(que_node_get_data_type(node), DATA_VARCHAR,							DATA_ENGLISH, 0, 0);		} else {			dtype_set(que_node_get_data_type(node), DATA_BINARY,								0, 0, 0);		}	} else if (func == PARS_TO_NUMBER_TOKEN) {		ut_a(dtype_get_mtype(que_node_get_data_type(arg))							== DATA_VARCHAR);		dtype_set(que_node_get_data_type(node), DATA_INT, 0, 4, 0);	} else if (func == PARS_BINARY_TO_NUMBER_TOKEN) {		ut_a(dtype_get_mtype(que_node_get_data_type(arg))							== DATA_VARCHAR);		dtype_set(que_node_get_data_type(node), DATA_INT, 0, 4, 0);	} else if (func == PARS_LENGTH_TOKEN) {		ut_a(dtype_get_mtype(que_node_get_data_type(arg))							== DATA_VARCHAR);		dtype_set(que_node_get_data_type(node), DATA_INT, 0, 4, 0);	} else if (func == PARS_INSTR_TOKEN) {		ut_a(dtype_get_mtype(que_node_get_data_type(arg))							== DATA_VARCHAR);		dtype_set(que_node_get_data_type(node), DATA_INT, 0, 4, 0);	} else if (func == PARS_SYSDATE_TOKEN) {		ut_a(arg == NULL);		dtype_set(que_node_get_data_type(node), DATA_INT, 0, 4, 0);	} else if ((func == PARS_SUBSTR_TOKEN)			|| (func == PARS_CONCAT_TOKEN)) {		ut_a(dtype_get_mtype(que_node_get_data_type(arg))							== DATA_VARCHAR);		dtype_set(que_node_get_data_type(node), DATA_VARCHAR,							DATA_ENGLISH, 0, 0);	} else if ((func == '>') || (func == '<') || (func == '=')		   || (func == PARS_GE_TOKEN)		   || (func == PARS_LE_TOKEN)		   || (func == PARS_NE_TOKEN)		   || (func == PARS_AND_TOKEN)		   || (func == PARS_OR_TOKEN)		   || (func == PARS_NOT_TOKEN)		   || (func == PARS_NOTFOUND_TOKEN)) {		/* We currently have no iboolean type: use integer type */		dtype_set(que_node_get_data_type(node), DATA_INT, 0, 4, 0);	} else if (func == PARS_RND_TOKEN) {		ut_a(dtype_get_mtype(que_node_get_data_type(arg)) == DATA_INT);		dtype_set(que_node_get_data_type(node), DATA_INT, 0, 4, 0);	} else if (func == PARS_RND_STR_TOKEN) {		ut_a(dtype_get_mtype(que_node_get_data_type(arg)) == DATA_INT);		dtype_set(que_node_get_data_type(node), DATA_VARCHAR,							DATA_ENGLISH, 0, 0);	} else {		ut_error;	}}/*************************************************************************Resolves the meaning of variables in an expression and the data types offunctions. It is an error if some identifier cannot be resolved here. */staticvoidpars_resolve_exp_variables_and_types(/*=================================*/	sel_node_t*	select_node,	/* in: select node or NULL; if					this is not NULL then the variable					sym nodes are added to the					copy_variables list of select_node */	que_node_t*	exp_node)	/* in: expression */{	func_node_t*	func_node;	que_node_t*	arg;	sym_node_t*	sym_node;	sym_node_t*	node;	ut_a(exp_node);	if (que_node_get_type(exp_node) == QUE_NODE_FUNC) {		func_node = exp_node;		arg = func_node->args;		while (arg) {			pars_resolve_exp_variables_and_types(select_node, arg);			arg = que_node_get_next(arg);		}		pars_resolve_func_data_type(func_node);		return;	}			ut_a(que_node_get_type(exp_node) == QUE_NODE_SYMBOL);	sym_node = exp_node;	if (sym_node->resolved) {		return;	}			/* Not resolved yet: look in the symbol table for a variable	or a cursor with the same name */	node = UT_LIST_GET_FIRST(pars_sym_tab_global->sym_list);	while (node) {		if (node->resolved			&& ((node->token_type == SYM_VAR)					|| (node->token_type == SYM_CURSOR))			&& node->name			&& (sym_node->name_len == node->name_len)			&& (ut_memcmp(sym_node->name, node->name,						node->name_len) == 0)) {				/* Found a variable or a cursor declared with				the same name */								break;		}		node = UT_LIST_GET_NEXT(sym_list, node);	}	if (!node) {		fprintf(stderr, "PARSER ERROR: Unresolved identifier %s\n",							sym_node->name);	}		ut_a(node);	sym_node->resolved = TRUE;	sym_node->token_type = SYM_IMPLICIT_VAR;	sym_node->alias = node;			sym_node->indirection = node;	if (select_node) {		UT_LIST_ADD_LAST(col_var_list, select_node->copy_variables,								sym_node);	}	dfield_set_type(que_node_get_val(sym_node),					que_node_get_data_type(node));}/*************************************************************************Resolves the meaning of variables in an expression list. It is an error ifsome identifier cannot be resolved here. Resolves also the data types offunctions. */staticvoidpars_resolve_exp_list_variables_and_types(/*======================================*/	sel_node_t*	select_node,	/* in: select node or NULL */	que_node_t*	exp_node)	/* in: expression list first node, or					NULL */{	while (exp_node) {		pars_resolve_exp_variables_and_types(select_node, exp_node);		exp_node = que_node_get_next(exp_node);	}}/*************************************************************************Resolves the columns in an expression. */staticvoidpars_resolve_exp_columns(/*=====================*/	sym_node_t*	table_node,	/* in: first node in a table list */	que_node_t*	exp_node)	/* in: expression */{	func_node_t*	func_node;	que_node_t*	arg;	sym_node_t*	sym_node;	dict_table_t*	table;	sym_node_t*	t_node;	dict_col_t*	col;	ulint		n_cols;	ulint		i;	ut_a(exp_node);	if (que_node_get_type(exp_node) == QUE_NODE_FUNC) {		func_node = exp_node;		arg = func_node->args;		while (arg) {			pars_resolve_exp_columns(table_node, arg);			arg = que_node_get_next(arg);		}		return;	}			ut_a(que_node_get_type(exp_node) == QUE_NODE_SYMBOL);	sym_node = exp_node;	if (sym_node->resolved) {		return;	}			/* Not resolved yet: look in the table list for a column with the	same name */	t_node = table_node;	while (t_node) {		table = t_node->table;		n_cols = dict_table_get_n_user_cols(table);		for (i = 0; i < n_cols; i++) {			col = dict_table_get_nth_col(table, i);			if ((sym_node->name_len == ut_strlen(col->name))			    && (0 == ut_memcmp(sym_node->name, col->name,			    			sym_node->name_len))) {			    	/* Found */				sym_node->resolved = TRUE;				sym_node->token_type = SYM_COLUMN;				sym_node->table = table;				sym_node->col_no = i;				sym_node->prefetch_buf = NULL;								dfield_set_type(&(sym_node->common.val),						dict_col_get_type(col));				return;			}		}		t_node = que_node_get_next(t_node);	}}/*************************************************************************Resolves the meaning of columns in an expression list. */staticvoidpars_resolve_exp_list_columns(/*==========================*/	sym_node_t*	table_node,	/* in: first node in a table list */	que_node_t*	exp_node)	/* in: expression list first node, or					NULL */{	while (exp_node) {		pars_resolve_exp_columns(table_node, exp_node);		exp_node = que_node_get_next(exp_node);	}}/*************************************************************************Retrieves the table definition for a table name id. */staticvoidpars_retrieve_table_def(/*====================*/	sym_node_t*	sym_node)	/* in: table node */{	const char*	table_name;	ut_a(sym_node);	ut_a(que_node_get_type(sym_node) == QUE_NODE_SYMBOL);	sym_node->resolved = TRUE;	sym_node->token_type = SYM_TABLE;	table_name = (const char*) sym_node->name;		sym_node->table = dict_table_get_low(table_name);	ut_a(sym_node->table);}/*************************************************************************Retrieves the table definitions for a list of table name ids. */staticulintpars_retrieve_table_list_defs(/*==========================*/					/* out: number of tables */	sym_node_t*	sym_node)	/* in: first table node in list */{	ulint		count		= 0;		if (sym_node == NULL) {		return(count);	}	while (sym_node) {		pars_retrieve_table_def(sym_node);		count++;		sym_node = que_node_get_next(sym_node);	}	return(count);}/*************************************************************************Adds all columns to the select list if the query is SELECT * FROM ... */staticvoidpars_select_all_columns(/*====================*/	sel_node_t*	select_node)	/* in: select node already containing					the table list */{	sym_node_t*	col_node;	sym_node_t*	table_node;	dict_table_t*	table;	dict_col_t*	col;	ulint		i;	select_node->select_list = NULL;		table_node = select_node->table_list;	while (table_node) {		table = table_node->table;		for (i = 0; i < dict_table_get_n_user_cols(table); i++) {			col = dict_table_get_nth_col(table, i);

⌨️ 快捷键说明

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