added temporary table detection for reads

This commit is contained in:
Markus Makela
2014-08-30 19:51:59 +03:00
parent 7629c455a6
commit 45faa38877

View File

@ -291,15 +291,26 @@ static int hashcmpfun(
void* v1, void* v1,
void* v2) void* v2)
{ {
int i1; char* i1 = (char*) v1;
int i2; char* i2 = (char*) v2;
i1 = *(int *)v1; return strcmp(i1,i2);
i2 = *(int *)v2;
return (i1 < i2 ? -1 : (i1 > i2 ? 1 : 0));
} }
static void* hstrdup(void* fval)
{
char* str = (char*)fval;
return strdup(str);
}
static void* hfree(void* fval)
{
free (fval);
return NULL;
}
/** /**
* Implementation of the mandatory version entry point * Implementation of the mandatory version entry point
* *
@ -1069,7 +1080,7 @@ static int routeQuery(
DCB* slave_dcb = NULL; DCB* slave_dcb = NULL;
ROUTER_INSTANCE* inst = (ROUTER_INSTANCE *)instance; ROUTER_INSTANCE* inst = (ROUTER_INSTANCE *)instance;
ROUTER_CLIENT_SES* router_cli_ses = (ROUTER_CLIENT_SES *)router_session; ROUTER_CLIENT_SES* router_cli_ses = (ROUTER_CLIENT_SES *)router_session;
rses_property_t* rses_prop; rses_property_t* rses_prop_tmp;
bool rses_is_closed = false; bool rses_is_closed = false;
bool target_tmp_table = false; bool target_tmp_table = false;
char *dbname,*hkey; char *dbname,*hkey;
@ -1089,7 +1100,7 @@ static int routeQuery(
packet = GWBUF_DATA(querybuf); packet = GWBUF_DATA(querybuf);
packet_type = packet[4]; packet_type = packet[4];
rses_prop = *router_cli_ses->rses_properties; rses_prop_tmp = router_cli_ses->rses_properties[RSES_PROP_TYPE_TMPTABLES];
if (rses_is_closed) if (rses_is_closed)
{ {
@ -1172,9 +1183,9 @@ static int routeQuery(
/** /**
*Check if the query targets a temporary table *Check if the query targets a temporary table
*/ */
if(QUERY_IS_TYPE(qtype, QUERY_TYPE_READ)){ if(QUERY_IS_TYPE(qtype, QUERY_TYPE_READ)){
tbl = skygw_get_table_names(querybuf,&tsize); tbl = skygw_get_table_names(querybuf,&tsize);
if(tsize > 0) if(tsize > 0)
@ -1185,18 +1196,18 @@ static int routeQuery(
strcpy(hkey,dbname); strcpy(hkey,dbname);
strcat(hkey,"."); strcat(hkey,".");
strcat(hkey,tbl[0]); strcat(hkey,tbl[0]);
if(rses_prop && rses_prop->rses_prop_data.temp_tables){ if(rses_prop_tmp && rses_prop_tmp->rses_prop_data.temp_tables){
if((target_tmp_table = hashtable_fetch(rses_prop->rses_prop_data.temp_tables,(void *)hkey))) if((target_tmp_table = (bool)hashtable_fetch(rses_prop_tmp->rses_prop_data.temp_tables,(void *)hkey)))
{ {
/**Query target is a temporary table*/ /**Query target is a temporary table*/
qtype = QUERY_TYPE_READ_TMP_TABLE;
LOGIF(LT, (skygw_log_write( LOGIF(LT, (skygw_log_write(LOGFILE_TRACE,
LOGFILE_TRACE,
"Query targets a temporary table: %s",hkey))); "Query targets a temporary table: %s",hkey)));
} }
} }
free(hkey);
} }
@ -1207,10 +1218,6 @@ static int routeQuery(
} }
} }
/** /**
@ -1274,8 +1281,7 @@ static int routeQuery(
goto return_ret; goto return_ret;
} }
else if (QUERY_IS_TYPE(qtype, QUERY_TYPE_READ) && else if (QUERY_IS_TYPE(qtype, QUERY_TYPE_READ) &&
!router_cli_ses->rses_transaction_active && !router_cli_ses->rses_transaction_active)
!target_tmp_table)
{ {
bool succp; bool succp;
@ -1350,40 +1356,42 @@ static int routeQuery(
goto return_ret; goto return_ret;
} }
//#if defined(TEMPORARY_TABLES)
if(!query_is_parsed(querybuf) && !parse_query(querybuf)){
LOGIF(LE, (skygw_log_write(
LOGFILE_ERROR,
"Error: Unable to parse query.")));
}
qtype = query_classifier_get_type(querybuf);
if(QUERY_IS_TYPE(qtype, QUERY_TYPE_CREATE_TMP_TABLE)){ /**
* If query is of type QUERY_TYPE_CREATE_TMP_TABLE then find out
* the database and table name, create a hashvalue and
* add it to the router client session's property. If property
bool is_temp = true; * doesn't exist then create it first.
*/
if(rses_prop == NULL){ if(QUERY_IS_TYPE(qtype, QUERY_TYPE_CREATE_TMP_TABLE)){
if((rses_prop =
bool is_temp = true;
if(rses_prop_tmp == NULL){
if((rses_prop_tmp =
(rses_property_t*)calloc(1,sizeof(rses_property_t)))){ (rses_property_t*)calloc(1,sizeof(rses_property_t)))){
rses_prop->rses_prop_rsession = router_cli_ses;
rses_prop->rses_prop_refcount = 1; #if defined(SS_DEBUG)
rses_prop->rses_prop_next = NULL; rses_prop_tmp->rses_prop_chk_top = CHK_NUM_ROUTER_PROPERTY;
rses_prop->rses_prop_type = RSES_PROP_TYPE_SESCMD; rses_prop_tmp->rses_prop_chk_tail = CHK_NUM_ROUTER_PROPERTY;
*router_cli_ses->rses_properties = rses_prop; #endif
rses_prop_tmp->rses_prop_rsession = router_cli_ses;
rses_prop_tmp->rses_prop_refcount = 1;
rses_prop_tmp->rses_prop_next = NULL;
rses_prop_tmp->rses_prop_type = RSES_PROP_TYPE_TMPTABLES;
router_cli_ses->rses_properties[RSES_PROP_TYPE_TMPTABLES] = rses_prop_tmp;
} }
} }
if( rses_prop->rses_prop_data.temp_tables == NULL){ if( rses_prop_tmp->rses_prop_data.temp_tables == NULL){
h = hashtable_alloc(10000, hashkeyfun, hashcmpfun); h = hashtable_alloc(7, hashkeyfun, hashcmpfun);
hashtable_memory_fns(h,hstrdup,NULL,hfree,NULL);
if(h){ if(h){
rses_prop->rses_prop_data.temp_tables = h; rses_prop_tmp->rses_prop_data.temp_tables = h;
} }
} }
@ -1393,32 +1401,34 @@ static int routeQuery(
if(tsize == 1 && tbl[0]) if(tsize == 1 && tbl[0])
{ /**One valid table created*/ { /**One valid table created*/
klen = strlen(dbname) + strlen(tbl[0]) + 2; klen = strlen(dbname) + strlen(tbl[0]) + 2;
hkey = calloc(klen,sizeof(char)); hkey = calloc(klen,sizeof(char));
strcpy(hkey,dbname); strcpy(hkey,dbname);
strcat(hkey,"."); strcat(hkey,".");
strcat(hkey,tbl[0]); strcat(hkey,tbl[0]);
if( if(
hashtable_add( hashtable_add(
rses_prop->rses_prop_data.temp_tables, rses_prop_tmp->rses_prop_data.temp_tables,
(void *)hkey, (void *)hkey,
(void *)&is_temp (void *)is_temp
) )
== 0) /**Conflict in hash table*/ == 0) /**Conflict in hash table*/
{ {
LOGIF(LT, (skygw_log_write(
LOGFILE_TRACE,
"Temporary table conflict in hashtable: %s",hkey)));
}
#if defined(SS_DEBUG)
bool retkey = hashtable_fetch(
rses_prop_tmp->rses_prop_data.temp_tables,
hkey);
if(retkey){
LOGIF(LT, (skygw_log_write( LOGIF(LT, (skygw_log_write(
LOGFILE_TRACE, LOGFILE_TRACE,
"Temporary table conflict in hashtable: %s",hkey))); "Temporary table added: %s",hkey)));
} }
char* retkey = hashtable_fetch( #endif
rses_prop->rses_prop_data.temp_tables,
hkey);
if(retkey){
LOGIF(LT, (skygw_log_write(
LOGFILE_TRACE,
"Temporary table added: %s",retkey)));
}
} }
if(tsize > 0){ if(tsize > 0){
@ -1426,16 +1436,9 @@ LOGIF(LT, (skygw_log_write(
free(tbl[i]); free(tbl[i]);
} }
free(tbl); free(tbl);
free(hkey);
} }
} }
/**
* If query is of type QUERY_TYPE_CREATE_TMP_TABLE then find out
* the database and table name, create a hashvalue and
* add it to the router client session's property. If property
* doesn't exist then create it first.
*/
//#endif
if (master_dcb == NULL) if (master_dcb == NULL)
{ {
@ -2436,6 +2439,9 @@ static void rses_property_done(
case RSES_PROP_TYPE_SESCMD: case RSES_PROP_TYPE_SESCMD:
mysql_sescmd_done(&prop->rses_prop_data.sescmd); mysql_sescmd_done(&prop->rses_prop_data.sescmd);
break; break;
case RSES_PROP_TYPE_TMPTABLES:
hashtable_free(prop->rses_prop_data.temp_tables);
break;
default: default:
LOGIF(LD, (skygw_log_write( LOGIF(LD, (skygw_log_write(
LOGFILE_DEBUG, LOGFILE_DEBUG,
@ -2836,7 +2842,7 @@ static bool execute_sescmd_in_backend(
break; break;
case MYSQL_COM_INIT_DB: case MYSQL_COM_INIT_DB:
//#if defined(TEMPORARY_TABLES)
/** /**
* Record database name and store to session. * Record database name and store to session.
*/ */
@ -2850,10 +2856,11 @@ static bool execute_sescmd_in_backend(
data = dcb->session->data; data = dcb->session->data;
tmpbuf = scur->scmd_cur_cmd->my_sescmd_buf; tmpbuf = scur->scmd_cur_cmd->my_sescmd_buf;
qlen = MYSQL_GET_PACKET_LEN((unsigned char*)tmpbuf->start); qlen = MYSQL_GET_PACKET_LEN((unsigned char*)tmpbuf->start);
memset(data->db,0,MYSQL_DATABASE_MAXLEN+1);
strncpy(data->db,tmpbuf->start+5,qlen - 1); strncpy(data->db,tmpbuf->start+5,qlen - 1);
} }
//#endif
case MYSQL_COM_QUERY: case MYSQL_COM_QUERY:
default: default:
/** /**