diff --git a/query_classifier/query_classifier.cc b/query_classifier/query_classifier.cc index dfcf8d149..c5ca3e0ba 100644 --- a/query_classifier/query_classifier.cc +++ b/query_classifier/query_classifier.cc @@ -67,28 +67,18 @@ extern __thread log_info_t tls_log_info; #define QTYPE_LESS_RESTRICTIVE_THAN_WRITE(t) (tgwbuf_bufobj == NULL || + buf->gwbuf_bufobj->bo_data == NULL || + (mysql = (MYSQL *)((parsing_info_t *)buf->gwbuf_bufobj->bo_data)->pi_handle) == NULL || + mysql->thd == NULL || + (THD *)(mysql->thd))->lex == NULL || + (THD *)(mysql->thd))->lex->prepared_stmt_name == NULL) + { + return NULL; + } return ((THD *)(mysql->thd))->lex->prepared_stmt_name.str; - } +#endif /** * Get the parse tree from parsed querybuf. @@ -975,31 +983,29 @@ char* skygw_query_classifier_get_stmtname( LEX* get_lex(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); + parsing_info_t* pi; + MYSQL* mysql; + THD* thd; + + if (querybuf == NULL || !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; - } - - return thd->lex; + 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; + } + return thd->lex; } @@ -1009,7 +1015,7 @@ LEX* get_lex(GWBUF* querybuf) * @param thd Pointer to a valid THD * @return Pointer to the head of the TABLE_LIST chain or NULL in case of an error */ -void* skygw_get_affected_tables(void* lexptr) +static void* skygw_get_affected_tables(void* lexptr) { LEX* lex = (LEX*)lexptr; @@ -1027,87 +1033,93 @@ void* skygw_get_affected_tables(void* lexptr) /** * Reads the parsetree and lists all the affected tables and views in the query. - * In the case of an error, the size of the table is set to zero and no memory is allocated. - * The caller must free the allocated memory. + * In the case of an error, the size of the table is set to zero and no memory + * is allocated. The caller must free the allocated memory. * * @param querybuf GWBUF where the table names are extracted from * @param tblsize Pointer where the number of tables is written * @return Array of null-terminated strings with the table names */ -char** skygw_get_table_names(GWBUF* querybuf,int* tblsize, bool fullnames) +char** skygw_get_table_names(GWBUF* querybuf, int* tblsize, bool fullnames) { - LEX* lex; - TABLE_LIST* tbl; - int i = 0, + LEX* lex; + TABLE_LIST* tbl; + int i = 0, currtblsz = 0; - char **tables = NULL, + char **tables = NULL, **tmp = NULL; - if( (lex = get_lex(querybuf)) == NULL || - lex->current_select == NULL ) + if(querybuf == NULL || + tblsize == NULL || + (lex = get_lex(querybuf)) == NULL || + lex->current_select == NULL) { - goto retblock; - } + goto retblock; + } - lex->current_select = lex->all_selects_list; + lex->current_select = lex->all_selects_list; - while(lex->current_select){ - - tbl = (TABLE_LIST*)skygw_get_affected_tables(lex); + while(lex->current_select) + { + tbl = (TABLE_LIST*)skygw_get_affected_tables(lex); - while (tbl) - { - if(i >= currtblsz){ - - tmp = (char**)malloc(sizeof(char*)*(currtblsz*2+1)); - - if(tmp){ - if(currtblsz > 0){ - int x; - for(x = 0;x= currtblsz) { - if(tbl->db && strcmp(tbl->db,"skygw_virtual") != 0) + tmp = (char**)malloc(sizeof(char*)*(currtblsz*2+1)); + + if(tmp) + { + if(currtblsz > 0) { - catnm = (char*)calloc(strlen(tbl->db) + strlen(tbl->table_name) + 2,sizeof(char)); + int x; + for(x = 0; xdb && + strcmp(tbl->db,"skygw_virtual") != 0) + { + catnm = (char*)calloc(strlen(tbl->db) + + strlen(tbl->table_name) + + 2, + sizeof(char)); strcpy(catnm,tbl->db); strcat(catnm,"."); strcat(catnm,tbl->table_name); } + } + + if(catnm) + { + tables[i++] = catnm; + } + else + { + tables[i++] = strdup(tbl->table_name); + } + tbl=tbl->next_local; } - - if(catnm) - { - tables[i++] = catnm; - } - else - { - tables[i++] = strdup(tbl->table_name); - } - - tbl=tbl->next_local; - } - } - lex->current_select = lex->current_select->next_select_in_list(); - } - - retblock: - *tblsize = i; - return tables; + } /*< while (tbl) */ + lex->current_select = lex->current_select->next_select_in_list(); + } /*< while(lex->current_select) */ +retblock: + *tblsize = i; + return tables; } /** @@ -1117,52 +1129,70 @@ char** skygw_get_table_names(GWBUF* querybuf,int* tblsize, bool fullnames) */ char* skygw_get_created_table_name(GWBUF* querybuf) { - LEX* lex; - - if((lex = get_lex(querybuf)) == NULL) - { - return NULL; - } + LEX* lex; + + if(querybuf == NULL || (lex = get_lex(querybuf)) == NULL) + { + return NULL; + } - if(lex->create_last_non_select_table && - lex->create_last_non_select_table->table_name){ - char* name = strdup(lex->create_last_non_select_table->table_name); - return name; - }else{ - return NULL; - } - + if (lex->create_last_non_select_table && + lex->create_last_non_select_table->table_name) + { + char* name = strdup(lex->create_last_non_select_table->table_name); + return name; + } + else + { + return NULL; + } } /** - * Checks whether the query is a "real" query ie. SELECT,UPDATE,INSERT,DELETE or any variation of these. - * Queries that affect the underlying database are not considered as real queries and the queries that target - * specific row or variable data are regarded as the real queries. + * Checks whether the query is a "real" query ie. SELECT,UPDATE,INSERT,DELETE or + * any variation of these. Queries that affect the underlying database are not + * considered as real queries and the queries that target specific row or + * variable data are regarded as the real queries. + * * @param GWBUF to analyze + * * @return true if the query is a real query, otherwise false */ bool skygw_is_real_query(GWBUF* querybuf) { - LEX* lex = get_lex(querybuf); - if(lex){ - switch(lex->sql_command){ - case SQLCOM_SELECT: - return lex->all_selects_list->table_list.elements > 0; - case SQLCOM_UPDATE: - case SQLCOM_INSERT: - case SQLCOM_INSERT_SELECT: - case SQLCOM_DELETE: - case SQLCOM_TRUNCATE: - case SQLCOM_REPLACE: - case SQLCOM_REPLACE_SELECT: - case SQLCOM_PREPARE: - case SQLCOM_EXECUTE: - return true; - default: - return false; + bool succp; + LEX* lex; + + if (querybuf == NULL || + (lex = get_lex(querybuf)) == NULL) + { + succp = false; + goto retblock; } - } - return false; + switch(lex->sql_command) { + case SQLCOM_SELECT: + succp = lex->all_selects_list->table_list.elements > 0; + goto retblock; + break; + case SQLCOM_UPDATE: + case SQLCOM_INSERT: + case SQLCOM_INSERT_SELECT: + case SQLCOM_DELETE: + case SQLCOM_TRUNCATE: + case SQLCOM_REPLACE: + case SQLCOM_REPLACE_SELECT: + case SQLCOM_PREPARE: + case SQLCOM_EXECUTE: + succp = true; + goto retblock; + break; + default: + succp = false; + goto retblock; + break; + } +retblock: + return succp; } @@ -1173,10 +1203,11 @@ bool skygw_is_real_query(GWBUF* querybuf) */ bool is_drop_table_query(GWBUF* querybuf) { - LEX* lex; + LEX* lex; - return (lex = get_lex(querybuf)) != NULL && - lex->sql_command == SQLCOM_DROP_TABLE; + return (querybuf != NULL && + (lex = get_lex(querybuf)) != NULL && + lex->sql_command == SQLCOM_DROP_TABLE); } /** @@ -1202,7 +1233,8 @@ char* skygw_get_canonical( Item* item; char* querystr; - if (!GWBUF_IS_PARSED(querybuf)) + if (querybuf == NULL || + !GWBUF_IS_PARSED(querybuf)) { querystr = NULL; goto retblock; @@ -1339,25 +1371,30 @@ retblock: void parsing_info_done( void* ptr) { - parsing_info_t* pi = (parsing_info_t *)ptr; + parsing_info_t* pi; + + if (ptr) + { + pi = (parsing_info_t *)ptr; - if (pi->pi_handle != NULL) - { - MYSQL* mysql = (MYSQL *)pi->pi_handle; - - if (mysql->thd != NULL) - { - (*mysql->methods->free_embedded_thd)(mysql); - mysql->thd = NULL; - } - mysql_close(mysql); - } - /** Free plain text query string */ - if (pi->pi_query_plain_str != NULL) - { - free(pi->pi_query_plain_str); - } - free(pi); + if (pi->pi_handle != NULL) + { + MYSQL* mysql = (MYSQL *)pi->pi_handle; + + if (mysql->thd != NULL) + { + (*mysql->methods->free_embedded_thd)(mysql); + mysql->thd = NULL; + } + mysql_close(mysql); + } + /** Free plain text query string */ + if (pi->pi_query_plain_str != NULL) + { + free(pi->pi_query_plain_str); + } + free(pi); + } } /** diff --git a/query_classifier/query_classifier.h b/query_classifier/query_classifier.h index 3600bce5a..5837b81c7 100644 --- a/query_classifier/query_classifier.h +++ b/query_classifier/query_classifier.h @@ -83,12 +83,13 @@ typedef struct parsing_info_st { skygw_query_type_t query_classifier_get_type(GWBUF* querybuf); /** Free THD context and close MYSQL */ -char* skygw_query_classifier_get_stmtname(MYSQL* mysql); +#if defined(NOT_USED) +char* skygw_query_classifier_get_stmtname(GWBUF* buf); +#endif char* skygw_get_created_table_name(GWBUF* querybuf); bool is_drop_table_query(GWBUF* querybuf); bool skygw_is_real_query(GWBUF* querybuf); -void* skygw_get_affected_tables(void* lexptr); -char** skygw_get_table_names(GWBUF* querybuf,int* tblsize,bool fullnames); +char** skygw_get_table_names(GWBUF* querybuf, int* tblsize, bool fullnames); char* skygw_get_canonical(GWBUF* querybuf); bool parse_query (GWBUF* querybuf); parsing_info_t* parsing_info_init(void (*donefun)(void *));