MXS-1624 Implement qc_dup

Only for qc_sqlite.

After a second look qc_mysqlembedded will not support dupping
the statement information. Without additional changes, simply stashing
an info object away, parsing another new GWBUF, deleting that and
then using the stashed away info object will not work; the THD object
will be corrupted. As qc_mysqlembedded is _only_ used for verifying the
sqlite-based parser this is not important anyway.
This commit is contained in:
Johan Wikman 2018-07-04 12:39:13 +03:00
parent 4e168f36f7
commit 295bae5673
2 changed files with 40 additions and 29 deletions

View File

@ -131,7 +131,7 @@ static const char* map_function_name(NAME_MAPPING* function_name_mappings, const
#define MYSQL_COM_QUERY_HEADER_SIZE 5 /*< 3 bytes size, 1 sequence, 1 command */
#define MAX_QUERYBUF_SIZE 2048
typedef struct parsing_info_st
typedef struct parsing_info_st : public QC_STMT_INFO
{
#if defined(SS_DEBUG)
skygw_chk_t pi_chk_top;
@ -3488,13 +3488,6 @@ int32_t qc_mysql_set_sql_mode(qc_sql_mode_t sql_mode)
return rv;
}
QC_STMT_INFO* qc_mysql_dup(QC_STMT_INFO* info)
{
// TODO: Not implemented yet.
ss_dassert(!true);
return info;
}
/**
* EXPORTS
*/
@ -3528,7 +3521,7 @@ extern "C"
qc_mysql_get_server_version,
qc_mysql_get_sql_mode,
qc_mysql_set_sql_mode,
qc_mysql_dup,
nullptr,
};
static MXS_MODULE info =

View File

@ -236,12 +236,27 @@ extern void exposed_sqlite3Update(Parse* pParse,
/**
* Contains information about a particular query.
*/
class QcSqliteInfo
class QcSqliteInfo : public QC_STMT_INFO
{
QcSqliteInfo(const QcSqliteInfo&);
QcSqliteInfo& operator = (const QcSqliteInfo&);
public:
void inc_ref()
{
ss_dassert(m_refs > 0);
++m_refs;
}
void dec_ref()
{
ss_dassert(m_refs > 0);
if (--m_refs == 0)
{
delete this;
}
}
static QcSqliteInfo* create(uint32_t collect)
{
QcSqliteInfo* pInfo = new (std::nothrow) QcSqliteInfo(collect);
@ -276,20 +291,6 @@ public:
std::for_each(info.fields, info.fields + info.n_fields, finish_field_info);
}
~QcSqliteInfo()
{
std::for_each(m_table_names.begin(), m_table_names.end(), mxs_free);
std::for_each(m_table_fullnames.begin(), m_table_fullnames.end(), mxs_free);
free(m_zCreated_table_name);
std::for_each(m_database_names.begin(), m_database_names.end(), mxs_free);
free(m_zPrepare_name);
gwbuf_free(m_pPreparable_stmt);
std::for_each(m_field_infos.begin(), m_field_infos.end(), finish_field_info);
std::for_each(m_function_infos.begin(), m_function_infos.end(), finish_function_info);
// Data in m_function_field_usage is freed in finish_function_info().
}
bool is_valid() const
{
return m_status != QC_QUERY_INVALID;
@ -3002,7 +3003,8 @@ public:
private:
QcSqliteInfo(uint32_t cllct)
: m_status(QC_QUERY_INVALID)
: m_refs(1)
, m_status(QC_QUERY_INVALID)
, m_collect(cllct)
, m_collected(0)
, m_pQuery(NULL)
@ -3021,6 +3023,22 @@ private:
{
}
~QcSqliteInfo()
{
ss_dassert(m_refs == 0);
std::for_each(m_table_names.begin(), m_table_names.end(), mxs_free);
std::for_each(m_table_fullnames.begin(), m_table_fullnames.end(), mxs_free);
free(m_zCreated_table_name);
std::for_each(m_database_names.begin(), m_database_names.end(), mxs_free);
free(m_zPrepare_name);
gwbuf_free(m_pPreparable_stmt);
std::for_each(m_field_infos.begin(), m_field_infos.end(), finish_field_info);
std::for_each(m_function_infos.begin(), m_function_infos.end(), finish_function_info);
// Data in m_function_field_usage is freed in finish_function_info().
}
private:
bool should_collect(qc_collect_info_t collect) const
{
@ -3186,6 +3204,7 @@ private:
public:
// TODO: Make these private once everything's been updated.
int32_t m_refs; // The reference count.
qc_parse_result_t m_status; // The validity of the information in this structure.
uint32_t m_collect; // What information should be collected.
uint32_t m_collected; // What information has been collected.
@ -3281,7 +3300,7 @@ extern int maxscaleTranslateKeyword(int token);
static void buffer_object_free(void* pData)
{
QcSqliteInfo* pInfo = static_cast<QcSqliteInfo*>(pData);
delete pInfo;
pInfo->dec_ref();
}
static void enlarge_string_array(size_t n, size_t len, char*** ppzStrings, size_t* pCapacity)
@ -4496,7 +4515,7 @@ static int32_t qc_sqlite_thread_init(void)
this_thread.pInfo->m_pQuery = NULL;
this_thread.pInfo->m_nQuery = 0;
delete this_thread.pInfo;
this_thread.pInfo->dec_ref();
this_thread.pInfo = NULL;
this_thread.initialized = true;
@ -4961,8 +4980,7 @@ int32_t qc_sqlite_set_sql_mode(qc_sql_mode_t sql_mode)
QC_STMT_INFO* qc_sqlite_dup(QC_STMT_INFO* info)
{
// TODO: Not implemented yet.
ss_dassert(!true);
static_cast<QcSqliteInfo*>(info)->inc_ref();
return info;
}