Query classifier can keep parse tree after the function that created it returns. Parse tree can then be queried from outside. Added skygw_query_classifier_get_stmtname which returns the name of statement, and skygw_query_classifier_free which frees mysql handle, parse tree and thread context (thd).
This commit is contained in:
@ -101,7 +101,8 @@ static int is_autocommit_stmt(
|
|||||||
*/
|
*/
|
||||||
skygw_query_type_t skygw_query_classifier_get_type(
|
skygw_query_type_t skygw_query_classifier_get_type(
|
||||||
const char* query,
|
const char* query,
|
||||||
unsigned long client_flags)
|
unsigned long client_flags,
|
||||||
|
MYSQL** p_mysql)
|
||||||
{
|
{
|
||||||
MYSQL* mysql;
|
MYSQL* mysql;
|
||||||
char* query_str;
|
char* query_str;
|
||||||
@ -129,9 +130,13 @@ skygw_query_type_t skygw_query_classifier_get_type(
|
|||||||
mysql_error(mysql))));
|
mysql_error(mysql))));
|
||||||
|
|
||||||
mysql_library_end();
|
mysql_library_end();
|
||||||
goto return_without_server;
|
goto return_qtype;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (p_mysql != NULL)
|
||||||
|
{
|
||||||
|
*p_mysql = mysql;
|
||||||
|
}
|
||||||
/** Set methods and authentication to mysql */
|
/** Set methods and authentication to mysql */
|
||||||
mysql_options(mysql, MYSQL_READ_DEFAULT_GROUP, "libmysqld_skygw");
|
mysql_options(mysql, MYSQL_READ_DEFAULT_GROUP, "libmysqld_skygw");
|
||||||
mysql_options(mysql, MYSQL_OPT_USE_EMBEDDED_CONNECTION, NULL);
|
mysql_options(mysql, MYSQL_OPT_USE_EMBEDDED_CONNECTION, NULL);
|
||||||
@ -143,25 +148,39 @@ skygw_query_type_t skygw_query_classifier_get_type(
|
|||||||
/** Get one or create new THD object to be use in parsing */
|
/** Get one or create new THD object to be use in parsing */
|
||||||
thd = get_or_create_thd_for_parsing(mysql, query_str);
|
thd = get_or_create_thd_for_parsing(mysql, query_str);
|
||||||
|
|
||||||
if (thd == NULL) {
|
if (thd == NULL)
|
||||||
goto return_with_server_handle;
|
{
|
||||||
|
skygw_query_classifier_free(mysql);
|
||||||
}
|
}
|
||||||
/** Create parse_tree inside thd */
|
/** Create parse_tree inside thd */
|
||||||
failp = create_parse_tree(thd);
|
failp = create_parse_tree(thd);
|
||||||
|
|
||||||
if (failp) {
|
if (failp)
|
||||||
goto return_with_thd;
|
{
|
||||||
|
skygw_query_classifier_free(mysql);
|
||||||
|
*p_mysql = NULL;
|
||||||
}
|
}
|
||||||
qtype = resolve_query_type(thd);
|
qtype = resolve_query_type(thd);
|
||||||
|
|
||||||
return_with_thd:
|
if (p_mysql == NULL)
|
||||||
|
{
|
||||||
|
skygw_query_classifier_free(mysql);
|
||||||
|
}
|
||||||
|
return_qtype:
|
||||||
|
return qtype;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void skygw_query_classifier_free(
|
||||||
|
MYSQL* mysql)
|
||||||
|
{
|
||||||
|
if (mysql->thd != NULL)
|
||||||
|
{
|
||||||
(*mysql->methods->free_embedded_thd)(mysql);
|
(*mysql->methods->free_embedded_thd)(mysql);
|
||||||
mysql->thd = 0;
|
mysql->thd = NULL;
|
||||||
return_with_server_handle:
|
}
|
||||||
mysql_close(mysql);
|
mysql_close(mysql);
|
||||||
mysql_thread_end();
|
mysql_thread_end();
|
||||||
return_without_server:
|
|
||||||
return qtype;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -518,6 +537,11 @@ static skygw_query_type_t resolve_query_type(
|
|||||||
goto return_qtype;
|
goto return_qtype;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case SQLCOM_PREPARE:
|
||||||
|
type |= QUERY_TYPE_PREPARE_NAMED_STMT;
|
||||||
|
goto return_qtype;
|
||||||
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -783,3 +807,11 @@ static int is_autocommit_stmt(
|
|||||||
return_rc:
|
return_rc:
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
char* skygw_query_classifier_get_stmtname(
|
||||||
|
MYSQL* mysql)
|
||||||
|
{
|
||||||
|
return ((THD *)(mysql->thd))->lex->prepared_stmt_name.str;
|
||||||
|
|
||||||
|
}
|
||||||
|
|||||||
@ -19,6 +19,7 @@ Copyright SkySQL Ab
|
|||||||
|
|
||||||
/** getpid */
|
/** getpid */
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
|
#include <mysql.h>
|
||||||
#include "../utils/skygw_utils.h"
|
#include "../utils/skygw_utils.h"
|
||||||
|
|
||||||
EXTERN_C_BLOCK_BEGIN
|
EXTERN_C_BLOCK_BEGIN
|
||||||
@ -29,25 +30,36 @@ EXTERN_C_BLOCK_BEGIN
|
|||||||
* is modified
|
* is modified
|
||||||
*/
|
*/
|
||||||
typedef enum {
|
typedef enum {
|
||||||
QUERY_TYPE_UNKNOWN = 0x000, /*< Initial value, can't be tested bitwisely */
|
QUERY_TYPE_UNKNOWN = 0x0000, /*< Initial value, can't be tested bitwisely */
|
||||||
QUERY_TYPE_LOCAL_READ = 0x001, /*< Read non-database data, execute in MaxScale */
|
QUERY_TYPE_LOCAL_READ = 0x0001, /*< Read non-database data, execute in MaxScale */
|
||||||
QUERY_TYPE_READ = 0x002, /*< No updates */
|
QUERY_TYPE_READ = 0x0002, /*< No updates */
|
||||||
QUERY_TYPE_WRITE = 0x004, /*< Master data will be modified */
|
QUERY_TYPE_WRITE = 0x0004, /*< Master data will be modified */
|
||||||
QUERY_TYPE_SESSION_WRITE = 0x008, /*< Session data will be modified */
|
QUERY_TYPE_SESSION_WRITE = 0x0008, /*< Session data will be modified */
|
||||||
QUERY_TYPE_GLOBAL_WRITE = 0x010, /*< Global system variable modification */
|
QUERY_TYPE_GLOBAL_WRITE = 0x0010, /*< Global system variable modification */
|
||||||
QUERY_TYPE_BEGIN_TRX = 0x020, /*< BEGIN or START TRANSACTION */
|
QUERY_TYPE_BEGIN_TRX = 0x0020, /*< BEGIN or START TRANSACTION */
|
||||||
QUERY_TYPE_ENABLE_AUTOCOMMIT = 0x040,/*< SET autocommit=1 */
|
QUERY_TYPE_ENABLE_AUTOCOMMIT = 0x0040, /*< SET autocommit=1 */
|
||||||
QUERY_TYPE_DISABLE_AUTOCOMMIT = 0x080,/*< SET autocommit=0 */
|
QUERY_TYPE_DISABLE_AUTOCOMMIT = 0x0080, /*< SET autocommit=0 */
|
||||||
QUERY_TYPE_ROLLBACK = 0x100, /*< ROLLBACK */
|
QUERY_TYPE_ROLLBACK = 0x0100, /*< ROLLBACK */
|
||||||
QUERY_TYPE_COMMIT = 0x200 /*< COMMIT */
|
QUERY_TYPE_COMMIT = 0x0200, /*< COMMIT */
|
||||||
|
QUERY_TYPE_PREPARE_NAMED_STMT = 0x0400, /*< Prepared stmt with name from user */
|
||||||
|
QUERY_TYPE_PREPARE_STMT = 0x0800, /*< Prepared stmt with id provided by server */
|
||||||
|
QUERY_TYPE_EXEC_STMT = 0x1000 /*< Execute prepared statement */
|
||||||
} skygw_query_type_t;
|
} skygw_query_type_t;
|
||||||
|
|
||||||
#define QUERY_IS_TYPE(mask,type) ((mask & type) == type)
|
#define QUERY_IS_TYPE(mask,type) ((mask & type) == type)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create THD and use it for creating parse tree. Examine parse tree and
|
||||||
|
* classify the query.
|
||||||
|
*/
|
||||||
skygw_query_type_t skygw_query_classifier_get_type(
|
skygw_query_type_t skygw_query_classifier_get_type(
|
||||||
const char* query_str,
|
const char* query_str,
|
||||||
unsigned long client_flags);
|
unsigned long client_flags,
|
||||||
|
MYSQL** mysql);
|
||||||
|
|
||||||
|
/** Free THD context and close MYSQL */
|
||||||
|
void skygw_query_classifier_free(MYSQL* mysql);
|
||||||
|
char* skygw_query_classifier_get_stmtname(MYSQL* mysql);
|
||||||
|
|
||||||
EXTERN_C_BLOCK_END
|
EXTERN_C_BLOCK_END
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user