fixed temporary tables looking for database drops instead of table drops
This commit is contained in:
@ -544,7 +544,8 @@ static skygw_query_type_t resolve_query_type(
|
|||||||
{
|
{
|
||||||
type |= QUERY_TYPE_WRITE;
|
type |= QUERY_TYPE_WRITE;
|
||||||
|
|
||||||
if (lex->create_info.options & HA_LEX_CREATE_TMP_TABLE)
|
if (lex->create_info.options & HA_LEX_CREATE_TMP_TABLE &&
|
||||||
|
lex->sql_command == SQLCOM_CREATE_TABLE)
|
||||||
{
|
{
|
||||||
type |= QUERY_TYPE_CREATE_TMP_TABLE;
|
type |= QUERY_TYPE_CREATE_TMP_TABLE;
|
||||||
}
|
}
|
||||||
@ -870,7 +871,6 @@ char* skygw_query_classifier_get_stmtname(
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
||||||
* Finds the head of the list of tables affected by the current select statement.
|
* Finds the head of the list of tables affected by the current select statement.
|
||||||
* @param thd Pointer to a valid THD
|
* @param thd Pointer to a valid THD
|
||||||
* @return Pointer to the head of the TABLE_LIST chain or NULL in case of an error
|
* @return Pointer to the head of the TABLE_LIST chain or NULL in case of an error
|
||||||
@ -908,7 +908,6 @@ char** skygw_get_table_names(GWBUF* querybuf,int* tblsize)
|
|||||||
MYSQL* mysql;
|
MYSQL* mysql;
|
||||||
THD* thd;
|
THD* thd;
|
||||||
TABLE_LIST* tbl;
|
TABLE_LIST* tbl;
|
||||||
SELECT_LEX*slx;
|
|
||||||
int i = 0, currtblsz = 0;
|
int i = 0, currtblsz = 0;
|
||||||
char**tables,**tmp;
|
char**tables,**tmp;
|
||||||
|
|
||||||
@ -975,7 +974,78 @@ char** skygw_get_table_names(GWBUF* querybuf,int* tblsize)
|
|||||||
*tblsize = i;
|
*tblsize = i;
|
||||||
return tables;
|
return tables;
|
||||||
}
|
}
|
||||||
|
/**
|
||||||
|
* Extract the name of the created table.
|
||||||
|
* @param querybuf Buffer to use.
|
||||||
|
* @return A pointer to the name if a table was created, otherwise NULL
|
||||||
|
*/
|
||||||
|
char* skygw_get_created_table_name(GWBUF* querybuf)
|
||||||
|
{
|
||||||
|
parsing_info_t* pi;
|
||||||
|
MYSQL* mysql;
|
||||||
|
THD* thd;
|
||||||
|
if (!GWBUF_IS_PARSED(querybuf))
|
||||||
|
{
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
pi = (parsing_info_t *)gwbuf_get_buffer_object_data(querybuf,
|
||||||
|
GWBUF_PARSING_INFO);
|
||||||
|
|
||||||
|
if (pi == NULL)
|
||||||
|
{
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((mysql = (MYSQL *)pi->pi_handle) == NULL ||
|
||||||
|
(thd = (THD *)mysql->thd) == NULL)
|
||||||
|
{
|
||||||
|
ss_dassert(mysql != NULL &&
|
||||||
|
thd != NULL);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(thd->lex->create_last_non_select_table &&
|
||||||
|
thd->lex->create_last_non_select_table->table_name){
|
||||||
|
char* name = strdup(thd->lex->create_last_non_select_table->table_name);
|
||||||
|
return name;
|
||||||
|
}else{
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* Checks whether the buffer contains a DROP TABLE... query.
|
||||||
|
* @param querybuf Buffer to inspect
|
||||||
|
* @return true if it contains the query otherwise false
|
||||||
|
*/
|
||||||
|
bool is_drop_table_query(GWBUF* querybuf)
|
||||||
|
{
|
||||||
|
parsing_info_t* pi;
|
||||||
|
MYSQL* mysql;
|
||||||
|
THD* thd;
|
||||||
|
|
||||||
|
if (!GWBUF_IS_PARSED(querybuf))
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
pi = (parsing_info_t *)gwbuf_get_buffer_object_data(querybuf,
|
||||||
|
GWBUF_PARSING_INFO);
|
||||||
|
|
||||||
|
if (pi == NULL)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((mysql = (MYSQL *)pi->pi_handle) == NULL ||
|
||||||
|
(thd = (THD *)mysql->thd) == NULL)
|
||||||
|
{
|
||||||
|
ss_dassert(mysql != NULL &&
|
||||||
|
thd != NULL);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return thd->lex->sql_command == SQLCOM_DROP_TABLE;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Replace user-provided literals with question marks. Return a copy of the
|
* Replace user-provided literals with question marks. Return a copy of the
|
||||||
|
@ -74,6 +74,8 @@ skygw_query_type_t query_classifier_get_type(GWBUF* querybuf);
|
|||||||
|
|
||||||
/** Free THD context and close MYSQL */
|
/** Free THD context and close MYSQL */
|
||||||
char* skygw_query_classifier_get_stmtname(MYSQL* mysql);
|
char* skygw_query_classifier_get_stmtname(MYSQL* mysql);
|
||||||
|
char* skygw_get_created_table_name(GWBUF* querybuf);
|
||||||
|
bool is_drop_table_query(GWBUF* querybuf);
|
||||||
void* skygw_get_affected_tables(void* thdp);
|
void* skygw_get_affected_tables(void* thdp);
|
||||||
char** skygw_get_table_names(GWBUF* querybuf,int* tblsize);
|
char** skygw_get_table_names(GWBUF* querybuf,int* tblsize);
|
||||||
char* skygw_get_canonical(GWBUF* querybuf);
|
char* skygw_get_canonical(GWBUF* querybuf);
|
||||||
|
@ -287,6 +287,9 @@ static int hashcmpfun (void *, void *);
|
|||||||
static int hashkeyfun(
|
static int hashkeyfun(
|
||||||
void* key)
|
void* key)
|
||||||
{
|
{
|
||||||
|
if(key == NULL){
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
unsigned int hash = 0,c = 0;
|
unsigned int hash = 0,c = 0;
|
||||||
char* ptr = (char*)key;
|
char* ptr = (char*)key;
|
||||||
while((c = *ptr++)){
|
while((c = *ptr++)){
|
||||||
@ -1246,7 +1249,6 @@ static int routeQuery(
|
|||||||
HASHTABLE* h;
|
HASHTABLE* h;
|
||||||
MYSQL_session* data;
|
MYSQL_session* data;
|
||||||
size_t len;
|
size_t len;
|
||||||
MYSQL* mysql = NULL;
|
|
||||||
route_target_t route_target;
|
route_target_t route_target;
|
||||||
|
|
||||||
|
|
||||||
@ -1541,39 +1543,34 @@ static int routeQuery(
|
|||||||
}
|
}
|
||||||
target_dcb = master_dcb;
|
target_dcb = master_dcb;
|
||||||
}
|
}
|
||||||
/** Lock router session */
|
|
||||||
/*if (!rses_begin_locked_router_action(router_cli_ses))
|
|
||||||
{
|
|
||||||
goto return_ret;
|
|
||||||
} */
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* If query is of type QUERY_TYPE_CREATE_TMP_TABLE then find out
|
* If query is of type QUERY_TYPE_CREATE_TMP_TABLE then find out
|
||||||
* the database and table name, create a hashvalue and
|
* the database and table name, create a hashvalue and
|
||||||
* add it to the router client session's property. If property
|
* add it to the router client session's property. If property
|
||||||
* doesn't exist then create it first.
|
* doesn't exist then create it first. If the query is DROP TABLE...
|
||||||
|
* then see if it targets a temporary table and remove it from the hashtable
|
||||||
|
* if it does.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
if(QUERY_IS_TYPE(qtype, QUERY_TYPE_CREATE_TMP_TABLE) ||
|
|
||||||
packet_type == MYSQL_COM_DROP_DB){
|
|
||||||
|
|
||||||
tbl = skygw_get_table_names(querybuf,&tsize);
|
|
||||||
|
|
||||||
if(tsize == 1 && tbl[0])
|
|
||||||
{ /**One valid table created*/
|
|
||||||
|
|
||||||
klen = strlen(dbname) + strlen(tbl[0]) + 2;
|
|
||||||
hkey = calloc(klen,sizeof(char));
|
|
||||||
strcpy(hkey,dbname);
|
|
||||||
strcat(hkey,".");
|
|
||||||
strcat(hkey,tbl[0]);
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
if(QUERY_IS_TYPE(qtype, QUERY_TYPE_CREATE_TMP_TABLE)){
|
if(QUERY_IS_TYPE(qtype, QUERY_TYPE_CREATE_TMP_TABLE)){
|
||||||
|
|
||||||
bool is_temp = true;
|
bool is_temp = true;
|
||||||
|
char* tblname = NULL;
|
||||||
|
|
||||||
|
tblname = skygw_get_created_table_name(querybuf);
|
||||||
|
if(tblname && strlen(tblname) > 0){
|
||||||
|
klen = strlen(dbname) + strlen(tblname) + 2;
|
||||||
|
hkey = calloc(klen,sizeof(char));
|
||||||
|
strcpy(hkey,dbname);
|
||||||
|
strcat(hkey,".");
|
||||||
|
strcat(hkey,tblname);
|
||||||
|
}else{
|
||||||
|
hkey = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
if(rses_prop_tmp == NULL){
|
if(rses_prop_tmp == NULL){
|
||||||
if((rses_prop_tmp =
|
if((rses_prop_tmp =
|
||||||
@ -1603,7 +1600,7 @@ static int routeQuery(
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if(
|
if( hkey &&
|
||||||
hashtable_add(
|
hashtable_add(
|
||||||
rses_prop_tmp->rses_prop_data.temp_tables,
|
rses_prop_tmp->rses_prop_data.temp_tables,
|
||||||
(void *)hkey,
|
(void *)hkey,
|
||||||
@ -1616,40 +1613,51 @@ static int routeQuery(
|
|||||||
"Temporary table conflict in hashtable: %s",hkey)));
|
"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(
|
|
||||||
LOGFILE_TRACE,
|
|
||||||
"Temporary table added: %s",hkey)));
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
#if defined(SS_DEBUG)
|
||||||
|
bool retkey = hashtable_fetch(rses_prop_tmp->rses_prop_data.temp_tables,
|
||||||
|
hkey);
|
||||||
|
if(retkey)
|
||||||
|
{
|
||||||
|
LOGIF(LT, (skygw_log_write(LOGFILE_TRACE,
|
||||||
|
"Temporary table added: %s",hkey)));
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
free(hkey);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**Check if DROP TABLE... targets a temporary table*/
|
/**Check if DROP TABLE... targets a temporary table*/
|
||||||
if(packet_type == MYSQL_COM_DROP_DB)
|
if(is_drop_table_query(querybuf))
|
||||||
{
|
{
|
||||||
if(rses_prop_tmp && rses_prop_tmp->rses_prop_data.temp_tables)
|
|
||||||
{
|
|
||||||
hashtable_delete(rses_prop_tmp->rses_prop_data.temp_tables, (void *)hkey);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
free(hkey);
|
tbl = skygw_get_table_names(querybuf,&tsize);
|
||||||
|
|
||||||
if(tsize > 0)
|
|
||||||
{
|
|
||||||
for(i = 0;i<tsize;i++)
|
for(i = 0;i<tsize;i++)
|
||||||
{
|
{
|
||||||
|
|
||||||
|
klen = strlen(dbname) + strlen(tbl[i]) + 2;
|
||||||
|
hkey = calloc(klen,sizeof(char));
|
||||||
|
strcpy(hkey,dbname);
|
||||||
|
strcat(hkey,".");
|
||||||
|
strcat(hkey,tbl[i]);
|
||||||
|
|
||||||
|
if(rses_prop_tmp && rses_prop_tmp->rses_prop_data.temp_tables)
|
||||||
|
{
|
||||||
|
if(hashtable_delete(rses_prop_tmp->rses_prop_data.temp_tables, (void *)hkey))
|
||||||
|
{
|
||||||
|
LOGIF(LT, (skygw_log_write(LOGFILE_TRACE,
|
||||||
|
"Temporary table dropped: %s",hkey)));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
free(tbl[i]);
|
free(tbl[i]);
|
||||||
|
free(hkey);
|
||||||
}
|
}
|
||||||
free(tbl);
|
free(tbl);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
if (master_dcb == NULL)
|
if (master_dcb == NULL)
|
||||||
{
|
{
|
||||||
|
Reference in New Issue
Block a user