diff --git a/include/maxscale/query_classifier.h b/include/maxscale/query_classifier.h index e804abcc5..9198c945f 100644 --- a/include/maxscale/query_classifier.h +++ b/include/maxscale/query_classifier.h @@ -29,6 +29,16 @@ typedef enum qc_init_kind QC_INIT_BOTH = 0x03 } qc_init_kind_t; +/** + * qc_sql_mode_t specifies what should be assumed of the statements + * that will be parsed. + */ +typedef enum qc_sql_mode +{ + QC_SQL_MODE_DEFAULT, /*< Assume the statements are MariaDB SQL. */ + QC_SQL_MODE_ORACLE /*< Assume the statements are PL/SQL. */ +} qc_sql_mode_t; + /** * @c qc_collect_info_t specifies what information should be collected during parsing. */ @@ -376,6 +386,24 @@ typedef struct query_classifier * exhaustion or equivalent. */ int32_t (*qc_get_preparable_stmt)(GWBUF* stmt, GWBUF** preparable_stmt); + + /** + * Gets the sql mode of the *calling* thread. + * + * @param sql_mode The mode. + * + * @return QC_RESULT_OK + */ + int32_t (*qc_get_sql_mode)(qc_sql_mode_t* sql_mode); + + /** + * Sets the sql mode for the *calling* thread. + * + * @param sql_mode The mode. + * + * @return QC_RESULT_OK if @sql_mode is valid, otherwise QC_RESULT_ERROR. + */ + int32_t (*qc_set_sql_mode)(qc_sql_mode_t sql_mode); } QUERY_CLASSIFIER; /** @@ -641,6 +669,13 @@ char* qc_get_prepare_name(GWBUF* stmt); */ GWBUF* qc_get_preparable_stmt(GWBUF* stmt); +/** + * Gets the sql mode of the *calling* thread. + * + * @return The mode. + */ +qc_sql_mode_t qc_get_sql_mode(); + /** * Returns the tables accessed by the statement. * @@ -739,6 +774,13 @@ static inline bool qc_query_is_type(uint32_t typemask, qc_query_type_t type) */ bool qc_query_has_clause(GWBUF* stmt); +/** + * Sets the sql mode for the *calling* thread. + * + * @param sql_mode The mode. + */ +void qc_set_sql_mode(qc_sql_mode_t sql_mode); + /** * Returns the string representation of a query type. * diff --git a/query_classifier/qc_dummy/qc_dummy.cc b/query_classifier/qc_dummy/qc_dummy.cc index 6b91fceba..72e9573c3 100644 --- a/query_classifier/qc_dummy/qc_dummy.cc +++ b/query_classifier/qc_dummy/qc_dummy.cc @@ -115,6 +115,16 @@ int32_t qc_dummy_get_preparable_stmt(GWBUF* stmt, GWBUF** preparable_stmt) return QC_RESULT_OK; } +int32_t qc_dummy_get_sql_mode(qc_sql_mode_t* sql_mode) +{ + return QC_RESULT_ERROR; +} + +int32_t qc_dummy_set_sql_mode(qc_sql_mode_t sql_mode) +{ + return QC_RESULT_ERROR; +} + extern "C" { MXS_MODULE* MXS_CREATE_MODULE() @@ -139,6 +149,8 @@ extern "C" qc_dummy_get_field_info, qc_dummy_get_function_info, qc_dummy_get_preparable_stmt, + qc_dummy_get_sql_mode, + qc_dummy_set_sql_mode, }; static MXS_MODULE info = diff --git a/query_classifier/qc_mysqlembedded/qc_mysqlembedded.cc b/query_classifier/qc_mysqlembedded/qc_mysqlembedded.cc index d5c42d585..55885052d 100644 --- a/query_classifier/qc_mysqlembedded/qc_mysqlembedded.cc +++ b/query_classifier/qc_mysqlembedded/qc_mysqlembedded.cc @@ -3020,6 +3020,16 @@ void qc_mysql_thread_end(void) mysql_thread_end(); } +int32_t qc_mysql_get_sql_mode(qc_sql_mode_t* sql_mode) +{ + return QC_RESULT_ERROR; +} + +int32_t qc_mysql_set_sql_mode(qc_sql_mode_t sql_mode) +{ + return QC_RESULT_ERROR; +} + /** * EXPORTS */ @@ -3049,6 +3059,8 @@ extern "C" qc_mysql_get_field_info, qc_mysql_get_function_info, qc_mysql_get_preparable_stmt, + qc_mysql_get_sql_mode, + qc_mysql_set_sql_mode, }; static MXS_MODULE info = diff --git a/query_classifier/qc_sqlite/qc_sqlite.c b/query_classifier/qc_sqlite/qc_sqlite.c index 857b4abb0..8b2dfb083 100644 --- a/query_classifier/qc_sqlite/qc_sqlite.c +++ b/query_classifier/qc_sqlite/qc_sqlite.c @@ -63,12 +63,6 @@ typedef enum qc_parse_as QC_PARSE_AS_103 // Parse as embedded lib does in 10.3 } qc_parse_as_t; -typedef enum qc_sql_mode -{ - QC_SQL_MODE_DEFAULT, - QC_SQL_MODE_ORACLE -} qc_sql_mode_t; - /** * Contains information about a particular query. */ @@ -3971,6 +3965,16 @@ int32_t qc_sqlite_get_preparable_stmt(GWBUF* stmt, GWBUF** preparable_stmt) return rv; } +int32_t qc_sqlite_get_sql_mode(qc_sql_mode_t* sql_mode) +{ + return QC_RESULT_ERROR; +} + +int32_t qc_sqlite_set_sql_mode(qc_sql_mode_t sql_mode) +{ + return QC_RESULT_ERROR; +} + /** * EXPORTS */ @@ -3997,6 +4001,8 @@ MXS_MODULE* MXS_CREATE_MODULE() qc_sqlite_get_field_info, qc_sqlite_get_function_info, qc_sqlite_get_preparable_stmt, + qc_sqlite_get_sql_mode, + qc_sqlite_set_sql_mode, }; static MXS_MODULE info = diff --git a/server/core/query_classifier.cc b/server/core/query_classifier.cc index d708f26b3..578923cb0 100644 --- a/server/core/query_classifier.cc +++ b/server/core/query_classifier.cc @@ -907,3 +907,25 @@ uint32_t qc_get_trx_type_mask(GWBUF* stmt) { return qc_get_trx_type_mask_using(stmt, qc_trx_parse_using); } + +qc_sql_mode_t qc_get_sql_mode() +{ + QC_TRACE(); + ss_dassert(classifier); + + qc_sql_mode_t sql_mode; + + ss_debug(int32_t rv =) classifier->qc_get_sql_mode(&sql_mode); + ss_dassert(rv == QC_RESULT_OK); + + return sql_mode; +} + +void qc_set_sql_mode(qc_sql_mode_t sql_mode) +{ + QC_TRACE(); + ss_dassert(classifier); + + ss_debug(int32_t rv =) classifier->qc_set_sql_mode(sql_mode); + ss_dassert(rv == QC_RESULT_OK); +}