📄 pars0pars.c
字号:
node->cond = cond; pars_resolve_exp_variables_and_types(NULL, cond); node->stat_list = stat_list; if (else_part && (que_node_get_type(else_part) == QUE_NODE_ELSIF)) { /* There is a list of elsif conditions */ node->else_part = NULL; node->elsif_list = else_part; elsif_node = else_part; while (elsif_node) { pars_set_parent_in_list(elsif_node->stat_list, node); elsif_node = que_node_get_next(elsif_node); } } else { node->else_part = else_part; node->elsif_list = NULL; pars_set_parent_in_list(else_part, node); } pars_set_parent_in_list(stat_list, node); return(node);}/*************************************************************************Parses a while-statement. */while_node_t*pars_while_statement(/*=================*/ /* out: while-statement node */ que_node_t* cond, /* in: while-condition */ que_node_t* stat_list) /* in: statement list */{ while_node_t* node; node = mem_heap_alloc(pars_sym_tab_global->heap, sizeof(while_node_t)); node->common.type = QUE_NODE_WHILE; node->cond = cond; pars_resolve_exp_variables_and_types(NULL, cond); node->stat_list = stat_list; pars_set_parent_in_list(stat_list, node); return(node);}/*************************************************************************Parses a for-loop-statement. */for_node_t*pars_for_statement(/*===============*/ /* out: for-statement node */ sym_node_t* loop_var, /* in: loop variable */ que_node_t* loop_start_limit,/* in: loop start expression */ que_node_t* loop_end_limit, /* in: loop end expression */ que_node_t* stat_list) /* in: statement list */{ for_node_t* node; node = mem_heap_alloc(pars_sym_tab_global->heap, sizeof(for_node_t)); node->common.type = QUE_NODE_FOR; pars_resolve_exp_variables_and_types(NULL, loop_var); pars_resolve_exp_variables_and_types(NULL, loop_start_limit); pars_resolve_exp_variables_and_types(NULL, loop_end_limit); node->loop_var = loop_var->indirection; ut_a(loop_var->indirection); node->loop_start_limit = loop_start_limit; node->loop_end_limit = loop_end_limit; node->stat_list = stat_list; pars_set_parent_in_list(stat_list, node); return(node);}/*************************************************************************Parses a return-statement. */return_node_t*pars_return_statement(void)/*=======================*/ /* out: return-statement node */{ return_node_t* node; node = mem_heap_alloc(pars_sym_tab_global->heap, sizeof(return_node_t)); node->common.type = QUE_NODE_RETURN; return(node);}/*************************************************************************Parses an assignment statement. */assign_node_t*pars_assignment_statement(/*======================*/ /* out: assignment statement node */ sym_node_t* var, /* in: variable to assign */ que_node_t* val) /* in: value to assign */{ assign_node_t* node; node = mem_heap_alloc(pars_sym_tab_global->heap, sizeof(assign_node_t)); node->common.type = QUE_NODE_ASSIGNMENT; node->var = var; node->val = val; pars_resolve_exp_variables_and_types(NULL, var); pars_resolve_exp_variables_and_types(NULL, val); ut_a(dtype_get_mtype(dfield_get_type(que_node_get_val(var))) == dtype_get_mtype(dfield_get_type(que_node_get_val(val)))); return(node);}/*************************************************************************Parses a procedure call. */func_node_t*pars_procedure_call(/*================*/ /* out: function node */ que_node_t* res_word,/* in: procedure name reserved word */ que_node_t* args) /* in: argument list */{ func_node_t* node; node = pars_func(res_word, args); pars_resolve_exp_list_variables_and_types(NULL, args); return(node);}/*************************************************************************Parses a fetch statement. */fetch_node_t*pars_fetch_statement(/*=================*/ /* out: fetch statement node */ sym_node_t* cursor, /* in: cursor node */ sym_node_t* into_list) /* in: variables to set */{ sym_node_t* cursor_decl; fetch_node_t* node; node = mem_heap_alloc(pars_sym_tab_global->heap, sizeof(fetch_node_t)); node->common.type = QUE_NODE_FETCH; pars_resolve_exp_variables_and_types(NULL, cursor); pars_resolve_exp_list_variables_and_types(NULL, into_list); node->into_list = into_list; cursor_decl = cursor->alias; ut_a(cursor_decl->token_type == SYM_CURSOR); node->cursor_def = cursor_decl->cursor_def; ut_a(que_node_list_get_len(into_list) == que_node_list_get_len(node->cursor_def->select_list)); return(node);}/*************************************************************************Parses an open or close cursor statement. */open_node_t*pars_open_statement(/*================*/ /* out: fetch statement node */ ulint type, /* in: ROW_SEL_OPEN_CURSOR or ROW_SEL_CLOSE_CURSOR */ sym_node_t* cursor) /* in: cursor node */{ sym_node_t* cursor_decl; open_node_t* node; node = mem_heap_alloc(pars_sym_tab_global->heap, sizeof(open_node_t)); node->common.type = QUE_NODE_OPEN; pars_resolve_exp_variables_and_types(NULL, cursor); cursor_decl = cursor->alias; ut_a(cursor_decl->token_type == SYM_CURSOR); node->op_type = type; node->cursor_def = cursor_decl->cursor_def; return(node);}/*************************************************************************Parses a row_printf-statement. */row_printf_node_t*pars_row_printf_statement(/*======================*/ /* out: row_printf-statement node */ sel_node_t* sel_node) /* in: select node */{ row_printf_node_t* node; node = mem_heap_alloc(pars_sym_tab_global->heap, sizeof(row_printf_node_t)); node->common.type = QUE_NODE_ROW_PRINTF; node->sel_node = sel_node; sel_node->common.parent = node; return(node);}/*************************************************************************Parses a commit statement. */commit_node_t*pars_commit_statement(void)/*=======================*/{ return(commit_node_create(pars_sym_tab_global->heap));}/*************************************************************************Parses a rollback statement. */roll_node_t*pars_rollback_statement(void)/*=========================*/{ return(roll_node_create(pars_sym_tab_global->heap));}/*************************************************************************Parses a column definition at a table creation. */sym_node_t*pars_column_def(/*============*/ /* out: column sym table node */ sym_node_t* sym_node, /* in: column node in the symbol table */ pars_res_word_t* type) /* in: data type */{ pars_set_dfield_type(que_node_get_val(sym_node), type); return(sym_node);}/*************************************************************************Parses a table creation operation. */tab_node_t*pars_create_table(/*==============*/ /* out: table create subgraph */ sym_node_t* table_sym, /* in: table name node in the symbol table */ sym_node_t* column_defs, /* in: list of column names */ void* not_fit_in_memory)/* in: a non-NULL pointer means that this is a table which in simulations should be simulated as not fitting in memory; thread is put to sleep to simulate disk accesses; NOTE that this flag is not stored to the data dictionary on disk, and the database will forget about non-NULL value if it has to reload the table definition from disk */{ dict_table_t* table; sym_node_t* column; tab_node_t* node; dtype_t* dtype; ulint n_cols; n_cols = que_node_list_get_len(column_defs); /* As the InnoDB SQL parser is for internal use only, for creating some system tables, this function will only create tables in the old (not compact) record format. */ table = dict_mem_table_create(table_sym->name, 0, n_cols, FALSE); if (not_fit_in_memory != NULL) { table->does_not_fit_in_memory = TRUE; } column = column_defs; while (column) { dtype = dfield_get_type(que_node_get_val(column)); dict_mem_table_add_col(table, column->name, dtype->mtype, dtype->prtype, dtype->len, dtype->prec); column->resolved = TRUE; column->token_type = SYM_COLUMN; column = que_node_get_next(column); } node = tab_create_graph_create(table, pars_sym_tab_global->heap); table_sym->resolved = TRUE; table_sym->token_type = SYM_TABLE; return(node);}/*************************************************************************Parses an index creation operation. */ind_node_t*pars_create_index(/*==============*/ /* out: index create subgraph */ pars_res_word_t* unique_def, /* in: not NULL if a unique index */ pars_res_word_t* clustered_def, /* in: not NULL if a clustered index */ sym_node_t* index_sym, /* in: index name node in the symbol table */ sym_node_t* table_sym, /* in: table name node in the symbol table */ sym_node_t* column_list) /* in: list of column names */{ dict_index_t* index; sym_node_t* column; ind_node_t* node; ulint n_fields; ulint ind_type; n_fields = que_node_list_get_len(column_list); ind_type = 0; if (unique_def) { ind_type = ind_type | DICT_UNIQUE; } if (clustered_def) { ind_type = ind_type | DICT_CLUSTERED; } index = dict_mem_index_create(table_sym->name, index_sym->name, 0, ind_type, n_fields); column = column_list; while (column) { dict_mem_index_add_field(index, column->name, 0, 0); column->resolved = TRUE; column->token_type = SYM_COLUMN; column = que_node_get_next(column); } node = ind_create_graph_create(index, pars_sym_tab_global->heap); table_sym->resolved = TRUE; table_sym->token_type = SYM_TABLE; index_sym->resolved = TRUE; index_sym->token_type = SYM_TABLE; return(node);}/*************************************************************************Parses a procedure definition. */que_fork_t*pars_procedure_definition(/*======================*/ /* out: query fork node */ sym_node_t* sym_node, /* in: procedure id node in the symbol table */ sym_node_t* param_list, /* in: parameter declaration list */ que_node_t* stat_list) /* in: statement list */{ proc_node_t* node; que_fork_t* fork; que_thr_t* thr; mem_heap_t* heap; heap = pars_sym_tab_global->heap; fork = que_fork_create(NULL, NULL, QUE_FORK_PROCEDURE, heap); fork->trx = NULL; thr = que_thr_create(fork, heap); node = mem_heap_alloc(heap, sizeof(proc_node_t)); node->common.type = QUE_NODE_PROC; node->common.parent = thr; sym_node->token_type = SYM_PROCEDURE_NAME; sym_node->resolved = TRUE; node->proc_id = sym_node; node->param_list = param_list; node->stat_list = stat_list; pars_set_parent_in_list(stat_list, node); node->sym_tab = pars_sym_tab_global; thr->child = node; pars_sym_tab_global->query_graph = fork; return(fork);}/*****************************************************************Parses a stored procedure call, when this is not within another storedprocedure, that is, the client issues a procedure call directly.In MySQL/InnoDB, stored InnoDB procedures are invoked via theparsed procedure tree, not via InnoDB SQL, so this function is not used. */que_fork_t*pars_stored_procedure_call(/*=======================*/ /* out: query graph */ sym_node_t* sym_node __attribute__((unused))) /* in: stored procedure name */{ ut_error; return(NULL);}/*****************************************************************Retrieves characters to the lexical analyzer. */voidpars_get_lex_chars(/*===============*/ char* buf, /* in/out: buffer where to copy */ int* result, /* out: number of characters copied or EOF */ int max_size) /* in: maximum number of characters which fit in the buffer */{ int len; len = pars_sym_tab_global->string_len - pars_sym_tab_global->next_char_pos; if (len == 0) {#ifdef YYDEBUG /* fputs("SQL string ends\n", stderr); */#endif *result = 0; return; } if (len > max_size) { len = max_size; }#ifdef UNIV_SQL_DEBUG if (pars_print_lexed) { if (len >= 5) { len = 5; } fwrite(pars_sym_tab_global->sql_string + pars_sym_tab_global->next_char_pos, 1, len, stderr); }#endif /* UNIV_SQL_DEBUG */ ut_memcpy(buf, pars_sym_tab_global->sql_string + pars_sym_tab_global->next_char_pos, len); *result = len; pars_sym_tab_global->next_char_pos += len;}/*****************************************************************Called by yyparse on error. */voidyyerror(/*====*/ const char* s __attribute__((unused))) /* in: error message string */{ ut_ad(s); fputs("PARSER ERROR: Syntax error in SQL string\n", stderr); ut_error;}/*****************************************************************Parses an SQL string returning the query graph. */que_t*pars_sql(/*=====*/ /* out, own: the query graph */ const char* str) /* in: SQL string */{ sym_node_t* sym_node; mem_heap_t* heap; que_t* graph; ut_ad(str); heap = mem_heap_create(256);#ifdef UNIV_SYNC_DEBUG /* Currently, the parser is not reentrant: */ ut_ad(mutex_own(&(dict_sys->mutex)));#endif /* UNIV_SYNC_DEBUG */ pars_sym_tab_global = sym_tab_create(heap); pars_sym_tab_global->sql_string = mem_heap_strdup(heap, str); pars_sym_tab_global->string_len = strlen(str); pars_sym_tab_global->next_char_pos = 0; yyparse(); sym_node = UT_LIST_GET_FIRST(pars_sym_tab_global->sym_list); while (sym_node) { ut_a(sym_node->resolved); sym_node = UT_LIST_GET_NEXT(sym_list, sym_node); } graph = pars_sym_tab_global->query_graph; graph->sym_tab = pars_sym_tab_global; /* fprintf(stderr, "SQL graph size %lu\n", mem_heap_get_size(heap)); */ return(graph);}/**********************************************************************Completes a query graph by adding query thread and fork nodesabove it and prepares the graph for running. The fork created is oftype QUE_FORK_MYSQL_INTERFACE. */que_thr_t*pars_complete_graph_for_exec(/*=========================*/ /* out: query thread node to run */ que_node_t* node, /* in: root node for an incomplete query graph */ trx_t* trx, /* in: transaction handle */ mem_heap_t* heap) /* in: memory heap from which allocated */{ que_fork_t* fork; que_thr_t* thr; fork = que_fork_create(NULL, NULL, QUE_FORK_MYSQL_INTERFACE, heap); fork->trx = trx; thr = que_thr_create(fork, heap); thr->child = node; que_node_set_parent(node, thr); trx->graph = NULL; return(thr);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -