Loading sql/log_event.cc +2 −2 Original line number Diff line number Diff line Loading @@ -3114,8 +3114,8 @@ int Load_log_event::exec_event(NET* net, struct st_relay_log_info* rli, ex.skip_lines = skip_lines; List<Item> field_list; thd->main_lex.select_lex.context.resolve_in_table_list_only(&tables); set_fields(tables.db, field_list, &thd->main_lex.select_lex.context); thd->lex->select_lex.context.resolve_in_table_list_only(&tables); set_fields(tables.db, field_list, &thd->lex->select_lex.context); thd->variables.pseudo_thread_id= thread_id; if (net) { Loading sql/mysqld.cc +0 −12 Original line number Diff line number Diff line Loading @@ -1598,18 +1598,6 @@ static void network_init(void) #endif /*!EMBEDDED_LIBRARY*/ void MYSQLerror(const char *s) { THD *thd=current_thd; char *yytext= (char*) thd->lex->tok_start; /* "parse error" changed into "syntax error" between bison 1.75 and 1.875 */ if (strcmp(s,"parse error") == 0 || strcmp(s,"syntax error") == 0) s=ER(ER_SYNTAX_ERROR); my_printf_error(ER_PARSE_ERROR, ER(ER_PARSE_ERROR), MYF(0), s, (yytext ? (char*) yytext : ""), thd->lex->yylineno); } #ifndef EMBEDDED_LIBRARY /* Loading sql/sql_class.cc +14 −18 Original line number Diff line number Diff line Loading @@ -166,14 +166,10 @@ Open_tables_state::Open_tables_state(ulong version_arg) } /* Pass nominal parameters to Statement constructor only to ensure that the destructor works OK in case of error. The main_mem_root will be re-initialized in init(). */ THD::THD() :Statement(CONVENTIONAL_EXECUTION, 0, ALLOC_ROOT_MIN_BLOCK_SIZE, 0), :Statement(&main_lex, &main_mem_root, CONVENTIONAL_EXECUTION, /* statement id */ 0), Open_tables_state(refresh_version), lock_id(&main_lock_id), user_time(0), in_sub_stmt(0), global_read_lock(0), is_fatal_error(0), Loading @@ -184,6 +180,12 @@ THD::THD() { ulong tmp; /* Pass nominal parameters to init_alloc_root only to ensure that the destructor works OK in case of an error. The main_mem_root will be re-initialized in init_for_queries(). */ init_sql_alloc(&main_mem_root, ALLOC_ROOT_MIN_BLOCK_SIZE, 0); stmt_arena= this; thread_stack= 0; db= 0; Loading Loading @@ -475,6 +477,7 @@ THD::~THD() #ifndef DBUG_OFF dbug_sentry= THD_SENTRY_GONE; #endif free_root(&main_mem_root, MYF(0)); DBUG_VOID_RETURN; } Loading Loading @@ -1613,18 +1616,17 @@ void Query_arena::cleanup_stmt() Statement functions */ Statement::Statement(enum enum_state state_arg, ulong id_arg, ulong alloc_block_size, ulong prealloc_size) :Query_arena(&main_mem_root, state_arg), Statement::Statement(LEX *lex_arg, MEM_ROOT *mem_root_arg, enum enum_state state_arg, ulong id_arg) :Query_arena(mem_root_arg, state_arg), id(id_arg), set_query_id(1), lex(&main_lex), lex(lex_arg), query(0), query_length(0), cursor(0) { name.str= NULL; init_sql_alloc(&main_mem_root, alloc_block_size, prealloc_size); } Loading Loading @@ -1666,7 +1668,7 @@ void Statement::restore_backup_statement(Statement *stmt, Statement *backup) void THD::end_statement() { /* Cleanup SQL processing state to resuse this statement in next query. */ /* Cleanup SQL processing state to reuse this statement in next query. */ lex_end(lex); delete lex->result; lex->result= 0; Loading Loading @@ -1707,12 +1709,6 @@ void THD::restore_active_arena(Query_arena *set, Query_arena *backup) Statement::~Statement() { /* We must free `main_mem_root', not `mem_root' (pointer), to work correctly if this statement is used as a backup statement, for which `mem_root' may point to some other statement. */ free_root(&main_mem_root, MYF(0)); } C_MODE_START Loading sql/sql_class.h +38 −16 Original line number Diff line number Diff line Loading @@ -753,8 +753,10 @@ class Query_arena class Server_side_cursor; /* State of a single command executed against this connection. /** @class Statement @brief State of a single command executed against this connection. One connection can contain a lot of simultaneously running statements, some of which could be: - prepared, that is, contain placeholders, Loading @@ -772,10 +774,6 @@ class Statement: public ilink, public Query_arena Statement(const Statement &rhs); /* not implemented: */ Statement &operator=(const Statement &rhs); /* non-copyable */ public: /* FIXME: these must be protected */ MEM_ROOT main_mem_root; LEX main_lex; /* Uniquely identifies each statement object in thread scope; change during statement lifetime. FIXME: must be const Loading Loading @@ -819,10 +817,10 @@ class Statement: public ilink, public Query_arena public: /* This constructor is called for backup statements */ Statement() { clear_alloc_root(&main_mem_root); } Statement() {} Statement(enum enum_state state_arg, ulong id_arg, ulong alloc_block_size, ulong prealloc_size); Statement(LEX *lex_arg, MEM_ROOT *mem_root_arg, enum enum_state state_arg, ulong id_arg); virtual ~Statement(); /* Assign execution context (note: not all members) of given stmt to self */ Loading @@ -834,7 +832,7 @@ class Statement: public ilink, public Query_arena }; /* /** Container for all statements created/used in a connection. Statements in Statement_map have unique Statement::id (guaranteed by id assignment in Statement::Statement) Loading Loading @@ -914,6 +912,10 @@ bool xid_cache_insert(XID *xid, enum xa_states xa_state); bool xid_cache_insert(XID_STATE *xid_state); void xid_cache_delete(XID_STATE *xid_state); /** @class Security_context @brief A set of THD members describing the current authenticated user. */ class Security_context { public: Loading Loading @@ -943,7 +945,7 @@ class Security_context { }; /* /** A registry for item tree transformations performed during query optimization. We register only those changes which require a rollback to re-execute a prepared statement or stored procedure Loading @@ -954,7 +956,7 @@ struct Item_change_record; typedef I_List<Item_change_record> Item_change_list; /* /** Type of prelocked mode. See comment for THD::prelocked_mode for complete description. */ Loading @@ -963,7 +965,7 @@ enum prelocked_mode_type {NON_PRELOCKED= 0, PRELOCKED= 1, PRELOCKED_UNDER_LOCK_TABLES= 2}; /* /** Class that holds information about tables which were opened and locked by the thread. It is also used to save/restore this information in push_open_tables_state()/pop_open_tables_state(). Loading Loading @@ -1048,14 +1050,17 @@ class Open_tables_state } }; /* class to save context when executing a function or trigger */ /** @class Sub_statement_state @brief Used to save context when executing a function or trigger */ /* Defines used for Sub_statement_state::in_sub_stmt */ #define SUB_STMT_TRIGGER 1 #define SUB_STMT_FUNCTION 2 class Sub_statement_state { public: Loading Loading @@ -1114,7 +1119,8 @@ class Internal_error_handler }; /* /** @class THD For each client connection we create a separate thread with THD serving as a thread/connection descriptor */ Loading Loading @@ -1726,6 +1732,22 @@ class THD :public Statement, private: /** The current internal error handler for this thread, or NULL. */ Internal_error_handler *m_internal_handler; /** The lex to hold the parsed tree of conventional (non-prepared) queries. Whereas for prepared and stored procedure statements we use an own lex instance for each new query, for conventional statements we reuse the same lex. (@see mysql_parse for details). */ LEX main_lex; /** This memory root is used for two purposes: - for conventional queries, to allocate structures stored in main_lex during parsing, and allocate runtime data (execution plan, etc.) during execution. - for prepared queries, only to allocate runtime data. The parsed tree itself is reused between executions and thus is stored elsewhere. */ MEM_ROOT main_mem_root; }; Loading sql/sql_lex.cc +30 −0 Original line number Diff line number Diff line Loading @@ -1648,6 +1648,36 @@ void st_select_lex::print_limit(THD *thd, String *str) } } /** @brief Restore the LEX and THD in case of a parse error. This is a clean up call that is invoked by the Bison generated parser before returning an error from MYSQLparse. If your semantic actions manipulate with the global thread state (which is a very bad practice and should not normally be employed) and need a clean-up in case of error, and you can not use %destructor rule in the grammar file itself, this function should be used to implement the clean up. */ void st_lex::cleanup_lex_after_parse_error(THD *thd) { /* Delete sphead for the side effect of restoring of the original LEX state, thd->lex, thd->mem_root and thd->free_list if they were replaced when parsing stored procedure statements. We will never use sphead object after a parse error, so it's okay to delete it only for the sake of the side effect. TODO: make this functionality explicit in sp_head class. Sic: we must nullify the member of the main lex, not the current one that will be thrown away */ if (thd->lex->sphead); { delete thd->lex->sphead; thd->lex->sphead= NULL; } } /* Initialize (or reset) Query_tables_list object. Loading Loading
sql/log_event.cc +2 −2 Original line number Diff line number Diff line Loading @@ -3114,8 +3114,8 @@ int Load_log_event::exec_event(NET* net, struct st_relay_log_info* rli, ex.skip_lines = skip_lines; List<Item> field_list; thd->main_lex.select_lex.context.resolve_in_table_list_only(&tables); set_fields(tables.db, field_list, &thd->main_lex.select_lex.context); thd->lex->select_lex.context.resolve_in_table_list_only(&tables); set_fields(tables.db, field_list, &thd->lex->select_lex.context); thd->variables.pseudo_thread_id= thread_id; if (net) { Loading
sql/mysqld.cc +0 −12 Original line number Diff line number Diff line Loading @@ -1598,18 +1598,6 @@ static void network_init(void) #endif /*!EMBEDDED_LIBRARY*/ void MYSQLerror(const char *s) { THD *thd=current_thd; char *yytext= (char*) thd->lex->tok_start; /* "parse error" changed into "syntax error" between bison 1.75 and 1.875 */ if (strcmp(s,"parse error") == 0 || strcmp(s,"syntax error") == 0) s=ER(ER_SYNTAX_ERROR); my_printf_error(ER_PARSE_ERROR, ER(ER_PARSE_ERROR), MYF(0), s, (yytext ? (char*) yytext : ""), thd->lex->yylineno); } #ifndef EMBEDDED_LIBRARY /* Loading
sql/sql_class.cc +14 −18 Original line number Diff line number Diff line Loading @@ -166,14 +166,10 @@ Open_tables_state::Open_tables_state(ulong version_arg) } /* Pass nominal parameters to Statement constructor only to ensure that the destructor works OK in case of error. The main_mem_root will be re-initialized in init(). */ THD::THD() :Statement(CONVENTIONAL_EXECUTION, 0, ALLOC_ROOT_MIN_BLOCK_SIZE, 0), :Statement(&main_lex, &main_mem_root, CONVENTIONAL_EXECUTION, /* statement id */ 0), Open_tables_state(refresh_version), lock_id(&main_lock_id), user_time(0), in_sub_stmt(0), global_read_lock(0), is_fatal_error(0), Loading @@ -184,6 +180,12 @@ THD::THD() { ulong tmp; /* Pass nominal parameters to init_alloc_root only to ensure that the destructor works OK in case of an error. The main_mem_root will be re-initialized in init_for_queries(). */ init_sql_alloc(&main_mem_root, ALLOC_ROOT_MIN_BLOCK_SIZE, 0); stmt_arena= this; thread_stack= 0; db= 0; Loading Loading @@ -475,6 +477,7 @@ THD::~THD() #ifndef DBUG_OFF dbug_sentry= THD_SENTRY_GONE; #endif free_root(&main_mem_root, MYF(0)); DBUG_VOID_RETURN; } Loading Loading @@ -1613,18 +1616,17 @@ void Query_arena::cleanup_stmt() Statement functions */ Statement::Statement(enum enum_state state_arg, ulong id_arg, ulong alloc_block_size, ulong prealloc_size) :Query_arena(&main_mem_root, state_arg), Statement::Statement(LEX *lex_arg, MEM_ROOT *mem_root_arg, enum enum_state state_arg, ulong id_arg) :Query_arena(mem_root_arg, state_arg), id(id_arg), set_query_id(1), lex(&main_lex), lex(lex_arg), query(0), query_length(0), cursor(0) { name.str= NULL; init_sql_alloc(&main_mem_root, alloc_block_size, prealloc_size); } Loading Loading @@ -1666,7 +1668,7 @@ void Statement::restore_backup_statement(Statement *stmt, Statement *backup) void THD::end_statement() { /* Cleanup SQL processing state to resuse this statement in next query. */ /* Cleanup SQL processing state to reuse this statement in next query. */ lex_end(lex); delete lex->result; lex->result= 0; Loading Loading @@ -1707,12 +1709,6 @@ void THD::restore_active_arena(Query_arena *set, Query_arena *backup) Statement::~Statement() { /* We must free `main_mem_root', not `mem_root' (pointer), to work correctly if this statement is used as a backup statement, for which `mem_root' may point to some other statement. */ free_root(&main_mem_root, MYF(0)); } C_MODE_START Loading
sql/sql_class.h +38 −16 Original line number Diff line number Diff line Loading @@ -753,8 +753,10 @@ class Query_arena class Server_side_cursor; /* State of a single command executed against this connection. /** @class Statement @brief State of a single command executed against this connection. One connection can contain a lot of simultaneously running statements, some of which could be: - prepared, that is, contain placeholders, Loading @@ -772,10 +774,6 @@ class Statement: public ilink, public Query_arena Statement(const Statement &rhs); /* not implemented: */ Statement &operator=(const Statement &rhs); /* non-copyable */ public: /* FIXME: these must be protected */ MEM_ROOT main_mem_root; LEX main_lex; /* Uniquely identifies each statement object in thread scope; change during statement lifetime. FIXME: must be const Loading Loading @@ -819,10 +817,10 @@ class Statement: public ilink, public Query_arena public: /* This constructor is called for backup statements */ Statement() { clear_alloc_root(&main_mem_root); } Statement() {} Statement(enum enum_state state_arg, ulong id_arg, ulong alloc_block_size, ulong prealloc_size); Statement(LEX *lex_arg, MEM_ROOT *mem_root_arg, enum enum_state state_arg, ulong id_arg); virtual ~Statement(); /* Assign execution context (note: not all members) of given stmt to self */ Loading @@ -834,7 +832,7 @@ class Statement: public ilink, public Query_arena }; /* /** Container for all statements created/used in a connection. Statements in Statement_map have unique Statement::id (guaranteed by id assignment in Statement::Statement) Loading Loading @@ -914,6 +912,10 @@ bool xid_cache_insert(XID *xid, enum xa_states xa_state); bool xid_cache_insert(XID_STATE *xid_state); void xid_cache_delete(XID_STATE *xid_state); /** @class Security_context @brief A set of THD members describing the current authenticated user. */ class Security_context { public: Loading Loading @@ -943,7 +945,7 @@ class Security_context { }; /* /** A registry for item tree transformations performed during query optimization. We register only those changes which require a rollback to re-execute a prepared statement or stored procedure Loading @@ -954,7 +956,7 @@ struct Item_change_record; typedef I_List<Item_change_record> Item_change_list; /* /** Type of prelocked mode. See comment for THD::prelocked_mode for complete description. */ Loading @@ -963,7 +965,7 @@ enum prelocked_mode_type {NON_PRELOCKED= 0, PRELOCKED= 1, PRELOCKED_UNDER_LOCK_TABLES= 2}; /* /** Class that holds information about tables which were opened and locked by the thread. It is also used to save/restore this information in push_open_tables_state()/pop_open_tables_state(). Loading Loading @@ -1048,14 +1050,17 @@ class Open_tables_state } }; /* class to save context when executing a function or trigger */ /** @class Sub_statement_state @brief Used to save context when executing a function or trigger */ /* Defines used for Sub_statement_state::in_sub_stmt */ #define SUB_STMT_TRIGGER 1 #define SUB_STMT_FUNCTION 2 class Sub_statement_state { public: Loading Loading @@ -1114,7 +1119,8 @@ class Internal_error_handler }; /* /** @class THD For each client connection we create a separate thread with THD serving as a thread/connection descriptor */ Loading Loading @@ -1726,6 +1732,22 @@ class THD :public Statement, private: /** The current internal error handler for this thread, or NULL. */ Internal_error_handler *m_internal_handler; /** The lex to hold the parsed tree of conventional (non-prepared) queries. Whereas for prepared and stored procedure statements we use an own lex instance for each new query, for conventional statements we reuse the same lex. (@see mysql_parse for details). */ LEX main_lex; /** This memory root is used for two purposes: - for conventional queries, to allocate structures stored in main_lex during parsing, and allocate runtime data (execution plan, etc.) during execution. - for prepared queries, only to allocate runtime data. The parsed tree itself is reused between executions and thus is stored elsewhere. */ MEM_ROOT main_mem_root; }; Loading
sql/sql_lex.cc +30 −0 Original line number Diff line number Diff line Loading @@ -1648,6 +1648,36 @@ void st_select_lex::print_limit(THD *thd, String *str) } } /** @brief Restore the LEX and THD in case of a parse error. This is a clean up call that is invoked by the Bison generated parser before returning an error from MYSQLparse. If your semantic actions manipulate with the global thread state (which is a very bad practice and should not normally be employed) and need a clean-up in case of error, and you can not use %destructor rule in the grammar file itself, this function should be used to implement the clean up. */ void st_lex::cleanup_lex_after_parse_error(THD *thd) { /* Delete sphead for the side effect of restoring of the original LEX state, thd->lex, thd->mem_root and thd->free_list if they were replaced when parsing stored procedure statements. We will never use sphead object after a parse error, so it's okay to delete it only for the sake of the side effect. TODO: make this functionality explicit in sp_head class. Sic: we must nullify the member of the main lex, not the current one that will be thrown away */ if (thd->lex->sphead); { delete thd->lex->sphead; thd->lex->sphead= NULL; } } /* Initialize (or reset) Query_tables_list object. Loading