diff --git a/include/mysql.h b/include/mysql.h index 57ae0c3da408b5ef6198e1c939b55f2a000ac70c..2e2558d7183e34930500c562a367d63aa9326571 100644 --- a/include/mysql.h +++ b/include/mysql.h @@ -502,10 +502,12 @@ my_bool STDCALL mysql_send_long_data(MYSQL_STMT *stmt, my_bool last_data); int STDCALL mysql_multi_query(MYSQL *mysql,const char *query, unsigned long len); -MYSQL_RES *STDCALL mysql_next_result(MYSQL *mysql); MYSQL_RES *STDCALL mysql_prepare_result(MYSQL_STMT *stmt); my_ulonglong STDCALL mysql_stmt_affected_rows(MYSQL_STMT *stmt); int STDCALL mysql_stmt_store_result(MYSQL_STMT *stmt); +my_bool STDCALL mysql_more_results(MYSQL *mysql); +my_bool STDCALL mysql_next_result(MYSQL *mysql); + /* new status messages */ diff --git a/include/mysql_com.h b/include/mysql_com.h index 8716ef3a58f02ac060172e75a1ce68b137066e3e..ee3e026dae74ee43b224656ced1d934e87aebfb0 100644 --- a/include/mysql_com.h +++ b/include/mysql_com.h @@ -106,10 +106,12 @@ enum enum_server_command #define CLIENT_TRANSACTIONS 8192 /* Client knows about transactions */ #define CLIENT_PROTOCOL_41 16384 /* New 4.1 protocol */ #define CLIENT_SECURE_CONNECTION 32768 /* New 4.1 authentication */ +#define CLIENT_MULTI_QUERIES 65536 /* Enable/disable multi query support */ #define SERVER_STATUS_IN_TRANS 1 /* Transaction has started */ #define SERVER_STATUS_AUTOCOMMIT 2 /* Server in auto_commit mode */ #define SERVER_STATUS_MORE_RESULTS 4 /* More results on server */ +#define SERVER_MORE_RESULTS_EXISTS 8 /* Multi query - next query exists */ #define MYSQL_ERRMSG_SIZE 200 #define NET_READ_TIMEOUT 30 /* Timeout on read */ diff --git a/libmysql/libmysql.c b/libmysql/libmysql.c index a2bd668aca9ac56de6da109e4085f15f070f0bb6..af521512020ab02c3ed3dc9551acf307ebd30b76 100644 --- a/libmysql/libmysql.c +++ b/libmysql/libmysql.c @@ -3858,8 +3858,8 @@ static my_bool read_prepare_result(MYSQL_STMT *stmt) } if (!(stmt->params= (MYSQL_BIND *) alloc_root(&stmt->mem_root, sizeof(MYSQL_BIND)* - (stmt->param_count + - field_count)))) + (param_count + + field_count)))) { set_stmt_error(stmt, CR_OUT_OF_MEMORY); DBUG_RETURN(0); @@ -5161,3 +5161,36 @@ my_bool STDCALL mysql_autocommit(MYSQL * mysql, my_bool auto_mode) DBUG_RETURN((my_bool) mysql_real_query(mysql, "set autocommit=1", 16)); DBUG_RETURN((my_bool) mysql_real_query(mysql, "set autocommit=0", 16)); } + + +/******************************************************************** + Multi query execution related implementations +*********************************************************************/ + +/* + Returns if there are any more query results exists to be read using + mysql_next_result() +*/ + +my_bool STDCALL mysql_more_results(MYSQL *mysql) +{ + if (mysql->last_used_con->server_status & SERVER_MORE_RESULTS_EXISTS) + return 1; + return 0; +} + +/* + Reads and returns the next query results +*/ + +my_bool STDCALL mysql_next_result(MYSQL *mysql) +{ + + mysql->net.last_error[0]=0; + mysql->net.last_errno=0; + mysql->affected_rows= ~(my_ulonglong) 0; + + if (mysql->last_used_con->server_status & SERVER_MORE_RESULTS_EXISTS) + return mysql_read_query_result(mysql); + return 0; +} diff --git a/sql/sql_lex.cc b/sql/sql_lex.cc index 23b207b252cb7168ff22c5870e0c289f4aaa9434..e4fc3a5aec3792bf53813a6b45cef909e597847e 100644 --- a/sql/sql_lex.cc +++ b/sql/sql_lex.cc @@ -906,7 +906,15 @@ int yylex(void *arg, void *yythd) case STATE_COLON: // optional line terminator if (yyPeek()) { - state=STATE_CHAR; // Return ';' + if (((THD *)yythd)->client_capabilities & CLIENT_MULTI_QUERIES) + { + lex->found_colon=(char*)lex->ptr; + ((THD *)yythd)->server_status |= SERVER_MORE_RESULTS_EXISTS; + lex->next_state=STATE_END; + return(END_OF_INPUT); + } + else + state=STATE_CHAR; // Return ';' break; } /* fall true */ diff --git a/sql/sql_lex.h b/sql/sql_lex.h index 5c1c91bbe4ab38c57b43357a789400b5a18df253..9fc00e5f56dfad70435aa1cadcf3af07002d1cdc 100644 --- a/sql/sql_lex.h +++ b/sql/sql_lex.h @@ -414,6 +414,7 @@ typedef struct st_lex char *backup_dir; /* For RESTORE/BACKUP */ char* to_log; /* For PURGE MASTER LOGS TO */ char* x509_subject,*x509_issuer,*ssl_cipher; + char* found_colon; /* For multi queries - next query */ enum SSL_type ssl_type; /* defined in violite.h */ String *wild; sql_exchange *exchange; diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc index 8c76118a526f3fbb55ae7fffc1d44d8b549553f1..2af124353e9a6e4e2f9a93067516a31363e866eb 100644 --- a/sql/sql_parse.cc +++ b/sql/sql_parse.cc @@ -1426,6 +1426,14 @@ bool dispatch_command(enum enum_server_command command, THD *thd, mysql_slow_log.write(thd, thd->query, thd->query_length, start_of_query); } } + if (command == COM_QUERY && thd->lex.found_colon) + { + /* + Multiple queries exits, execute them individually + */ + uint length= thd->query_length-(uint)(thd->lex.found_colon-thd->query)+1; + dispatch_command(command, thd, thd->lex.found_colon, length); + } thd->proc_info="cleaning up"; VOID(pthread_mutex_lock(&LOCK_thread_count)); // For process list thd->proc_info=0; @@ -3082,6 +3090,7 @@ mysql_init_query(THD *thd) lex->olap=lex->describe=0; lex->derived_tables= false; lex->lock_option=TL_READ; + lex->found_colon=0; thd->check_loops_counter= thd->select_number= lex->select_lex.select_number= 1; thd->free_list= 0; @@ -3090,6 +3099,7 @@ mysql_init_query(THD *thd) thd->sent_row_count= thd->examined_row_count= 0; thd->fatal_error= thd->rand_used= 0; thd->possible_loops= 0; + thd->server_status &= ~SERVER_MORE_RESULTS_EXISTS; DBUG_VOID_RETURN; }