From c29e8b2b9e575c8d52475b44e334dd2cf07fc4db Mon Sep 17 00:00:00 2001 From: Johan Wikman Date: Thu, 3 Aug 2017 11:05:42 +0300 Subject: [PATCH] MXS-1340 Move update_field_info to QcSqliteInfo --- query_classifier/qc_sqlite/qc_sqlite.cc | 213 ++++++++++++------------ 1 file changed, 103 insertions(+), 110 deletions(-) diff --git a/query_classifier/qc_sqlite/qc_sqlite.cc b/query_classifier/qc_sqlite/qc_sqlite.cc index 42f908ace..76bc3564b 100644 --- a/query_classifier/qc_sqlite/qc_sqlite.cc +++ b/query_classifier/qc_sqlite/qc_sqlite.cc @@ -164,12 +164,6 @@ static bool parse_query(GWBUF* query, uint32_t collect); static void parse_query_string(const char* query, int len); static bool query_is_parsed(GWBUF* query, uint32_t collect); static bool should_exclude(const char* zName, const ExprList* pExclude); -static void update_field_info(QcSqliteInfo* info, - const char* database, - const char* table, - const char* column, - uint32_t usage, - const ExprList* pExclude); static void update_field_infos_from_expr(QcSqliteInfo* info, const Expr* pExpr, uint32_t usage, @@ -460,6 +454,107 @@ public: } // PUBLIC for now at least. + void update_field_info(const char* database, + const char* table, + const char* column, + uint32_t usage, + const ExprList* pExclude) + { + ss_dassert(column); + + if (is_sequence_related_field(this, database, table, column)) + { + m_type_mask |= QUERY_TYPE_WRITE; + return; + } + + if (!(m_collect & QC_COLLECT_FIELDS) || (m_collected & QC_COLLECT_FIELDS)) + { + // If field information should not be collected, or if field information + // has already been collected, we just return. + return; + } + + QC_FIELD_INFO item = { (char*)database, (char*)table, (char*)column, usage }; + + size_t i; + for (i = 0; i < m_field_infos_len; ++i) + { + QC_FIELD_INFO* field_info = m_pField_infos + i; + + if (strcasecmp(item.column, field_info->column) == 0) + { + if (!item.table && !field_info->table) + { + ss_dassert(!item.database && !field_info->database); + break; + } + else if (item.table && field_info->table && (strcmp(item.table, field_info->table) == 0)) + { + if (!item.database && !field_info->database) + { + break; + } + else if (item.database && + field_info->database && + (strcmp(item.database, field_info->database) == 0)) + { + break; + } + } + } + } + + QC_FIELD_INFO* field_infos = NULL; + + if (i == m_field_infos_len) // If true, the field was not present already. + { + // If only a column is specified, but not a table or database and we + // have a list of expressions that should be excluded, we check if the column + // value is present in that list. This is in order to exclude the second "d" in + // a statement like "select a as d from x where d = 2". + if (!(column && !table && !database && pExclude && should_exclude(column, pExclude))) + { + if (m_field_infos_len < m_field_infos_capacity) + { + field_infos = m_pField_infos; + } + else + { + size_t capacity = m_field_infos_capacity ? 2 * m_field_infos_capacity : 8; + field_infos = (QC_FIELD_INFO*)MXS_REALLOC(m_pField_infos, + capacity * sizeof(QC_FIELD_INFO)); + + if (field_infos) + { + m_pField_infos = field_infos; + m_field_infos_capacity = capacity; + } + } + } + } + else + { + m_pField_infos[i].usage |= usage; + } + + // If field_infos is NULL, then the field was found and has already been noted. + if (field_infos) + { + item.database = item.database ? MXS_STRDUP(item.database) : NULL; + item.table = item.table ? MXS_STRDUP(item.table) : NULL; + ss_dassert(item.column); + item.column = MXS_STRDUP(item.column); + + // We are happy if we at least could dup the column. + + if (item.column) + { + field_infos[m_field_infos_len++] = item; + } + } + } + void update_names(const char* zDatabase, const char* zTable, const char* zAlias) { ss_dassert(zTable); @@ -1235,108 +1330,6 @@ static bool should_exclude(const char* zName, const ExprList* pExclude) return i != pExclude->nExpr; } -static void update_field_info(QcSqliteInfo* info, - const char* database, - const char* table, - const char* column, - uint32_t usage, - const ExprList* pExclude) -{ - ss_dassert(column); - - if (is_sequence_related_field(info, database, table, column)) - { - info->m_type_mask |= QUERY_TYPE_WRITE; - return; - } - - if (!(info->m_collect & QC_COLLECT_FIELDS) || (info->m_collected & QC_COLLECT_FIELDS)) - { - // If field information should not be collected, or if field information - // has already been collected, we just return. - return; - } - - QC_FIELD_INFO item = { (char*)database, (char*)table, (char*)column, usage }; - - size_t i; - for (i = 0; i < info->m_field_infos_len; ++i) - { - QC_FIELD_INFO* field_info = info->m_pField_infos + i; - - if (strcasecmp(item.column, field_info->column) == 0) - { - if (!item.table && !field_info->table) - { - ss_dassert(!item.database && !field_info->database); - break; - } - else if (item.table && field_info->table && (strcmp(item.table, field_info->table) == 0)) - { - if (!item.database && !field_info->database) - { - break; - } - else if (item.database && - field_info->database && - (strcmp(item.database, field_info->database) == 0)) - { - break; - } - } - } - } - - QC_FIELD_INFO* field_infos = NULL; - - if (i == info->m_field_infos_len) // If true, the field was not present already. - { - // If only a column is specified, but not a table or database and we - // have a list of expressions that should be excluded, we check if the column - // value is present in that list. This is in order to exclude the second "d" in - // a statement like "select a as d from x where d = 2". - if (!(column && !table && !database && pExclude && should_exclude(column, pExclude))) - { - if (info->m_field_infos_len < info->m_field_infos_capacity) - { - field_infos = info->m_pField_infos; - } - else - { - size_t capacity = info->m_field_infos_capacity ? 2 * info->m_field_infos_capacity : 8; - field_infos = (QC_FIELD_INFO*)MXS_REALLOC(info->m_pField_infos, - capacity * sizeof(QC_FIELD_INFO)); - - if (field_infos) - { - info->m_pField_infos = field_infos; - info->m_field_infos_capacity = capacity; - } - } - } - } - else - { - info->m_pField_infos[i].usage |= usage; - } - - // If field_infos is NULL, then the field was found and has already been noted. - if (field_infos) - { - item.database = item.database ? MXS_STRDUP(item.database) : NULL; - item.table = item.table ? MXS_STRDUP(item.table) : NULL; - ss_dassert(item.column); - item.column = MXS_STRDUP(item.column); - - // We are happy if we at least could dup the column. - - if (item.column) - { - field_infos[info->m_field_infos_len++] = item; - } - } -} - static void update_function_info(QcSqliteInfo* info, const char* name, uint32_t usage) @@ -1476,7 +1469,7 @@ static void update_field_infos_from_expr(QcSqliteInfo* info, if (should_update) { - update_field_info(info, item.database, item.table, item.column, usage, pExclude); + info->update_field_info(item.database, item.table, item.column, usage, pExclude); } } } @@ -1823,7 +1816,7 @@ static void update_field_infos_from_idlist(QcSqliteInfo* info, { IdList::IdList_item* pItem = &pIds->a[i]; - update_field_info(info, NULL, NULL, pItem->zName, usage, pExclude); + info->update_field_info(NULL, NULL, pItem->zName, usage, pExclude); } }