Added parameter NULL checks to query_classifier.cc

This commit is contained in:
VilhoRaatikka
2015-01-10 21:29:29 +02:00
parent 4c20ed4c11
commit ee2876e9a4
2 changed files with 207 additions and 169 deletions

View File

@ -67,28 +67,18 @@ extern __thread log_info_t tls_log_info;
#define QTYPE_LESS_RESTRICTIVE_THAN_WRITE(t) (t<QUERY_TYPE_WRITE ? true : false) #define QTYPE_LESS_RESTRICTIVE_THAN_WRITE(t) (t<QUERY_TYPE_WRITE ? true : false)
static THD* get_or_create_thd_for_parsing( static THD* get_or_create_thd_for_parsing(MYSQL* mysql, char* query_str);
MYSQL* mysql, static unsigned long set_client_flags(MYSQL* mysql);
char* query_str); static bool create_parse_tree(THD* thd);
static skygw_query_type_t resolve_query_type(THD* thd);
static unsigned long set_client_flags(
MYSQL* mysql);
static bool create_parse_tree(
THD* thd);
static skygw_query_type_t resolve_query_type(
THD* thd);
static bool skygw_stmt_causes_implicit_commit( static bool skygw_stmt_causes_implicit_commit(
LEX* lex, LEX* lex,
int* autocommit_stmt); int* autocommit_stmt);
static int is_autocommit_stmt( static int is_autocommit_stmt(LEX* lex);
LEX* lex); static void parsing_info_set_plain_str(void* ptr, char* str);
static void* skygw_get_affected_tables(void* lexptr);
static void parsing_info_set_plain_str(void* ptr,
char* str);
/** /**
* Calls parser for the query includede in the buffer. Creates and adds parsing * Calls parser for the query includede in the buffer. Creates and adds parsing
@ -107,6 +97,11 @@ skygw_query_type_t query_classifier_get_type(
ss_info_dassert(querybuf != NULL, ("querybuf is NULL")); ss_info_dassert(querybuf != NULL, ("querybuf is NULL"));
if (querybuf == NULL)
{
succp = false;
goto retblock;
}
/** Create parsing info for the query and store it to buffer */ /** Create parsing info for the query and store it to buffer */
succp = query_is_parsed(querybuf); succp = query_is_parsed(querybuf);
@ -133,6 +128,7 @@ skygw_query_type_t query_classifier_get_type(
} }
} }
} }
retblock:
return qtype; return qtype;
} }
@ -158,7 +154,7 @@ bool parse_query (
/** Do not parse without releasing previous parse info first */ /** Do not parse without releasing previous parse info first */
ss_dassert(!query_is_parsed(querybuf)); ss_dassert(!query_is_parsed(querybuf));
if (query_is_parsed(querybuf)) if (querybuf == NULL || query_is_parsed(querybuf))
{ {
return false; return false;
} }
@ -225,7 +221,7 @@ bool query_is_parsed(
GWBUF* buf) GWBUF* buf)
{ {
CHK_GWBUF(buf); CHK_GWBUF(buf);
return GWBUF_IS_PARSED(buf); return (buf != NULL && GWBUF_IS_PARSED(buf));
} }
@ -957,13 +953,25 @@ return_rc:
return rc; return rc;
} }
#if defined(NOT_USED)
char* skygw_query_classifier_get_stmtname( char* skygw_query_classifier_get_stmtname(
MYSQL* mysql) GWBUF* buf)
{ {
return ((THD *)(mysql->thd))->lex->prepared_stmt_name.str; MYSQL* mysql;
if (buf == NULL ||
buf->gwbuf_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. * Get the parse tree from parsed querybuf.
@ -979,7 +987,7 @@ LEX* get_lex(GWBUF* querybuf)
MYSQL* mysql; MYSQL* mysql;
THD* thd; THD* thd;
if (!GWBUF_IS_PARSED(querybuf)) if (querybuf == NULL || !GWBUF_IS_PARSED(querybuf))
{ {
return NULL; return NULL;
} }
@ -994,11 +1002,9 @@ LEX* get_lex(GWBUF* querybuf)
if ((mysql = (MYSQL *)pi->pi_handle) == NULL || if ((mysql = (MYSQL *)pi->pi_handle) == NULL ||
(thd = (THD *)mysql->thd) == NULL) (thd = (THD *)mysql->thd) == NULL)
{ {
ss_dassert(mysql != NULL && ss_dassert(mysql != NULL && thd != NULL);
thd != NULL);
return NULL; return NULL;
} }
return thd->lex; return thd->lex;
} }
@ -1009,7 +1015,7 @@ LEX* get_lex(GWBUF* querybuf)
* @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
*/ */
void* skygw_get_affected_tables(void* lexptr) static void* skygw_get_affected_tables(void* lexptr)
{ {
LEX* lex = (LEX*)lexptr; LEX* lex = (LEX*)lexptr;
@ -1027,8 +1033,8 @@ void* skygw_get_affected_tables(void* lexptr)
/** /**
* Reads the parsetree and lists all the affected tables and views in the query. * 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. * In the case of an error, the size of the table is set to zero and no memory
* The caller must free the allocated memory. * is allocated. The caller must free the allocated memory.
* *
* @param querybuf GWBUF where the table names are extracted from * @param querybuf GWBUF where the table names are extracted from
* @param tblsize Pointer where the number of tables is written * @param tblsize Pointer where the number of tables is written
@ -1043,7 +1049,9 @@ char** skygw_get_table_names(GWBUF* querybuf,int* tblsize, bool fullnames)
char **tables = NULL, char **tables = NULL,
**tmp = NULL; **tmp = NULL;
if( (lex = get_lex(querybuf)) == NULL || if(querybuf == NULL ||
tblsize == NULL ||
(lex = get_lex(querybuf)) == NULL ||
lex->current_select == NULL) lex->current_select == NULL)
{ {
goto retblock; goto retblock;
@ -1051,39 +1059,45 @@ char** skygw_get_table_names(GWBUF* querybuf,int* tblsize, bool fullnames)
lex->current_select = lex->all_selects_list; lex->current_select = lex->all_selects_list;
while(lex->current_select){ while(lex->current_select)
{
tbl = (TABLE_LIST*)skygw_get_affected_tables(lex); tbl = (TABLE_LIST*)skygw_get_affected_tables(lex);
while (tbl) while (tbl)
{ {
if(i >= currtblsz){ if (i >= currtblsz)
{
tmp = (char**)malloc(sizeof(char*)*(currtblsz*2+1)); tmp = (char**)malloc(sizeof(char*)*(currtblsz*2+1));
if(tmp){ if(tmp)
if(currtblsz > 0){ {
if(currtblsz > 0)
{
int x; int x;
for(x = 0;x<currtblsz;x++){ for(x = 0; x<currtblsz; x++)
{
tmp[x] = tables[x]; tmp[x] = tables[x];
} }
free(tables); free(tables);
} }
tables = tmp; tables = tmp;
currtblsz = currtblsz*2 + 1; currtblsz = currtblsz*2 + 1;
}
} }
} if(tmp != NULL)
if(tmp != NULL){ {
char *catnm = NULL; char *catnm = NULL;
if(fullnames) if(fullnames)
{ {
if(tbl->db && strcmp(tbl->db,"skygw_virtual") != 0) if (tbl->db &&
strcmp(tbl->db,"skygw_virtual") != 0)
{ {
catnm = (char*)calloc(strlen(tbl->db) + strlen(tbl->table_name) + 2,sizeof(char)); catnm = (char*)calloc(strlen(tbl->db) +
strlen(tbl->table_name) +
2,
sizeof(char));
strcpy(catnm,tbl->db); strcpy(catnm,tbl->db);
strcat(catnm,"."); strcat(catnm,".");
strcat(catnm,tbl->table_name); strcat(catnm,tbl->table_name);
@ -1098,13 +1112,11 @@ char** skygw_get_table_names(GWBUF* querybuf,int* tblsize, bool fullnames)
{ {
tables[i++] = strdup(tbl->table_name); tables[i++] = strdup(tbl->table_name);
} }
tbl=tbl->next_local; tbl=tbl->next_local;
} }
} } /*< while (tbl) */
lex->current_select = lex->current_select->next_select_in_list(); lex->current_select = lex->current_select->next_select_in_list();
} } /*< while(lex->current_select) */
retblock: retblock:
*tblsize = i; *tblsize = i;
return tables; return tables;
@ -1119,35 +1131,49 @@ char* skygw_get_created_table_name(GWBUF* querybuf)
{ {
LEX* lex; LEX* lex;
if((lex = get_lex(querybuf)) == NULL) if(querybuf == NULL || (lex = get_lex(querybuf)) == NULL)
{ {
return NULL; return NULL;
} }
if (lex->create_last_non_select_table && if (lex->create_last_non_select_table &&
lex->create_last_non_select_table->table_name){ lex->create_last_non_select_table->table_name)
{
char* name = strdup(lex->create_last_non_select_table->table_name); char* name = strdup(lex->create_last_non_select_table->table_name);
return name; return name;
}else{ }
else
{
return NULL; return NULL;
} }
} }
/** /**
* Checks whether the query is a "real" query ie. SELECT,UPDATE,INSERT,DELETE or any variation of these. * Checks whether the query is a "real" query ie. SELECT,UPDATE,INSERT,DELETE or
* Queries that affect the underlying database are not considered as real queries and the queries that target * any variation of these. Queries that affect the underlying database are not
* specific row or variable data are regarded as the real queries. * considered as real queries and the queries that target specific row or
* variable data are regarded as the real queries.
*
* @param GWBUF to analyze * @param GWBUF to analyze
*
* @return true if the query is a real query, otherwise false * @return true if the query is a real query, otherwise false
*/ */
bool skygw_is_real_query(GWBUF* querybuf) bool skygw_is_real_query(GWBUF* querybuf)
{ {
LEX* lex = get_lex(querybuf); bool succp;
if(lex){ LEX* lex;
if (querybuf == NULL ||
(lex = get_lex(querybuf)) == NULL)
{
succp = false;
goto retblock;
}
switch(lex->sql_command) { switch(lex->sql_command) {
case SQLCOM_SELECT: case SQLCOM_SELECT:
return lex->all_selects_list->table_list.elements > 0; succp = lex->all_selects_list->table_list.elements > 0;
goto retblock;
break;
case SQLCOM_UPDATE: case SQLCOM_UPDATE:
case SQLCOM_INSERT: case SQLCOM_INSERT:
case SQLCOM_INSERT_SELECT: case SQLCOM_INSERT_SELECT:
@ -1157,12 +1183,16 @@ bool skygw_is_real_query(GWBUF* querybuf)
case SQLCOM_REPLACE_SELECT: case SQLCOM_REPLACE_SELECT:
case SQLCOM_PREPARE: case SQLCOM_PREPARE:
case SQLCOM_EXECUTE: case SQLCOM_EXECUTE:
return true; succp = true;
goto retblock;
break;
default: default:
return false; succp = false;
goto retblock;
break;
} }
} retblock:
return false; return succp;
} }
@ -1175,8 +1205,9 @@ bool is_drop_table_query(GWBUF* querybuf)
{ {
LEX* lex; LEX* lex;
return (lex = get_lex(querybuf)) != NULL && return (querybuf != NULL &&
lex->sql_command == SQLCOM_DROP_TABLE; (lex = get_lex(querybuf)) != NULL &&
lex->sql_command == SQLCOM_DROP_TABLE);
} }
/** /**
@ -1202,7 +1233,8 @@ char* skygw_get_canonical(
Item* item; Item* item;
char* querystr; char* querystr;
if (!GWBUF_IS_PARSED(querybuf)) if (querybuf == NULL ||
!GWBUF_IS_PARSED(querybuf))
{ {
querystr = NULL; querystr = NULL;
goto retblock; goto retblock;
@ -1339,7 +1371,11 @@ retblock:
void parsing_info_done( void parsing_info_done(
void* ptr) 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) if (pi->pi_handle != NULL)
{ {
@ -1359,6 +1395,7 @@ void parsing_info_done(
} }
free(pi); free(pi);
} }
}
/** /**
* Add plain text query string to parsing info. * Add plain text query string to parsing info.

View File

@ -83,11 +83,12 @@ typedef struct parsing_info_st {
skygw_query_type_t query_classifier_get_type(GWBUF* querybuf); 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); #if defined(NOT_USED)
char* skygw_query_classifier_get_stmtname(GWBUF* buf);
#endif
char* skygw_get_created_table_name(GWBUF* querybuf); char* skygw_get_created_table_name(GWBUF* querybuf);
bool is_drop_table_query(GWBUF* querybuf); bool is_drop_table_query(GWBUF* querybuf);
bool skygw_is_real_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); char* skygw_get_canonical(GWBUF* querybuf);
bool parse_query (GWBUF* querybuf); bool parse_query (GWBUF* querybuf);