Merge branch 'develop' into MAX-324
Conflicts: query_classifier/query_classifier.cc
This commit is contained in:
@ -1210,6 +1210,8 @@ bool is_drop_table_query(GWBUF* querybuf)
|
|||||||
lex->sql_command == SQLCOM_DROP_TABLE);
|
lex->sql_command == SQLCOM_DROP_TABLE);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
inline void add_str(char** buf, int* buflen, int* bufsize, char* str)
|
inline void add_str(char** buf, int* buflen, int* bufsize, char* str)
|
||||||
{
|
{
|
||||||
int isize = strlen(str) + 1;
|
int isize = strlen(str) + 1;
|
||||||
@ -1542,7 +1544,7 @@ static void parsing_info_set_plain_str(
|
|||||||
* @return string representing the query type value
|
* @return string representing the query type value
|
||||||
*/
|
*/
|
||||||
char* skygw_get_qtype_str(
|
char* skygw_get_qtype_str(
|
||||||
skygw_query_type_t qtype)
|
skygw_query_type_t qtype)
|
||||||
{
|
{
|
||||||
int t1 = (int)qtype;
|
int t1 = (int)qtype;
|
||||||
int t2 = 1;
|
int t2 = 1;
|
||||||
@ -1554,27 +1556,27 @@ char* skygw_get_qtype_str(
|
|||||||
* t1 is completely cleared.
|
* t1 is completely cleared.
|
||||||
*/
|
*/
|
||||||
while (t1 != 0)
|
while (t1 != 0)
|
||||||
|
{
|
||||||
|
if (t1&t2)
|
||||||
{
|
{
|
||||||
if (t1&t2)
|
t = (skygw_query_type_t)t2;
|
||||||
{
|
|
||||||
t = (skygw_query_type_t)t2;
|
|
||||||
|
|
||||||
if (qtype_str == NULL)
|
if (qtype_str == NULL)
|
||||||
{
|
{
|
||||||
qtype_str = strdup(STRQTYPE(t));
|
qtype_str = strdup(STRQTYPE(t));
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
size_t len = strlen(STRQTYPE(t));
|
size_t len = strlen(STRQTYPE(t));
|
||||||
/** reallocate space for delimiter, new string and termination */
|
/** reallocate space for delimiter, new string and termination */
|
||||||
qtype_str = (char *)realloc(qtype_str, strlen(qtype_str)+1+len+1);
|
qtype_str = (char *)realloc(qtype_str, strlen(qtype_str)+1+len+1);
|
||||||
snprintf(qtype_str+strlen(qtype_str), 1+len+1, "|%s", STRQTYPE(t));
|
snprintf(qtype_str+strlen(qtype_str), 1+len+1, "|%s", STRQTYPE(t));
|
||||||
}
|
}
|
||||||
/** Remove found value from t1 */
|
/** Remove found value from t1 */
|
||||||
t1 &= ~t2;
|
t1 &= ~t2;
|
||||||
}
|
|
||||||
t2 <<= 1;
|
|
||||||
}
|
}
|
||||||
|
t2 <<= 1;
|
||||||
|
}
|
||||||
return qtype_str;
|
return qtype_str;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -494,38 +494,92 @@ return_packetbuf:
|
|||||||
return packetbuf;
|
return packetbuf;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Parse the buffer and split complete packets into individual buffers.
|
||||||
|
* Any partial packets are left in the old buffer.
|
||||||
|
* @param p_readbuf Buffer to split
|
||||||
|
* @return Head of the chain of complete packets
|
||||||
|
*/
|
||||||
|
GWBUF* modutil_get_complete_packets(GWBUF** p_readbuf)
|
||||||
|
{
|
||||||
|
GWBUF *buff = NULL, *packet = NULL;
|
||||||
|
|
||||||
|
while((packet = modutil_get_next_MySQL_packet(p_readbuf)) != NULL)
|
||||||
|
{
|
||||||
|
buff = gwbuf_append(buff,packet);
|
||||||
|
}
|
||||||
|
|
||||||
|
return buff;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Count the number of EOF, OK or ERR packets in the buffer.
|
* Count the number of EOF, OK or ERR packets in the buffer. Only complete
|
||||||
|
* packets are inspected and the buffer is assumed to only contain whole packets.
|
||||||
|
* If partial packets are in the buffer, they are ingnored. The caller must handle the
|
||||||
|
* detection of partial packets in buffers.
|
||||||
* @param reply Buffer to use
|
* @param reply Buffer to use
|
||||||
* @param use_ok Whether the DEPRECATE_EOF flag is set
|
* @param use_ok Whether the DEPRECATE_EOF flag is set
|
||||||
* @param n_found If there were previous packets found
|
* @param n_found If there were previous packets found
|
||||||
* @return Number of EOF packets
|
* @return Number of EOF packets
|
||||||
*/
|
*/
|
||||||
int
|
int
|
||||||
modutil_count_signal_packets(GWBUF *reply,int use_ok, int n_found)
|
modutil_count_signal_packets(GWBUF *reply, int use_ok, int n_found)
|
||||||
{
|
{
|
||||||
unsigned char* ptr = (unsigned char*) reply->start;
|
unsigned char* ptr = (unsigned char*) reply->start;
|
||||||
unsigned char* end = (unsigned char*) reply->end;
|
unsigned char* end = (unsigned char*) reply->end;
|
||||||
int pktlen,pkt = 0;
|
unsigned char* prev = ptr;
|
||||||
|
int pktlen, eof = 0, err = 0, found = n_found;
|
||||||
|
int errlen = 0, eoflen = 0;
|
||||||
|
int iserr = 0, iseof = 0;
|
||||||
while(ptr < end)
|
while(ptr < end)
|
||||||
{
|
{
|
||||||
pktlen = gw_mysql_get_byte3(ptr) + 4;
|
|
||||||
|
|
||||||
if(PTR_IS_ERR(ptr) || (PTR_IS_EOF(ptr) && !use_ok) || (use_ok && PTR_IS_OK(ptr)))
|
pktlen = MYSQL_GET_PACKET_LEN(ptr) + 4;
|
||||||
|
|
||||||
|
if((iserr = PTR_IS_ERR(ptr)) || (iseof = PTR_IS_EOF(ptr)))
|
||||||
{
|
{
|
||||||
if(n_found)
|
if(iserr)
|
||||||
{
|
{
|
||||||
if(ptr + pktlen >= end)
|
err++;
|
||||||
pkt++;
|
errlen = pktlen;
|
||||||
}
|
}
|
||||||
else
|
else if(iseof)
|
||||||
{
|
{
|
||||||
pkt++;
|
eof++;
|
||||||
|
eoflen = pktlen;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if((ptr + pktlen) > end)
|
||||||
|
{
|
||||||
|
ptr = prev;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
prev = ptr;
|
||||||
ptr += pktlen;
|
ptr += pktlen;
|
||||||
}
|
}
|
||||||
return pkt;
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* If there were new EOF/ERR packets found, make sure that they are the last
|
||||||
|
* packet in the buffer.
|
||||||
|
*/
|
||||||
|
if((eof || err) && n_found)
|
||||||
|
{
|
||||||
|
if(err)
|
||||||
|
{
|
||||||
|
ptr -= errlen;
|
||||||
|
if(!PTR_IS_ERR(ptr))
|
||||||
|
err = 0;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ptr -= eoflen;
|
||||||
|
if(!PTR_IS_EOF(ptr))
|
||||||
|
eof = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return(eof + err);
|
||||||
}
|
}
|
||||||
|
@ -48,6 +48,7 @@ extern GWBUF *modutil_replace_SQL(GWBUF *, char *);
|
|||||||
extern char *modutil_get_query(GWBUF* buf);
|
extern char *modutil_get_query(GWBUF* buf);
|
||||||
extern int modutil_send_mysql_err_packet(DCB *, int, int, int, const char *, const char *);
|
extern int modutil_send_mysql_err_packet(DCB *, int, int, int, const char *, const char *);
|
||||||
GWBUF* modutil_get_next_MySQL_packet(GWBUF** p_readbuf);
|
GWBUF* modutil_get_next_MySQL_packet(GWBUF** p_readbuf);
|
||||||
|
GWBUF* modutil_get_complete_packets(GWBUF** p_readbuf);
|
||||||
int modutil_MySQL_query_len(GWBUF* buf, int* nbytes_missing);
|
int modutil_MySQL_query_len(GWBUF* buf, int* nbytes_missing);
|
||||||
|
|
||||||
GWBUF *modutil_create_mysql_err_msg(
|
GWBUF *modutil_create_mysql_err_msg(
|
||||||
|
@ -161,7 +161,7 @@ typedef struct {
|
|||||||
FILTER_DEF* dummy_filterdef;
|
FILTER_DEF* dummy_filterdef;
|
||||||
int active; /* filter is active? */
|
int active; /* filter is active? */
|
||||||
bool use_ok;
|
bool use_ok;
|
||||||
bool multipacket;
|
bool multipacket[2];
|
||||||
unsigned char command;
|
unsigned char command;
|
||||||
bool waiting[2]; /* if the client is waiting for a reply */
|
bool waiting[2]; /* if the client is waiting for a reply */
|
||||||
int eof[2];
|
int eof[2];
|
||||||
@ -172,7 +172,11 @@ typedef struct {
|
|||||||
int n_rejected; /* Number of rejected queries */
|
int n_rejected; /* Number of rejected queries */
|
||||||
int residual; /* Any outstanding SQL text */
|
int residual; /* Any outstanding SQL text */
|
||||||
GWBUF* tee_replybuf; /* Buffer for reply */
|
GWBUF* tee_replybuf; /* Buffer for reply */
|
||||||
|
GWBUF* tee_partials[2];
|
||||||
SPINLOCK tee_lock;
|
SPINLOCK tee_lock;
|
||||||
|
#ifdef SS_DEBUG
|
||||||
|
long d_id;
|
||||||
|
#endif
|
||||||
} TEE_SESSION;
|
} TEE_SESSION;
|
||||||
|
|
||||||
typedef struct orphan_session_tt
|
typedef struct orphan_session_tt
|
||||||
@ -181,6 +185,11 @@ typedef struct orphan_session_tt
|
|||||||
struct orphan_session_tt* next;
|
struct orphan_session_tt* next;
|
||||||
}orphan_session_t;
|
}orphan_session_t;
|
||||||
|
|
||||||
|
#ifdef SS_DEBUG
|
||||||
|
static SPINLOCK debug_lock;
|
||||||
|
static long debug_id = 0;
|
||||||
|
#endif
|
||||||
|
|
||||||
static orphan_session_t* allOrphans = NULL;
|
static orphan_session_t* allOrphans = NULL;
|
||||||
|
|
||||||
static SPINLOCK orphanLock;
|
static SPINLOCK orphanLock;
|
||||||
@ -322,7 +331,10 @@ void
|
|||||||
ModuleInit()
|
ModuleInit()
|
||||||
{
|
{
|
||||||
spinlock_init(&orphanLock);
|
spinlock_init(&orphanLock);
|
||||||
hktask_add("tee orphan cleanup",orphan_free,NULL,15);
|
//hktask_add("tee orphan cleanup",orphan_free,NULL,15);
|
||||||
|
#ifdef SS_DEBUG
|
||||||
|
spinlock_init(&debug_lock);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -707,6 +719,8 @@ session_state_t state;
|
|||||||
gwbuf_free(my_session->tee_replybuf);
|
gwbuf_free(my_session->tee_replybuf);
|
||||||
free(session);
|
free(session);
|
||||||
|
|
||||||
|
orphan_free(NULL);
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
/**
|
/**
|
||||||
@ -813,10 +827,10 @@ unsigned char command = *((unsigned char*)queue->start + 4);
|
|||||||
case 0x17:
|
case 0x17:
|
||||||
case 0x04:
|
case 0x04:
|
||||||
case 0x0a:
|
case 0x0a:
|
||||||
my_session->multipacket = true;
|
memset(my_session->multipacket,(char)true,2*sizeof(bool));
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
my_session->multipacket = false;
|
memset(my_session->multipacket,(char)false,2*sizeof(bool));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -824,6 +838,21 @@ unsigned char command = *((unsigned char*)queue->start + 4);
|
|||||||
memset(my_session->eof,0,2*sizeof(int));
|
memset(my_session->eof,0,2*sizeof(int));
|
||||||
memset(my_session->waiting,1,2*sizeof(bool));
|
memset(my_session->waiting,1,2*sizeof(bool));
|
||||||
my_session->command = command;
|
my_session->command = command;
|
||||||
|
#ifdef SS_DEBUG
|
||||||
|
spinlock_acquire(&debug_lock);
|
||||||
|
my_session->d_id = ++debug_id;
|
||||||
|
skygw_log_write_flush(LOGFILE_DEBUG,"tee.c [%d] command [%x]",
|
||||||
|
my_session->d_id,
|
||||||
|
my_session->command);
|
||||||
|
if(command == 0x03)
|
||||||
|
{
|
||||||
|
char* tmpstr = modutil_get_SQL(queue);
|
||||||
|
skygw_log_write_flush(LOGFILE_DEBUG,"tee.c query: '%s'",
|
||||||
|
tmpstr);
|
||||||
|
free(tmpstr);
|
||||||
|
}
|
||||||
|
spinlock_release(&debug_lock);
|
||||||
|
#endif
|
||||||
rval = my_session->down.routeQuery(my_session->down.instance,
|
rval = my_session->down.routeQuery(my_session->down.instance,
|
||||||
my_session->down.session,
|
my_session->down.session,
|
||||||
queue);
|
queue);
|
||||||
@ -873,93 +902,159 @@ unsigned char command = *((unsigned char*)queue->start + 4);
|
|||||||
static int
|
static int
|
||||||
clientReply (FILTER* instance, void *session, GWBUF *reply)
|
clientReply (FILTER* instance, void *session, GWBUF *reply)
|
||||||
{
|
{
|
||||||
int rc, branch, eof;
|
int rc, branch, eof;
|
||||||
TEE_SESSION *my_session = (TEE_SESSION *) session;
|
TEE_SESSION *my_session = (TEE_SESSION *) session;
|
||||||
|
bool route = false,mpkt;
|
||||||
|
GWBUF *complete = NULL;
|
||||||
|
unsigned char *ptr;
|
||||||
|
int min_eof = my_session->command != 0x04 ? 2 : 1;
|
||||||
|
|
||||||
spinlock_acquire(&my_session->tee_lock);
|
spinlock_acquire(&my_session->tee_lock);
|
||||||
|
|
||||||
ss_dassert(my_session->active);
|
ss_dassert(my_session->active);
|
||||||
|
|
||||||
branch = instance == NULL ? CHILD : PARENT;
|
branch = instance == NULL ? CHILD : PARENT;
|
||||||
unsigned char *ptr = (unsigned char*)reply->start;
|
|
||||||
|
|
||||||
if(my_session->replies[branch] == 0)
|
my_session->tee_partials[branch] = gwbuf_append(my_session->tee_partials[branch], reply);
|
||||||
{
|
my_session->tee_partials[branch] = gwbuf_make_contiguous(my_session->tee_partials[branch]);
|
||||||
/* Reply is in a single packet if it is an OK, ERR or LOCAL_INFILE packet.
|
complete = modutil_get_complete_packets(&my_session->tee_partials[branch]);
|
||||||
* Otherwise the reply is a result set and the amount of packets is unknown.
|
complete = gwbuf_make_contiguous(complete);
|
||||||
*/
|
|
||||||
if(PTR_IS_ERR(ptr) || PTR_IS_LOCAL_INFILE(ptr) ||
|
if(my_session->tee_partials[branch] &&
|
||||||
PTR_IS_OK(ptr) || !my_session->multipacket )
|
GWBUF_EMPTY(my_session->tee_partials[branch]))
|
||||||
{
|
{
|
||||||
my_session->waiting[branch] = false;
|
gwbuf_free(my_session->tee_partials[branch]);
|
||||||
}
|
my_session->tee_partials[branch] = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
ptr = (unsigned char*) complete->start;
|
||||||
|
|
||||||
|
if(my_session->replies[branch] == 0)
|
||||||
|
{
|
||||||
|
/* Reply is in a single packet if it is an OK, ERR or LOCAL_INFILE packet.
|
||||||
|
* Otherwise the reply is a result set and the amount of packets is unknown.
|
||||||
|
*/
|
||||||
|
if(PTR_IS_ERR(ptr) || PTR_IS_LOCAL_INFILE(ptr) ||
|
||||||
|
PTR_IS_OK(ptr) || !my_session->multipacket[branch] )
|
||||||
|
{
|
||||||
|
my_session->waiting[branch] = false;
|
||||||
|
my_session->multipacket[branch] = false;
|
||||||
|
}
|
||||||
#ifdef SS_DEBUG
|
#ifdef SS_DEBUG
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
ss_dassert(PTR_IS_RESULTSET(ptr));
|
ss_dassert(PTR_IS_RESULTSET(ptr));
|
||||||
skygw_log_write_flush(LOGFILE_DEBUG,"tee.c: Waiting for a result set from %s session.",branch == PARENT?"parent":"child");
|
skygw_log_write_flush(LOGFILE_DEBUG,"tee.c: [%d] Waiting for a result set from %s session.",
|
||||||
}
|
my_session->d_id,
|
||||||
ss_dassert(PTR_IS_ERR(ptr) || PTR_IS_LOCAL_INFILE(ptr)||
|
branch == PARENT?"parent":"child");
|
||||||
PTR_IS_OK(ptr) || my_session->waiting[branch] ||
|
}
|
||||||
!my_session->multipacket);
|
ss_dassert(PTR_IS_ERR(ptr) || PTR_IS_LOCAL_INFILE(ptr)||
|
||||||
|
PTR_IS_OK(ptr) || my_session->waiting[branch] ||
|
||||||
|
!my_session->multipacket);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
if(my_session->waiting[branch])
|
if(my_session->waiting[branch])
|
||||||
{
|
{
|
||||||
|
|
||||||
eof = modutil_count_signal_packets(reply,my_session->use_ok,my_session->eof[branch] > 0);
|
eof = modutil_count_signal_packets(complete,my_session->use_ok,my_session->eof[branch] > 0);
|
||||||
my_session->eof[branch] += eof;
|
my_session->eof[branch] += eof;
|
||||||
if(my_session->eof[branch] >= 2 ||
|
if(my_session->eof[branch] >= min_eof)
|
||||||
(my_session->command == 0x04 && my_session->eof[branch] > 0))
|
{
|
||||||
{
|
#ifdef SS_DEBUG
|
||||||
ss_dassert(my_session->eof[branch] < 3)
|
skygw_log_write_flush(LOGFILE_DEBUG,"tee.c [%d] %s received last EOF packet",
|
||||||
my_session->waiting[branch] = false;
|
my_session->d_id,
|
||||||
}
|
branch == PARENT?"parent":"child");
|
||||||
}
|
#endif
|
||||||
|
ss_dassert(my_session->eof[branch] < 3)
|
||||||
|
my_session->waiting[branch] = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if(branch == PARENT)
|
if(branch == PARENT)
|
||||||
{
|
{
|
||||||
ss_dassert(my_session->tee_replybuf == NULL)
|
ss_dassert(my_session->tee_replybuf == NULL);
|
||||||
my_session->tee_replybuf = reply;
|
my_session->tee_replybuf = complete;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
gwbuf_free(reply);
|
if(complete)
|
||||||
}
|
gwbuf_free(complete);
|
||||||
|
}
|
||||||
|
|
||||||
my_session->replies[branch]++;
|
my_session->replies[branch]++;
|
||||||
|
rc = 1;
|
||||||
|
mpkt = my_session->multipacket[PARENT] || my_session->multipacket[CHILD];
|
||||||
|
|
||||||
if(my_session->tee_replybuf != NULL &&
|
|
||||||
(my_session->branch_session == NULL ||
|
|
||||||
my_session->waiting[PARENT] ||
|
if(my_session->tee_replybuf != NULL)
|
||||||
(!my_session->waiting[CHILD] && !my_session->waiting[PARENT])))
|
{
|
||||||
|
|
||||||
|
if(my_session->branch_session == NULL)
|
||||||
|
{
|
||||||
|
rc = 0;
|
||||||
|
gwbuf_free(my_session->tee_replybuf);
|
||||||
|
my_session->tee_replybuf = NULL;
|
||||||
|
skygw_log_write_flush(LOGFILE_ERROR,"Error : Tee child session was closed.");
|
||||||
|
}
|
||||||
|
|
||||||
|
if(mpkt)
|
||||||
|
{
|
||||||
|
|
||||||
|
if(my_session->waiting[PARENT])
|
||||||
|
{
|
||||||
|
route = true;
|
||||||
|
#ifdef SS_DEBUG
|
||||||
|
ss_dassert(my_session->replies[PARENT] < 2 ||
|
||||||
|
modutil_count_signal_packets(my_session->tee_replybuf,
|
||||||
|
my_session->use_ok,
|
||||||
|
my_session->eof[PARENT]) == 0);
|
||||||
|
skygw_log_write_flush(LOGFILE_DEBUG,"tee.c:[%d] Routing partial response set.",my_session->d_id);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
else if(my_session->eof[PARENT] == min_eof &&
|
||||||
|
my_session->eof[CHILD] == min_eof)
|
||||||
|
{
|
||||||
|
route = true;
|
||||||
|
#ifdef SS_DEBUG
|
||||||
|
skygw_log_write_flush(LOGFILE_DEBUG,"tee.c:[%d] Routing final packet of response set.",my_session->d_id);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if(!my_session->waiting[PARENT] &&
|
||||||
|
!my_session->waiting[CHILD])
|
||||||
|
{
|
||||||
|
#ifdef SS_DEBUG
|
||||||
|
skygw_log_write_flush(LOGFILE_DEBUG,"tee.c:[%d] Routing single packet response.",my_session->d_id);
|
||||||
|
#endif
|
||||||
|
route = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if(route)
|
||||||
{
|
{
|
||||||
#ifdef SS_DEBUG
|
#ifdef SS_DEBUG
|
||||||
skygw_log_write_flush(LOGFILE_DEBUG, "tee.c: Routing buffer '%p' parent(waiting [%s] replies [%d] eof[%d])"
|
skygw_log_write_flush(LOGFILE_DEBUG, "tee.c:[%d] Routing buffer '%p' parent(waiting [%s] replies [%d] eof[%d])"
|
||||||
" child(waiting [%s] replies[%d] eof [%d])",
|
" child(waiting [%s] replies[%d] eof [%d])",
|
||||||
my_session->tee_replybuf,
|
my_session->d_id,
|
||||||
my_session->waiting[PARENT] ? "true":"false",
|
my_session->tee_replybuf,
|
||||||
my_session->replies[PARENT],
|
my_session->waiting[PARENT] ? "true":"false",
|
||||||
my_session->eof[PARENT],
|
my_session->replies[PARENT],
|
||||||
my_session->waiting[CHILD]?"true":"false",
|
my_session->eof[PARENT],
|
||||||
my_session->replies[CHILD],
|
my_session->waiting[CHILD]?"true":"false",
|
||||||
my_session->eof[CHILD]);
|
my_session->replies[CHILD],
|
||||||
|
my_session->eof[CHILD]);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
rc = my_session->up.clientReply (
|
rc = my_session->up.clientReply (my_session->up.instance,
|
||||||
my_session->up.instance,
|
my_session->up.session,
|
||||||
my_session->up.session,
|
my_session->tee_replybuf);
|
||||||
my_session->tee_replybuf);
|
my_session->tee_replybuf = NULL;
|
||||||
my_session->tee_replybuf = NULL;
|
}
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
rc = 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
spinlock_release(&my_session->tee_lock);
|
spinlock_release(&my_session->tee_lock);
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
/**
|
/**
|
||||||
* Diagnostics routine
|
* Diagnostics routine
|
||||||
|
@ -3609,7 +3609,7 @@ static GWBUF* sescmd_cursor_process_replies(
|
|||||||
bref_clear_state(bref, BREF_WAITING_RESULT);
|
bref_clear_state(bref, BREF_WAITING_RESULT);
|
||||||
}
|
}
|
||||||
/** Response is in the buffer and it will be sent to client. */
|
/** Response is in the buffer and it will be sent to client. */
|
||||||
else if (replybuf != NULL)
|
else
|
||||||
{
|
{
|
||||||
/** Mark the rest session commands as replied */
|
/** Mark the rest session commands as replied */
|
||||||
scmd->my_sescmd_is_replied = true;
|
scmd->my_sescmd_is_replied = true;
|
||||||
|
Reference in New Issue
Block a user