Fixed crash in connect.misc with embedded server

The problem was that connect tried to recusiverly call
emb_advanced_command(), which was not supported.

Fixed by adding support for recursive calls.
This commit is contained in:
Monty 2024-02-26 14:51:27 +02:00
parent 0c079f4f76
commit 89aae15da2
3 changed files with 26 additions and 4 deletions

View file

@ -23,6 +23,8 @@ void init_embedded_mysql(MYSQL *mysql, ulong client_flag);
void *create_embedded_thd(ulong client_flag); void *create_embedded_thd(ulong client_flag);
int check_embedded_connection(MYSQL *mysql, const char *db); int check_embedded_connection(MYSQL *mysql, const char *db);
void free_old_query(MYSQL *mysql); void free_old_query(MYSQL *mysql);
THD *embedded_get_current_thd();
void embedded_set_current_thd(THD *thd);
extern MYSQL_METHODS embedded_methods; extern MYSQL_METHODS embedded_methods;
/* This one is used by embedded library to gather returning data */ /* This one is used by embedded library to gather returning data */

View file

@ -111,7 +111,7 @@ emb_advanced_command(MYSQL *mysql, enum enum_server_command command,
MYSQL_STMT *stmt) MYSQL_STMT *stmt)
{ {
my_bool result= 1; my_bool result= 1;
THD *thd=(THD *) mysql->thd; THD *thd=(THD *) mysql->thd, *old_current_thd= current_thd;
NET *net= &mysql->net; NET *net= &mysql->net;
my_bool stmt_skip= stmt ? stmt->state != MYSQL_STMT_INIT_DONE : FALSE; my_bool stmt_skip= stmt ? stmt->state != MYSQL_STMT_INIT_DONE : FALSE;
@ -122,6 +122,8 @@ emb_advanced_command(MYSQL *mysql, enum enum_server_command command,
else else
{ {
free_embedded_thd(mysql); free_embedded_thd(mysql);
if (old_current_thd == thd)
old_current_thd= 0;
thd= 0; thd= 0;
} }
} }
@ -179,6 +181,8 @@ emb_advanced_command(MYSQL *mysql, enum enum_server_command command,
end: end:
thd->reset_globals(); thd->reset_globals();
if (old_current_thd)
old_current_thd->store_globals();
return result; return result;
} }
@ -432,12 +436,15 @@ int emb_unbuffered_fetch(MYSQL *mysql, char **row)
static void free_embedded_thd(MYSQL *mysql) static void free_embedded_thd(MYSQL *mysql)
{ {
THD *thd= (THD*)mysql->thd; THD *thd= (THD*)mysql->thd, *org_current_thd= current_thd;
server_threads.erase(thd); server_threads.erase(thd);
thd->clear_data_list(); thd->clear_data_list();
thd->store_globals(); thd->store_globals();
delete thd; delete thd;
set_current_thd(nullptr); if (thd == org_current_thd)
set_current_thd(nullptr);
else
set_current_thd(org_current_thd);
mysql->thd=0; mysql->thd=0;
} }
@ -727,6 +734,17 @@ void *create_embedded_thd(ulong client_flag)
} }
THD *embedded_get_current_thd()
{
return current_thd;
}
void embedded_set_current_thd(THD *thd)
{
set_current_thd(thd);
}
#ifdef NO_EMBEDDED_ACCESS_CHECKS #ifdef NO_EMBEDDED_ACCESS_CHECKS
static void static void
emb_transfer_connect_attrs(MYSQL *mysql) emb_transfer_connect_attrs(MYSQL *mysql)

View file

@ -78,7 +78,7 @@ mysql_real_connect(MYSQL *mysql,const char *host, const char *user,
uint port, const char *unix_socket,ulong client_flag) uint port, const char *unix_socket,ulong client_flag)
{ {
char name_buff[USERNAME_LENGTH]; char name_buff[USERNAME_LENGTH];
THD *org_current_thd= embedded_get_current_thd();
DBUG_ENTER("mysql_real_connect"); DBUG_ENTER("mysql_real_connect");
DBUG_PRINT("enter",("host: %s db: %s user: %s (libmysqld)", DBUG_PRINT("enter",("host: %s db: %s user: %s (libmysqld)",
host ? host : "(Null)", host ? host : "(Null)",
@ -200,6 +200,7 @@ mysql_real_connect(MYSQL *mysql,const char *host, const char *user,
} }
} }
} }
embedded_set_current_thd(org_current_thd);
DBUG_PRINT("exit",("Mysql handler: %p", mysql)); DBUG_PRINT("exit",("Mysql handler: %p", mysql));
DBUG_RETURN(mysql); DBUG_RETURN(mysql);
@ -216,6 +217,7 @@ error:
mysql_close(mysql); mysql_close(mysql);
mysql->free_me=free_me; mysql->free_me=free_me;
} }
embedded_set_current_thd(org_current_thd);
DBUG_RETURN(0); DBUG_RETURN(0);
} }