1
0
mirror of https://github.com/MariaDB/server.git synced 2025-07-29 05:21:33 +03:00

Auto-merge from mysql-next-mr.

This commit is contained in:
Alexander Nozdrin
2009-11-05 15:08:37 +03:00
457 changed files with 19019 additions and 8786 deletions

View File

@ -710,10 +710,14 @@ err:
}
#endif
/*****************************************************************************
/**
Read a packet from server. Give error message if socket was down
or packet is an error message
*****************************************************************************/
@retval packet_error An error occurred during reading.
Error message is set.
@retval
*/
ulong
cli_safe_read(MYSQL *mysql)
@ -879,31 +883,132 @@ void free_old_query(MYSQL *mysql)
DBUG_VOID_RETURN;
}
/**
Finish reading of a partial result set from the server.
Get the EOF packet, and update mysql->status
and mysql->warning_count.
@return TRUE if a communication or protocol error, an error
is set in this case, FALSE otherwise.
*/
my_bool flush_one_result(MYSQL *mysql)
{
ulong packet_length;
DBUG_ASSERT(mysql->status != MYSQL_STATUS_READY);
do
{
packet_length= cli_safe_read(mysql);
/*
There is an error reading from the connection,
or (sic!) there were no error and no
data in the stream, i.e. no more data from the server.
Since we know our position in the stream (somewhere in
the middle of a result set), this latter case is an error too
-- each result set must end with a EOF packet.
cli_safe_read() has set an error for us, just return.
*/
if (packet_length == packet_error)
return TRUE;
}
while (packet_length > 8 || mysql->net.read_pos[0] != 254);
/* Analyze EOF packet of the result set. */
if (protocol_41(mysql))
{
char *pos= (char*) mysql->net.read_pos + 1;
mysql->warning_count=uint2korr(pos);
pos+=2;
mysql->server_status=uint2korr(pos);
pos+=2;
}
return FALSE;
}
/**
Read a packet from network. If it's an OK packet, flush it.
@return TRUE if error, FALSE otherwise. In case of
success, is_ok_packet is set to TRUE or FALSE,
based on what we got from network.
*/
my_bool opt_flush_ok_packet(MYSQL *mysql, my_bool *is_ok_packet)
{
ulong packet_length= cli_safe_read(mysql);
if (packet_length == packet_error)
return TRUE;
/* cli_safe_read always reads a non-empty packet. */
DBUG_ASSERT(packet_length);
*is_ok_packet= mysql->net.read_pos[0] == 0;
if (*is_ok_packet)
{
uchar *pos= mysql->net.read_pos + 1;
net_field_length_ll(&pos); /* affected rows */
net_field_length_ll(&pos); /* insert id */
mysql->server_status=uint2korr(pos);
pos+=2;
if (protocol_41(mysql))
{
mysql->warning_count=uint2korr(pos);
pos+=2;
}
}
return FALSE;
}
/*
Flush result set sent from server
*/
static void cli_flush_use_result(MYSQL *mysql)
static void cli_flush_use_result(MYSQL *mysql, my_bool flush_all_results)
{
/* Clear the current execution status */
DBUG_ENTER("cli_flush_use_result");
DBUG_PRINT("warning",("Not all packets read, clearing them"));
for (;;)
if (flush_one_result(mysql))
DBUG_VOID_RETURN; /* An error occurred */
if (! flush_all_results)
DBUG_VOID_RETURN;
while (mysql->server_status & SERVER_MORE_RESULTS_EXISTS)
{
ulong pkt_len;
if ((pkt_len=cli_safe_read(mysql)) == packet_error)
break;
if (pkt_len <= 8 && mysql->net.read_pos[0] == 254)
my_bool is_ok_packet;
if (opt_flush_ok_packet(mysql, &is_ok_packet))
DBUG_VOID_RETURN; /* An error occurred. */
if (is_ok_packet)
{
if (protocol_41(mysql))
{
char *pos= (char*) mysql->net.read_pos + 1;
mysql->warning_count=uint2korr(pos); pos+=2;
mysql->server_status=uint2korr(pos); pos+=2;
}
break; /* End of data */
/*
Indeed what we got from network was an OK packet, and we
know that OK is the last one in a multi-result-set, so
just return.
*/
DBUG_VOID_RETURN;
}
/*
It's a result set, not an OK packet. A result set contains
of two result set subsequences: field metadata, terminated
with EOF packet, and result set data, again terminated with
EOF packet. Read and flush them.
*/
if (flush_one_result(mysql) || flush_one_result(mysql))
DBUG_VOID_RETURN; /* An error occurred. */
}
DBUG_VOID_RETURN;
}
@ -1009,7 +1114,7 @@ mysql_free_result(MYSQL_RES *result)
mysql->unbuffered_fetch_owner= 0;
if (mysql->status == MYSQL_STATUS_USE_RESULT)
{
(*mysql->methods->flush_use_result)(mysql);
(*mysql->methods->flush_use_result)(mysql, FALSE);
mysql->status=MYSQL_STATUS_READY;
if (mysql->unbuffered_fetch_owner)
*mysql->unbuffered_fetch_owner= TRUE;
@ -1036,7 +1141,6 @@ static const char *default_options[]=
"ssl-key" ,"ssl-cert" ,"ssl-ca" ,"ssl-capath",
"character-sets-dir", "default-character-set", "interactive-timeout",
"connect-timeout", "local-infile", "disable-local-infile",
"replication-probe", "enable-reads-from-master", "repl-parse-query",
"ssl-cipher", "max-allowed-packet", "protocol", "shared-memory-base-name",
"multi-results", "multi-statements", "multi-queries", "secure-auth",
"report-data-truncation",
@ -1184,7 +1288,7 @@ void mysql_read_default_options(struct st_mysql_options *options,
my_free(options->ssl_capath, MYF(MY_ALLOW_ZERO_PTR));
options->ssl_capath = my_strdup(opt_arg, MYF(MY_WME));
break;
case 26: /* ssl_cipher */
case 23: /* ssl_cipher */
my_free(options->ssl_cipher, MYF(MY_ALLOW_ZERO_PTR));
options->ssl_cipher= my_strdup(opt_arg, MYF(MY_WME));
break;
@ -1193,7 +1297,7 @@ void mysql_read_default_options(struct st_mysql_options *options,
case 14:
case 15:
case 16:
case 26:
case 23:
break;
#endif /* HAVE_OPENSSL */
case 17: /* charset-lib */
@ -1216,24 +1320,11 @@ void mysql_read_default_options(struct st_mysql_options *options,
case 22:
options->client_flag&= ~CLIENT_LOCAL_FILES;
break;
case 23: /* replication probe */
#ifndef TO_BE_DELETED
options->rpl_probe= 1;
#endif
break;
case 24: /* enable-reads-from-master */
options->no_master_reads= 0;
break;
case 25: /* repl-parse-query */
#ifndef TO_BE_DELETED
options->rpl_parse= 1;
#endif
break;
case 27:
case 24: /* max-allowed-packet */
if (opt_arg)
options->max_allowed_packet= atoi(opt_arg);
break;
case 28: /* protocol */
case 25: /* protocol */
if ((options->protocol= find_type(opt_arg,
&sql_protocol_typelib,0)) <= 0)
{
@ -1241,24 +1332,24 @@ void mysql_read_default_options(struct st_mysql_options *options,
exit(1);
}
break;
case 29: /* shared_memory_base_name */
case 26: /* shared_memory_base_name */
#ifdef HAVE_SMEM
if (options->shared_memory_base_name != def_shared_memory_base_name)
my_free(options->shared_memory_base_name,MYF(MY_ALLOW_ZERO_PTR));
options->shared_memory_base_name=my_strdup(opt_arg,MYF(MY_WME));
#endif
break;
case 30:
case 27: /* multi-results */
options->client_flag|= CLIENT_MULTI_RESULTS;
break;
case 31:
case 32:
case 28: /* multi-statements */
case 29: /* multi-queries */
options->client_flag|= CLIENT_MULTI_STATEMENTS | CLIENT_MULTI_RESULTS;
break;
case 33: /* secure-auth */
case 30: /* secure-auth */
options->secure_auth= TRUE;
break;
case 34: /* report-data-truncation */
case 31: /* report-data-truncation */
options->report_data_truncation= opt_arg ? test(atoi(opt_arg)) : 1;
break;
default:
@ -1585,16 +1676,8 @@ mysql_init(MYSQL *mysql)
else
bzero((char*) (mysql), sizeof(*(mysql)));
mysql->options.connect_timeout= CONNECT_TIMEOUT;
mysql->last_used_con= mysql->next_slave= mysql->master = mysql;
mysql->charset=default_client_charset_info;
strmov(mysql->net.sqlstate, not_error_sqlstate);
/*
By default, we are a replication pivot. The caller must reset it
after we return if this is not the case.
*/
#ifndef TO_BE_DELETED
mysql->rpl_pivot = 1;
#endif
/*
Only enable LOAD DATA INFILE by default if configured with
@ -2167,6 +2250,13 @@ CLI_MYSQL_REAL_CONNECT(MYSQL *mysql,const char *host, const char *user,
db ? db : "(Null)",
user ? user : "(Null)"));
/* Test whether we're already connected */
if (net->vio)
{
set_mysql_error(mysql, CR_ALREADY_CONNECTED, unknown_sqlstate);
DBUG_RETURN(0);
}
/* Don't give sigpipe errors if the client doesn't want them */
set_sigpipe(mysql);
mysql->methods= &client_methods;
@ -2774,11 +2864,6 @@ CLI_MYSQL_REAL_CONNECT(MYSQL *mysql,const char *host, const char *user,
mysql->reconnect=reconnect;
}
#ifndef TO_BE_DELETED
if (mysql->options.rpl_probe && mysql_rpl_probe(mysql))
goto error;
#endif
DBUG_PRINT("exit", ("Mysql handler: 0x%lx", (long) mysql));
reset_sigpipe(mysql);
DBUG_RETURN(mysql);
@ -2800,28 +2885,6 @@ error:
}
/* needed when we move MYSQL structure to a different address */
#ifndef TO_BE_DELETED
static void mysql_fix_pointers(MYSQL* mysql, MYSQL* old_mysql)
{
MYSQL *tmp, *tmp_prev;
if (mysql->master == old_mysql)
mysql->master= mysql;
if (mysql->last_used_con == old_mysql)
mysql->last_used_con= mysql;
if (mysql->last_used_slave == old_mysql)
mysql->last_used_slave= mysql;
for (tmp_prev = mysql, tmp = mysql->next_slave;
tmp != old_mysql;tmp = tmp->next_slave)
{
tmp_prev= tmp;
}
tmp_prev->next_slave= mysql;
}
#endif
my_bool mysql_reconnect(MYSQL *mysql)
{
MYSQL tmp_mysql;
@ -2840,8 +2903,7 @@ my_bool mysql_reconnect(MYSQL *mysql)
mysql_init(&tmp_mysql);
tmp_mysql.options= mysql->options;
tmp_mysql.options.my_cnf_file= tmp_mysql.options.my_cnf_group= 0;
tmp_mysql.rpl_pivot= mysql->rpl_pivot;
if (!mysql_real_connect(&tmp_mysql,mysql->host,mysql->user,mysql->passwd,
mysql->db, mysql->port, mysql->unix_socket,
mysql->client_flag | CLIENT_REMEMBER_OPTIONS))
@ -2875,7 +2937,6 @@ my_bool mysql_reconnect(MYSQL *mysql)
mysql->free_me=0;
mysql_close(mysql);
*mysql=tmp_mysql;
mysql_fix_pointers(mysql, &tmp_mysql); /* adjust connection pointers */
net_clear(&mysql->net, 1);
mysql->affected_rows= ~(my_ulonglong) 0;
DBUG_RETURN(0);
@ -3053,23 +3114,6 @@ void STDCALL mysql_close(MYSQL *mysql)
mysql_close_free_options(mysql);
mysql_close_free(mysql);
mysql_detach_stmt_list(&mysql->stmts, "mysql_close");
#ifndef TO_BE_DELETED
/* free/close slave list */
if (mysql->rpl_pivot)
{
MYSQL* tmp;
for (tmp = mysql->next_slave; tmp != mysql; )
{
/* trick to avoid following freed pointer */
MYSQL* tmp1 = tmp->next_slave;
mysql_close(tmp);
tmp = tmp1;
}
mysql->rpl_pivot=0;
}
#endif
if (mysql != mysql->master)
mysql_close(mysql->master);
#ifndef MYSQL_SERVER
if (mysql->thd)
(*mysql->methods->free_embedded_thd)(mysql);
@ -3089,12 +3133,6 @@ static my_bool cli_read_query_result(MYSQL *mysql)
ulong length;
DBUG_ENTER("cli_read_query_result");
/*
Read from the connection which we actually used, which
could differ from the original connection if we have slaves
*/
mysql = mysql->last_used_con;
if ((length = cli_safe_read(mysql)) == packet_error)
DBUG_RETURN(1);
free_old_query(mysql); /* Free old result */
@ -3169,23 +3207,6 @@ int STDCALL
mysql_send_query(MYSQL* mysql, const char* query, ulong length)
{
DBUG_ENTER("mysql_send_query");
DBUG_PRINT("enter",("rpl_parse: %d rpl_pivot: %d",
mysql->options.rpl_parse, mysql->rpl_pivot));
#ifndef TO_BE_DELETED
if (mysql->options.rpl_parse && mysql->rpl_pivot)
{
switch (mysql_rpl_query_type(query, length)) {
case MYSQL_RPL_MASTER:
DBUG_RETURN(mysql_master_send_query(mysql, query, length));
case MYSQL_RPL_SLAVE:
DBUG_RETURN(mysql_slave_send_query(mysql, query, length));
case MYSQL_RPL_ADMIN:
break; /* fall through */
}
}
mysql->last_used_con = mysql;
#endif
DBUG_RETURN(simple_command(mysql, COM_QUERY, (uchar*) query, length, 1));
}
@ -3212,8 +3233,7 @@ MYSQL_RES * STDCALL mysql_store_result(MYSQL *mysql)
{
MYSQL_RES *result;
DBUG_ENTER("mysql_store_result");
/* read from the actually used connection */
mysql = mysql->last_used_con;
if (!mysql->fields)
DBUG_RETURN(0);
if (mysql->status != MYSQL_STATUS_GET_RESULT)
@ -3268,8 +3288,6 @@ static MYSQL_RES * cli_use_result(MYSQL *mysql)
MYSQL_RES *result;
DBUG_ENTER("cli_use_result");
mysql = mysql->last_used_con;
if (!mysql->fields)
DBUG_RETURN(0);
if (mysql->status != MYSQL_STATUS_GET_RESULT)