|
|
|
|
@ -1,6 +1,7 @@
|
|
|
|
|
#include "proxysql.h"
|
|
|
|
|
#include "cpp.h"
|
|
|
|
|
|
|
|
|
|
#define EXPMARIA
|
|
|
|
|
|
|
|
|
|
extern Query_Processor *GloQPro;
|
|
|
|
|
extern Query_Cache *GloQC;
|
|
|
|
|
@ -292,7 +293,18 @@ int MySQL_Session::handler() {
|
|
|
|
|
//if (server_myds!=mybe->server_myds) {
|
|
|
|
|
// server_myds=mybe->server_myds;
|
|
|
|
|
//}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
#ifdef EXPMARIA
|
|
|
|
|
proxy_debug(PROXY_DEBUG_MYSQL_COM, 5, "Received query to be processed with MariaDB Client library\n");
|
|
|
|
|
mybe->server_myds->mysql_real_query.size=pkt.size-5;
|
|
|
|
|
mybe->server_myds->mysql_real_query.ptr=(char *)malloc(pkt.size-5);
|
|
|
|
|
memcpy(mybe->server_myds->mysql_real_query.ptr,(char *)pkt.ptr+5,pkt.size-5);
|
|
|
|
|
l_free(pkt.size,pkt.ptr);
|
|
|
|
|
#else
|
|
|
|
|
mybe->server_myds->PSarrayOUT->add(pkt.ptr, pkt.size);
|
|
|
|
|
#endif /* EXPMARIA */
|
|
|
|
|
|
|
|
|
|
client_myds->setDSS_STATE_QUERY_SENT_NET();
|
|
|
|
|
} else {
|
|
|
|
|
// this is processed by the admin module
|
|
|
|
|
@ -365,6 +377,7 @@ __get_a_backend:
|
|
|
|
|
if (status!=FAST_FORWARD && client_myds->DSS==STATE_QUERY_SENT_NET) {
|
|
|
|
|
// the client has completely sent the query, now we should handle it server side
|
|
|
|
|
//
|
|
|
|
|
proxy_debug(PROXY_DEBUG_MYSQL_CONNECTION, 5, "Sess=%p, client_myds->DSS==STATE_QUERY_SENT_NET\n", this);
|
|
|
|
|
if (mybe && mybe->server_myds->DSS==STATE_NOT_INITIALIZED) {
|
|
|
|
|
proxy_debug(PROXY_DEBUG_MYSQL_CONNECTION, 5, "Sess=%p, client_myds->DSS==STATE_QUERY_SENT_NET , server_myds==STATE_NOT_INITIALIZED\n", this);
|
|
|
|
|
// DSS is STATE_NOT_INITIALIZED. It means we are not connected to any server
|
|
|
|
|
@ -423,17 +436,30 @@ __get_a_backend:
|
|
|
|
|
handler___client_DSS_QUERY_SENT___send_INIT_DB_to_backend();
|
|
|
|
|
}
|
|
|
|
|
} else {
|
|
|
|
|
#ifndef EXPMARIA
|
|
|
|
|
if (client_myds->myconn->options.charset!=mybe->server_myds->myconn->options.charset /* FIXME: this was for debugging only */ /*|| rand()%3==0 */) {
|
|
|
|
|
handler___client_DSS_QUERY_SENT___send_SET_NAMES_to_backend();
|
|
|
|
|
} else {
|
|
|
|
|
#endif
|
|
|
|
|
//server_myds->PSarrayOUT->add(pkt.ptr, pkt.size);
|
|
|
|
|
#ifdef EXPMARIA
|
|
|
|
|
MySQL_Data_Stream *myds=mybe->server_myds;
|
|
|
|
|
myds->DSS=STATE_MARIADB_QUERY;
|
|
|
|
|
status=PROCESSING_QUERY;
|
|
|
|
|
myds->myconn->async_state_machine=ASYNC_QUERY_START;
|
|
|
|
|
myds->myconn->set_query(myds->mysql_real_query.ptr,myds->mysql_real_query.size);
|
|
|
|
|
myds->myconn->handler(0);
|
|
|
|
|
#else
|
|
|
|
|
mybe->server_myds->DSS=STATE_QUERY_SENT_DS;
|
|
|
|
|
// if (client_myds->myconn->processing_prepared_statement) {
|
|
|
|
|
mybe->server_myds->myconn->processing_prepared_statement_prepare=client_myds->myconn->processing_prepared_statement_prepare;
|
|
|
|
|
mybe->server_myds->myconn->processing_prepared_statement_execute=client_myds->myconn->processing_prepared_statement_execute;
|
|
|
|
|
// }
|
|
|
|
|
status=WAITING_SERVER_DATA;
|
|
|
|
|
#endif /* EXPMARIA */
|
|
|
|
|
#ifndef EXPMARIA
|
|
|
|
|
}
|
|
|
|
|
#endif
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
// } TRY #1
|
|
|
|
|
@ -485,6 +511,33 @@ __exit_DSS__STATE_NOT_INITIALIZED:
|
|
|
|
|
// }
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
case PROCESSING_QUERY:
|
|
|
|
|
if (myds->revents) {
|
|
|
|
|
myconn->handler(myds->revents);
|
|
|
|
|
if (myconn->async_state_machine==ASYNC_QUERY_END) {
|
|
|
|
|
|
|
|
|
|
// status=WAITING_SERVER_DATA;
|
|
|
|
|
// myds->DSS=STATE_READY;
|
|
|
|
|
/* multi-plexing attempt */
|
|
|
|
|
if ((myds->myconn->reusable==true) && ((myds->myprot.prot_status & SERVER_STATUS_IN_TRANS)==0)) {
|
|
|
|
|
myds->myconn->last_time_used=thread->curtime;
|
|
|
|
|
MyHGM->push_MyConn_to_pool(myds->myconn);
|
|
|
|
|
//MyHGM->destroy_MyConn_from_pool(mybe->server_myds->myconn);
|
|
|
|
|
//mybe->server_myds->myconn=NULL;
|
|
|
|
|
myds->detach_connection();
|
|
|
|
|
myds->unplug_backend();
|
|
|
|
|
}
|
|
|
|
|
/* multi-plexing attempt */
|
|
|
|
|
//status=NONE;
|
|
|
|
|
MySQL_Result_to_MySQL_wire(myconn->mysql,myconn->mysql_result,&client_myds->myprot);
|
|
|
|
|
mysql_free_result(myconn->mysql_result);
|
|
|
|
|
myconn->mysql_result=NULL;
|
|
|
|
|
myds->DSS=STATE_NOT_INITIALIZED;
|
|
|
|
|
status=WAITING_CLIENT_DATA;
|
|
|
|
|
client_myds->DSS=STATE_SLEEP;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
case PINGING_SERVER:
|
|
|
|
|
if (myds->revents) {
|
|
|
|
|
myconn->handler(myds->revents);
|
|
|
|
|
@ -529,8 +582,16 @@ __exit_DSS__STATE_NOT_INITIALIZED:
|
|
|
|
|
if (myds->revents) {
|
|
|
|
|
myconn->handler(myds->revents);
|
|
|
|
|
if (myconn->async_state_machine==ASYNC_SET_NAMES_SUCCESSFUL) {
|
|
|
|
|
#ifdef EXPMARIA
|
|
|
|
|
myds->DSS=STATE_MARIADB_QUERY;
|
|
|
|
|
status=PROCESSING_QUERY;
|
|
|
|
|
myds->myconn->async_state_machine=ASYNC_QUERY_START;
|
|
|
|
|
myds->myconn->set_query(myds->mysql_real_query.ptr,myds->mysql_real_query.size);
|
|
|
|
|
myds->myconn->handler(0);
|
|
|
|
|
#else
|
|
|
|
|
myds->DSS=STATE_READY;
|
|
|
|
|
status=WAITING_SERVER_DATA;
|
|
|
|
|
#endif /* EXPMARIA */
|
|
|
|
|
unsigned int k;
|
|
|
|
|
PtrSize_t pkt2;
|
|
|
|
|
for (k=0; k<mybe->server_myds->PSarrayOUTpending->len;) {
|
|
|
|
|
@ -1456,6 +1517,64 @@ void MySQL_Session::handler___client_DSS_QUERY_SENT___send_CHANGE_USER_to_backen
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
void MySQL_Session::MySQL_Result_to_MySQL_wire(MYSQL *mysql, MYSQL_RES *result, MySQL_Protocol *myprot) {
|
|
|
|
|
assert(myprot);
|
|
|
|
|
MySQL_Data_Stream *myds=myprot->get_myds();
|
|
|
|
|
myds->DSS=STATE_QUERY_SENT_DS;
|
|
|
|
|
int sid=1;
|
|
|
|
|
unsigned int num_fields=mysql_field_count(mysql);
|
|
|
|
|
unsigned int num_rows;
|
|
|
|
|
if (result) {
|
|
|
|
|
// we have a result set, this should be a SELECT statement with result
|
|
|
|
|
assert(result->current_field==0);
|
|
|
|
|
myprot->generate_pkt_column_count(true,NULL,NULL,sid,num_fields); sid++;
|
|
|
|
|
for (unsigned int i=0; i<num_fields; i++) {
|
|
|
|
|
MYSQL_FIELD *field=mysql_fetch_field(result);
|
|
|
|
|
myprot->generate_pkt_field(true,NULL,NULL,sid,field->db,field->table,field->org_table,field->name,field->org_name,field->charsetnr,field->length,field->type,field->flags,field->decimals,false,0,NULL);
|
|
|
|
|
sid++;
|
|
|
|
|
}
|
|
|
|
|
myds->DSS=STATE_COLUMN_DEFINITION;
|
|
|
|
|
num_rows=mysql_num_rows(result);
|
|
|
|
|
myprot->generate_pkt_EOF(true,NULL,NULL,sid,0,0); sid++;
|
|
|
|
|
//char **p=(char **)malloc(sizeof(char*)*num_fields);
|
|
|
|
|
//int *l=(int *)malloc(sizeof(int*)*num_fields);
|
|
|
|
|
//p[0]="column test";
|
|
|
|
|
for (unsigned int r=0; r<num_rows; r++) {
|
|
|
|
|
MYSQL_ROW row=mysql_fetch_row(result);
|
|
|
|
|
unsigned long *lengths=mysql_fetch_lengths(result);
|
|
|
|
|
//
|
|
|
|
|
// for (int i=0; i<num_fields; i++) {
|
|
|
|
|
// l[i]=result->rows[r]->sizes[i];
|
|
|
|
|
// p[i]=result->rows[r]->fields[i];
|
|
|
|
|
// }
|
|
|
|
|
myprot->generate_pkt_row(true,NULL,NULL,sid,num_fields,lengths,row); sid++;
|
|
|
|
|
}
|
|
|
|
|
myds->DSS=STATE_ROW;
|
|
|
|
|
myprot->generate_pkt_EOF(true,NULL,NULL,sid,0,2); sid++;
|
|
|
|
|
myds->DSS=STATE_SLEEP;
|
|
|
|
|
//free(l);
|
|
|
|
|
//free(p);
|
|
|
|
|
} else { // no result set
|
|
|
|
|
if (num_fields) {
|
|
|
|
|
num_rows = mysql_affected_rows(mysql);
|
|
|
|
|
myprot->generate_pkt_OK(true,NULL,NULL,sid,num_rows,mysql->insert_id,0,mysql->warning_count,mysql->info);
|
|
|
|
|
} else {
|
|
|
|
|
// error
|
|
|
|
|
char sqlstate[10];
|
|
|
|
|
sprintf(sqlstate,"#%s",mysql_sqlstate(mysql));
|
|
|
|
|
myprot->generate_pkt_ERR(true,NULL,NULL,sid,mysql_errno(mysql),sqlstate,mysql_error(mysql));
|
|
|
|
|
}
|
|
|
|
|
// if (error) {
|
|
|
|
|
// // there was an error
|
|
|
|
|
// myprot->generate_pkt_ERR(true,NULL,NULL,sid,1045,(char *)"#28000",error);
|
|
|
|
|
// } else {
|
|
|
|
|
// // no error, DML succeeded
|
|
|
|
|
// myprot->generate_pkt_OK(true,NULL,NULL,sid,affected_rows,0,0,0,NULL);
|
|
|
|
|
// }
|
|
|
|
|
// myds->DSS=STATE_SLEEP;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void MySQL_Session::SQLite3_to_MySQL(SQLite3_result *result, char *error, int affected_rows, MySQL_Protocol *myprot) {
|
|
|
|
|
assert(myprot);
|
|
|
|
|
MySQL_Data_Stream *myds=myprot->get_myds();
|
|
|
|
|
@ -1472,7 +1591,7 @@ void MySQL_Session::SQLite3_to_MySQL(SQLite3_result *result, char *error, int af
|
|
|
|
|
|
|
|
|
|
myprot->generate_pkt_EOF(true,NULL,NULL,sid,0,0); sid++;
|
|
|
|
|
char **p=(char **)malloc(sizeof(char*)*result->columns);
|
|
|
|
|
int *l=(int *)malloc(sizeof(int*)*result->columns);
|
|
|
|
|
unsigned long *l=(unsigned long *)malloc(sizeof(unsigned long *)*result->columns);
|
|
|
|
|
//p[0]="column test";
|
|
|
|
|
for (int r=0; r<result->rows_count; r++) {
|
|
|
|
|
for (int i=0; i<result->columns; i++) {
|
|
|
|
|
|