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:
VilhoRaatikka
2014-08-14 22:33:57 +03:00
parent 2393ac57e9
commit 902004c1ee
4 changed files with 24 additions and 35 deletions

View File

@ -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)
{ {

View File

@ -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.

View File

@ -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;

View File

@ -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,