Fix to bug #463, http://bugs.skysql.com/show_bug.cgi?id=463
mysql_common.c:gw_MySQL_get_next_packet didn't handle case where an insert command followed by alter table in the same read buffer. It shouldn't been possible without multi-statement being set.
This commit is contained in:
@ -814,6 +814,8 @@ int below_water;
|
|||||||
}
|
}
|
||||||
|
|
||||||
spinlock_acquire(&dcb->writeqlock);
|
spinlock_acquire(&dcb->writeqlock);
|
||||||
|
|
||||||
|
ss_dassert(dcb->state != DCB_STATE_ZOMBIE);
|
||||||
|
|
||||||
if (dcb->writeq != NULL)
|
if (dcb->writeq != NULL)
|
||||||
{
|
{
|
||||||
|
@ -1435,12 +1435,11 @@ static int route_by_statement(
|
|||||||
ss_dassert(GWBUF_IS_TYPE_MYSQL((*p_readbuf)));
|
ss_dassert(GWBUF_IS_TYPE_MYSQL((*p_readbuf)));
|
||||||
|
|
||||||
packetbuf = gw_MySQL_get_next_packet(p_readbuf);
|
packetbuf = gw_MySQL_get_next_packet(p_readbuf);
|
||||||
|
|
||||||
ss_dassert(GWBUF_IS_TYPE_MYSQL(packetbuf));
|
|
||||||
|
|
||||||
if (packetbuf != NULL)
|
if (packetbuf != NULL)
|
||||||
{
|
{
|
||||||
CHK_GWBUF(packetbuf);
|
CHK_GWBUF(packetbuf);
|
||||||
|
ss_dassert(GWBUF_IS_TYPE_MYSQL(packetbuf));
|
||||||
/**
|
/**
|
||||||
* This means that buffer includes exactly one MySQL
|
* This means that buffer includes exactly one MySQL
|
||||||
* statement.
|
* statement.
|
||||||
|
@ -1514,6 +1514,9 @@ GWBUF* gw_MySQL_get_next_packet(
|
|||||||
size_t packetlen;
|
size_t packetlen;
|
||||||
size_t totalbuflen;
|
size_t totalbuflen;
|
||||||
uint8_t* data;
|
uint8_t* data;
|
||||||
|
size_t nbytes_copied = 0;
|
||||||
|
uint8_t* target;
|
||||||
|
|
||||||
readbuf = *p_readbuf;
|
readbuf = *p_readbuf;
|
||||||
|
|
||||||
if (readbuf == NULL)
|
if (readbuf == NULL)
|
||||||
@ -1540,44 +1543,27 @@ GWBUF* gw_MySQL_get_next_packet(
|
|||||||
packetbuf = NULL;
|
packetbuf = NULL;
|
||||||
goto return_packetbuf;
|
goto return_packetbuf;
|
||||||
}
|
}
|
||||||
/** there is one complete packet in the buffer */
|
|
||||||
if (packetlen == buflen)
|
packetbuf = gwbuf_alloc(packetlen);
|
||||||
{
|
target = GWBUF_DATA(packetbuf);
|
||||||
packetbuf = gwbuf_clone_portion(readbuf, 0, packetlen);
|
packetbuf->gwbuf_type = readbuf->gwbuf_type; /*< Copy the type too */
|
||||||
*p_readbuf = gwbuf_consume(readbuf, packetlen);
|
|
||||||
goto return_packetbuf;
|
|
||||||
}
|
|
||||||
/**
|
/**
|
||||||
* Packet spans multiple buffers.
|
* Copy first MySQL packet to packetbuf and leave posible other
|
||||||
* Allocate buffer for complete packet
|
* packets to read buffer.
|
||||||
* copy packet parts into it and consume copied bytes
|
*/
|
||||||
*/
|
while (nbytes_copied < packetlen && totalbuflen > 0)
|
||||||
else if (packetlen > buflen)
|
|
||||||
{
|
{
|
||||||
size_t nbytes_copied = 0;
|
uint8_t* src = GWBUF_DATA((*p_readbuf));
|
||||||
uint8_t* target;
|
size_t bytestocopy;
|
||||||
|
|
||||||
packetbuf = gwbuf_alloc(packetlen);
|
bytestocopy = MIN(buflen,packetlen-nbytes_copied);
|
||||||
target = GWBUF_DATA(packetbuf);
|
|
||||||
packetbuf->gwbuf_type = readbuf->gwbuf_type; /*< Copy the type too */
|
|
||||||
|
|
||||||
while (nbytes_copied < packetlen)
|
memcpy(target+nbytes_copied, src, bytestocopy);
|
||||||
{
|
*p_readbuf = gwbuf_consume((*p_readbuf), bytestocopy);
|
||||||
uint8_t* src = GWBUF_DATA(readbuf);
|
totalbuflen = gwbuf_length((*p_readbuf));
|
||||||
size_t buflen = GWBUF_LENGTH(readbuf);
|
nbytes_copied += bytestocopy;
|
||||||
|
|
||||||
memcpy(target+nbytes_copied, src, buflen);
|
|
||||||
readbuf = gwbuf_consume(readbuf, buflen);
|
|
||||||
nbytes_copied += buflen;
|
|
||||||
}
|
|
||||||
*p_readbuf = readbuf;
|
|
||||||
ss_dassert(nbytes_copied == packetlen);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
packetbuf = gwbuf_clone_portion(readbuf, 0, packetlen);
|
|
||||||
*p_readbuf = gwbuf_consume(readbuf, packetlen);
|
|
||||||
}
|
}
|
||||||
|
ss_dassert(buflen == 0 || nbytes_copied == packetlen);
|
||||||
|
|
||||||
return_packetbuf:
|
return_packetbuf:
|
||||||
return packetbuf;
|
return packetbuf;
|
||||||
|
@ -1550,6 +1550,8 @@ static void clientReply (
|
|||||||
char* cmdstr = (char *)malloc(len+1);
|
char* cmdstr = (char *)malloc(len+1);
|
||||||
/** data+termination character == len */
|
/** data+termination character == len */
|
||||||
snprintf(cmdstr, len, "%s", &buf[5]);
|
snprintf(cmdstr, len, "%s", &buf[5]);
|
||||||
|
|
||||||
|
ss_dassert(len+4 == GWBUF_LENGTH(scur->scmd_cur_cmd->my_sescmd_buf));
|
||||||
|
|
||||||
LOGIF(LE, (skygw_log_write_flush(
|
LOGIF(LE, (skygw_log_write_flush(
|
||||||
LOGFILE_ERROR,
|
LOGFILE_ERROR,
|
||||||
|
Reference in New Issue
Block a user