diff options
Diffstat (limited to 'sql-common/client.c')
-rw-r--r-- | sql-common/client.c | 149 |
1 files changed, 81 insertions, 68 deletions
diff --git a/sql-common/client.c b/sql-common/client.c index 57653203149..6db20153eaa 100644 --- a/sql-common/client.c +++ b/sql-common/client.c @@ -128,6 +128,7 @@ const char *def_shared_memory_base_name= default_shared_memory_base_name; static void mysql_close_free_options(MYSQL *mysql); static void mysql_close_free(MYSQL *mysql); static void mysql_prune_stmt_list(MYSQL *mysql); +static int cli_report_progress(MYSQL *mysql, uchar *packet, uint length); #if !defined(__WIN__) static int wait_for_data(my_socket fd, uint timeout); @@ -731,6 +732,7 @@ cli_safe_read(MYSQL *mysql) NET *net= &mysql->net; ulong len=0; +restart: if (net->vio != 0) len=my_net_read(net); @@ -751,13 +753,27 @@ cli_safe_read(MYSQL *mysql) { if (len > 3) { - char *pos=(char*) net->read_pos+1; - net->last_errno=uint2korr(pos); + uchar *pos= net->read_pos+1; + uint last_errno=uint2korr(pos); + + if (last_errno == 65535 && + (mysql->server_capabilities & CLIENT_PROGRESS)) + { + if (cli_report_progress(mysql, pos+2, (uint) (len-3))) + { + /* Wrong packet */ + set_mysql_error(mysql, CR_MALFORMED_PACKET, unknown_sqlstate); + return (packet_error); + } + goto restart; + } + net->last_errno= last_errno; + pos+=2; len-=2; - if (protocol_41(mysql) && pos[0] == '#') + if (protocol_41(mysql) && (char) pos[0] == '#') { - strmake(net->sqlstate, pos+1, SQLSTATE_LENGTH); + strmake(net->sqlstate, (char*) pos+1, SQLSTATE_LENGTH); pos+= SQLSTATE_LENGTH+1; } else @@ -1010,6 +1026,40 @@ static void cli_flush_use_result(MYSQL *mysql, my_bool flush_all_results) } +/* + Report progress to the client + + RETURN VALUES + 0 ok + 1 error +*/ + +static int cli_report_progress(MYSQL *mysql, uchar *packet, uint length) +{ + uint stage, max_stage, proc_length; + double progress; + uchar *start= packet; + + if (length < 5) + return 1; /* Wrong packet */ + + if (!(mysql->options.extension && mysql->options.extension->report_progress)) + return 0; /* No callback, ignore packet */ + + packet++; /* Ignore number of strings */ + stage= (uint) *packet++; + max_stage= (uint) *packet++; + progress= uint3korr(packet)/1000.0; + packet+= 3; + proc_length= net_field_length(&packet); + if (packet + proc_length > start + length) + return 1; /* Wrong packet */ + (*mysql->options.extension->report_progress)(mysql, stage, max_stage, + progress, (char*) packet, + proc_length); + return 0; +} + #ifdef __WIN__ static my_bool is_NT(void) { @@ -1018,57 +1068,6 @@ static my_bool is_NT(void) } #endif - -#ifdef CHECK_LICENSE -/** - Check server side variable 'license'. - - If the variable does not exist or does not contain 'Commercial', - we're talking to non-commercial server from commercial client. - - @retval 0 success - @retval !0 network error or the server is not commercial. - Error code is saved in mysql->net.last_errno. -*/ - -static int check_license(MYSQL *mysql) -{ - MYSQL_ROW row; - MYSQL_RES *res; - NET *net= &mysql->net; - static const char query[]= "SELECT @@license"; - static const char required_license[]= STRINGIFY_ARG(LICENSE); - - if (mysql_real_query(mysql, query, sizeof(query)-1)) - { - if (net->last_errno == ER_UNKNOWN_SYSTEM_VARIABLE) - { - set_mysql_extended_error(mysql, CR_WRONG_LICENSE, unknown_sqlstate, - ER(CR_WRONG_LICENSE), required_license); - } - return 1; - } - if (!(res= mysql_use_result(mysql))) - return 1; - row= mysql_fetch_row(res); - /* - If no rows in result set, or column value is NULL (none of these - two is ever true for server variables now), or column value - mismatch, set wrong license error. - */ - if (!net->last_errno && - (!row || !row[0] || - strncmp(row[0], required_license, sizeof(required_license)))) - { - set_mysql_extended_error(mysql, CR_WRONG_LICENSE, unknown_sqlstate, - ER(CR_WRONG_LICENSE), required_license); - } - mysql_free_result(res); - return net->last_errno; -} -#endif /* CHECK_LICENSE */ - - /************************************************************************** Shut down connection **************************************************************************/ @@ -1180,21 +1179,24 @@ static int add_init_command(struct st_mysql_options *options, const char *cmd) return 0; } -#define EXTENSION_SET_STRING(OPTS, X, STR) \ - if ((OPTS)->extension) \ - my_free((OPTS)->extension->X); \ - else \ +#define EXTENSION_SET(OPTS, X, VAL) \ + if (!(OPTS)->extension) \ (OPTS)->extension= (struct st_mysql_options_extention *) \ my_malloc(sizeof(struct st_mysql_options_extention), \ MYF(MY_WME | MY_ZEROFILL)); \ - (OPTS)->extension->X= my_strdup((STR), MYF(MY_WME)); + (OPTS)->extension->X= VAL; + +#define EXTENSION_SET_STRING(OPTS, X, STR) \ + if ((OPTS)->extension) \ + my_free((OPTS)->extension->X); \ + EXTENSION_SET(OPTS, X, my_strdup((STR), MYF(MY_WME))); void mysql_read_default_options(struct st_mysql_options *options, const char *filename,const char *group) { int argc; char *argv_buff[1],**argv; - const char *groups[3]; + const char *groups[5]; DBUG_ENTER("mysql_read_default_options"); DBUG_PRINT("enter",("file: %s group: %s",filename,group ? group :"NULL")); @@ -1202,7 +1204,11 @@ void mysql_read_default_options(struct st_mysql_options *options, array_elements(default_options)); argc=1; argv=argv_buff; argv_buff[0]= (char*) "client"; - groups[0]= (char*) "client"; groups[1]= (char*) group; groups[2]=0; + groups[0]= (char*) "client"; + groups[1]= (char*) "client-server"; + groups[2]= (char*) "client-mariadb"; + groups[3]= (char*) group; + groups[4]=0; my_load_defaults(filename, groups, &argc, &argv, NULL); if (argc != 1) /* If some default option */ @@ -1746,6 +1752,7 @@ mysql_init(MYSQL *mysql) */ mysql->reconnect= 0; + DBUG_PRINT("mysql",("mysql: 0x%lx", (long) mysql)); return mysql; } @@ -2356,7 +2363,7 @@ static int send_change_user_packet(MCPVIO_EXT *mpvio, char *buff, *end; int res= 1; - buff= my_alloca(USERNAME_LENGTH + data_len + 1 + NAME_LEN + 2 + NAME_LEN); + buff= my_alloca(USERNAME_LENGTH+1 + data_len+1 + NAME_LEN+1 + 2 + NAME_LEN+1); end= strmake(buff, mysql->user, USERNAME_LENGTH) + 1; @@ -3425,11 +3432,6 @@ CLI_MYSQL_REAL_CONNECT(MYSQL *mysql,const char *host, const char *user, if (mysql->client_flag & CLIENT_COMPRESS) /* We will use compression */ net->compress=1; -#ifdef CHECK_LICENSE - if (check_license(mysql)) - goto error; -#endif - if (db && !mysql->db && mysql_select_db(mysql, db)) { if (mysql->net.last_errno == CR_SERVER_LOST) @@ -3724,6 +3726,8 @@ void mysql_detach_stmt_list(LIST **stmt_list __attribute__((unused)), void STDCALL mysql_close(MYSQL *mysql) { DBUG_ENTER("mysql_close"); + DBUG_PRINT("enter", ("mysql: 0x%lx", (long) mysql)); + if (mysql) /* Some simple safety */ { /* If connection is still up, send a QUIT message */ @@ -4106,6 +4110,15 @@ mysql_options(MYSQL *mysql,enum mysql_option option, const void *arg) case MYSQL_DEFAULT_AUTH: EXTENSION_SET_STRING(&mysql->options, default_auth, arg); break; + case MYSQL_PROGRESS_CALLBACK: + if (!mysql->options.extension) + mysql->options.extension= (struct st_mysql_options_extention *) + my_malloc(sizeof(struct st_mysql_options_extention), + MYF(MY_WME | MY_ZEROFILL)); + if (mysql->options.extension) + mysql->options.extension->report_progress= + (void (*)(const MYSQL *, uint, uint, double, const char *, uint)) arg; + break; default: DBUG_RETURN(1); } |