From e4f0598743e38b0a44eae85619ff31b272aa29d5 Mon Sep 17 00:00:00 2001 From: Johan Wikman Date: Mon, 31 Jul 2017 12:30:17 +0300 Subject: [PATCH] Convert qc_sqlite.c to C++ MXS-1307 requries some modifications in the query classifier and making those changes is easier if STL collections are available. --- query_classifier/qc_sqlite/CMakeLists.txt | 2 +- .../qc_sqlite/{qc_sqlite.c => qc_sqlite.cc} | 134 +++++++++++++----- 2 files changed, 103 insertions(+), 33 deletions(-) rename query_classifier/qc_sqlite/{qc_sqlite.c => qc_sqlite.cc} (95%) diff --git a/query_classifier/qc_sqlite/CMakeLists.txt b/query_classifier/qc_sqlite/CMakeLists.txt index d09745a1b..d0092d981 100644 --- a/query_classifier/qc_sqlite/CMakeLists.txt +++ b/query_classifier/qc_sqlite/CMakeLists.txt @@ -19,7 +19,7 @@ include_directories(${MARIADB_CONNECTOR_INCLUDE_DIR}) # GCC thinks there is an array-bounds error in sqlite code. set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wno-error=array-bounds") -add_library(qc_sqlite SHARED qc_sqlite.c qc_sqlite3.c builtin_functions.c) +add_library(qc_sqlite SHARED qc_sqlite.cc qc_sqlite3.c builtin_functions.c) add_dependencies(qc_sqlite maxscale_sqlite) add_definitions(-DMAXSCALE -DSQLITE_THREADSAFE=0 -DSQLITE_ENABLE_UPDATE_DELETE_LIMIT -DSQLITE_OMIT_ATTACH -DSQLITE_OMIT_REINDEX -DSQLITE_OMIT_AUTOVACUUM -DSQLITE_OMIT_PRAGMA) diff --git a/query_classifier/qc_sqlite/qc_sqlite.c b/query_classifier/qc_sqlite/qc_sqlite.cc similarity index 95% rename from query_classifier/qc_sqlite/qc_sqlite.c rename to query_classifier/qc_sqlite/qc_sqlite.cc index 06ddeffd9..1f9222566 100644 --- a/query_classifier/qc_sqlite/qc_sqlite.c +++ b/query_classifier/qc_sqlite/qc_sqlite.cc @@ -230,6 +230,10 @@ static void update_names(QC_SQLITE_INFO* info, const char* zDatabase, const char static void update_names_from_srclist(QC_SQLITE_INFO* info, const SrcList* pSrc); // Defined in parse.y + +extern "C" +{ + extern void exposed_sqlite3ExprDelete(sqlite3 *db, Expr *pExpr); extern void exposed_sqlite3ExprListDelete(sqlite3 *db, ExprList *pList); extern void exposed_sqlite3IdListDelete(sqlite3 *db, IdList *pList); @@ -259,9 +263,66 @@ extern void exposed_sqlite3StartTable(Parse *pParse, /* Parser context */ int isView, /* True if this is a VIEW */ int isVirtual, /* True if this is a VIRTUAL table */ int noErr); /* Do nothing if table already exists */ + +} + +extern "C" +{ + +extern void mxs_sqlite3AlterFinishAddColumn(Parse *, Token *); +extern void mxs_sqlite3AlterBeginAddColumn(Parse *, SrcList *); +extern void mxs_sqlite3Analyze(Parse *, SrcList *); +extern void mxs_sqlite3BeginTransaction(Parse*, int token, int type); +extern void mxs_sqlite3CommitTransaction(Parse*); +extern void mxs_sqlite3CreateIndex(Parse*,Token*,Token*,SrcList*,ExprList*,int,Token*, + Expr*, int, int); +extern void mxs_sqlite3BeginTrigger(Parse*, Token*,Token*,int,int,IdList*,SrcList*, + Expr*,int, int); +extern void mxs_sqlite3FinishTrigger(Parse*, TriggerStep*, Token*); +extern void mxs_sqlite3CreateView(Parse*,Token*,Token*,Token*,ExprList*,Select*,int,int); +extern void mxs_sqlite3DeleteFrom(Parse* pParse, SrcList* pTabList, Expr* pWhere, SrcList* pUsing); +extern void mxs_sqlite3DropIndex(Parse*, SrcList*, SrcList*,int); +extern void mxs_sqlite3DropTable(Parse*, SrcList*, int, int, int); +extern void mxs_sqlite3EndTable(Parse*, Token*, Token*, u8, Select*, SrcList*); +extern void mxs_sqlite3Insert(Parse*, SrcList*, Select*, IdList*, int,ExprList*); +extern void mxs_sqlite3RollbackTransaction(Parse*); +extern void mxs_sqlite3Savepoint(Parse *pParse, int op, Token *pName); +extern int mxs_sqlite3Select(Parse*, Select*, SelectDest*); +extern void mxs_sqlite3StartTable(Parse*,Token*,Token*,int,int,int,int); +extern void mxs_sqlite3Update(Parse*, SrcList*, ExprList*, Expr*, int); + extern void maxscaleCollectInfoFromSelect(Parse*, Select*, int); -extern void maxscale_update_function_info(const char* name, uint32_t usage); +extern void maxscaleAlterTable(Parse*, mxs_alter_t command, SrcList*, Token*); +extern void maxscaleCall(Parse*, SrcList* pName, ExprList* pExprList); +extern void maxscaleCheckTable(Parse*, SrcList* pTables); +extern void maxscaleCreateSequence(Parse*, Token* pDatabase, Token* pTable); +extern void maxscaleDeclare(Parse* pParse); +extern void maxscaleDeallocate(Parse*, Token* pName); +extern void maxscaleDo(Parse*, ExprList* pEList); +extern void maxscaleDrop(Parse*, int what, Token* pDatabase, Token* pName); +extern void maxscaleExecute(Parse*, Token* pName, int type_mask); +extern void maxscaleExecuteImmediate(Parse*, Token* pName, ExprSpan* pExprSpan, int type_mask); +extern void maxscaleExplain(Parse*, Token* pNext); +extern void maxscaleFlush(Parse*, Token* pWhat); +extern void maxscaleHandler(Parse*, mxs_handler_t, SrcList* pFullName, Token* pName); +extern void maxscaleLoadData(Parse*, SrcList* pFullName); +extern void maxscaleLock(Parse*, mxs_lock_t, SrcList*); +extern void maxscalePrepare(Parse*, Token* pName, Expr* pStmt); +extern void maxscalePrivileges(Parse*, int kind); +extern void maxscaleRenameTable(Parse*, SrcList* pTables); +extern void maxscaleSet(Parse*, int scope, mxs_set_t kind, ExprList*); +extern void maxscaleShow(Parse*, MxsShow* pShow); +extern void maxscaleTruncate(Parse*, Token* pDatabase, Token* pName); +extern void maxscaleUse(Parse*, Token*); + +extern void maxscale_update_function_info(const char* name, unsigned usage); + +extern void maxscaleComment(); +extern int maxscaleKeyword(int token); +extern int maxscaleTranslateKeyword(int token); + +} /** * Used for freeing a QC_SQLITE_INFO object added to a GWBUF. @@ -328,7 +389,7 @@ static void free_field_infos(QC_FIELD_INFO* infos, size_t n_infos) { if (infos) { - for (int i = 0; i < n_infos; ++i) + for (size_t i = 0; i < n_infos; ++i) { MXS_FREE(infos[i].database); MXS_FREE(infos[i].table); @@ -343,7 +404,7 @@ static void free_function_infos(QC_FUNCTION_INFO* infos, size_t n_infos) { if (infos) { - for (int i = 0; i < n_infos; ++i) + for (size_t i = 0; i < n_infos; ++i) { MXS_FREE(infos[i].name); } @@ -383,7 +444,7 @@ static QC_SQLITE_INFO* get_query_info(GWBUF* query, uint32_t collect) static QC_SQLITE_INFO* info_alloc(uint32_t collect) { - QC_SQLITE_INFO* info = MXS_MALLOC(sizeof(*info)); + QC_SQLITE_INFO* info = (QC_SQLITE_INFO*)MXS_MALLOC(sizeof(*info)); MXS_ABORT_IF_NULL(info); info_init(info, collect); @@ -745,9 +806,9 @@ static void log_invalid_data(GWBUF* query, const char* message) if (modutil_extract_SQL(query, &sql, &length)) { - if (length > GWBUF_LENGTH(query) - MYSQL_HEADER_LEN - 1) + if (length > (int)GWBUF_LENGTH(query) - MYSQL_HEADER_LEN - 1) { - length = GWBUF_LENGTH(query) - MYSQL_HEADER_LEN - 1; + length = (int)GWBUF_LENGTH(query) - MYSQL_HEADER_LEN - 1; } MXS_INFO("Parsing the query failed, %s: %*s", message, length, sql); @@ -788,7 +849,7 @@ static bool should_exclude(const char* zName, const ExprList* pExclude) int i; for (i = 0; i < pExclude->nExpr; ++i) { - const struct ExprList_item* item = &pExclude->a[i]; + const struct ExprList::ExprList_item* item = &pExclude->a[i]; // zName will contain a possible alias name. If the alias name // is referred to in e.g. in a having, it need to be excluded @@ -852,7 +913,7 @@ static void update_field_info(QC_SQLITE_INFO* info, QC_FIELD_INFO item = { (char*)database, (char*)table, (char*)column, usage }; - int i; + size_t i; for (i = 0; i < info->field_infos_len; ++i) { QC_FIELD_INFO* field_info = info->field_infos + i; @@ -897,7 +958,8 @@ static void update_field_info(QC_SQLITE_INFO* info, else { size_t capacity = info->field_infos_capacity ? 2 * info->field_infos_capacity : 8; - field_infos = MXS_REALLOC(info->field_infos, capacity * sizeof(QC_FIELD_INFO)); + field_infos = (QC_FIELD_INFO*)MXS_REALLOC(info->field_infos, + capacity * sizeof(QC_FIELD_INFO)); if (field_infos) { @@ -946,7 +1008,7 @@ static void update_function_info(QC_SQLITE_INFO* info, QC_FUNCTION_INFO item = { (char*)name, usage }; - int i; + size_t i; for (i = 0; i < info->function_infos_len; ++i) { QC_FUNCTION_INFO* function_info = info->function_infos + i; @@ -968,7 +1030,8 @@ static void update_function_info(QC_SQLITE_INFO* info, else { size_t capacity = info->function_infos_capacity ? 2 * info->function_infos_capacity : 8; - function_infos = MXS_REALLOC(info->function_infos, capacity * sizeof(QC_FUNCTION_INFO)); + function_infos = (QC_FUNCTION_INFO*)MXS_REALLOC(info->function_infos, + capacity * sizeof(QC_FUNCTION_INFO)); if (function_infos) { @@ -1011,7 +1074,7 @@ static void update_field_infos_from_expr(QC_SQLITE_INFO* info, if (pExpr->op == TK_ASTERISK) { - item.column = "*"; + item.column = (char*)"*"; } else if (pExpr->op == TK_ID) { @@ -1031,7 +1094,7 @@ static void update_field_infos_from_expr(QC_SQLITE_INFO* info, } else { - item.column = "*"; + item.column = (char*)"*"; } } else if (pExpr->pLeft->op == TK_ID && @@ -1048,7 +1111,7 @@ static void update_field_infos_from_expr(QC_SQLITE_INFO* info, } else { - item.column = "*"; + item.column = (char*)"*"; } } } @@ -1077,7 +1140,7 @@ static void update_field_infos_from_with(QC_SQLITE_INFO* info, { for (int i = 0; i < pWith->nCte; ++i) { - const struct Cte* pCte = &pWith->a[i]; + const struct With::Cte* pCte = &pWith->a[i]; if (pCte->pSelect) { @@ -1399,7 +1462,7 @@ static void update_field_infos_from_exprlist(QC_SQLITE_INFO* info, { for (int i = 0; i < pEList->nExpr; ++i) { - struct ExprList_item* pItem = &pEList->a[i]; + struct ExprList::ExprList_item* pItem = &pEList->a[i]; update_field_infos(info, 0, pItem->pExpr, usage, QC_TOKEN_MIDDLE, pExclude); } @@ -1412,7 +1475,7 @@ static void update_field_infos_from_idlist(QC_SQLITE_INFO* info, { for (int i = 0; i < pIds->nId; ++i) { - struct IdList_item* pItem = &pIds->a[i]; + struct IdList::IdList_item* pItem = &pIds->a[i]; update_field_info(info, NULL, NULL, pItem->zName, usage, pExclude); } @@ -1523,7 +1586,7 @@ static void update_names(QC_SQLITE_INFO* info, const char* zDatabase, const char if (zDatabase) { - zCopy = MXS_MALLOC(strlen(zDatabase) + 1 + strlen(zTable) + 1); + zCopy = (char*)MXS_MALLOC(strlen(zDatabase) + 1 + strlen(zTable) + 1); MXS_ABORT_IF_NULL(zCopy); strcpy(zCopy, zDatabase); @@ -1650,9 +1713,9 @@ void mxs_sqlite3BeginTrigger(Parse *pParse, /* The parse context of the CRE if (pTableName) { - for (int i = 0; i < pTableName->nAlloc; ++i) + for (size_t i = 0; i < pTableName->nAlloc; ++i) { - struct SrcList_item* pItem = &pTableName->a[i]; + const struct SrcList::SrcList_item* pItem = &pTableName->a[i]; if (pItem->zName) { @@ -1778,7 +1841,7 @@ void mxs_sqlite3DeleteFrom(Parse* pParse, SrcList* pTabList, Expr* pWhere, SrcLi // table and database names. for (int i = 0; i < pUsing->nSrc; ++i) { - struct SrcList_item* pItem = &pUsing->a[i]; + const struct SrcList::SrcList_item* pItem = &pUsing->a[i]; update_names(info, pItem->zDatabase, pItem->zName); } @@ -1787,14 +1850,14 @@ void mxs_sqlite3DeleteFrom(Parse* pParse, SrcList* pTabList, Expr* pWhere, SrcLi // names from the using declaration. for (int i = 0; i < pTabList->nSrc; ++i) { - const struct SrcList_item* pTable = &pTabList->a[i]; + const struct SrcList::SrcList_item* pTable = &pTabList->a[i]; ss_dassert(pTable->zName); int j = 0; bool isSame = false; do { - struct SrcList_item* pItem = &pUsing->a[j++]; + SrcList::SrcList_item* pItem = &pUsing->a[j++]; if (strcasecmp(pTable->zName, pItem->zName) == 0) { @@ -2093,7 +2156,7 @@ void mxs_sqlite3Update(Parse* pParse, SrcList* pTabList, ExprList* pChanges, Exp { for (int i = 0; i < pChanges->nExpr; ++i) { - struct ExprList_item* pItem = &pChanges->a[i]; + ExprList::ExprList_item* pItem = &pChanges->a[i]; update_field_infos(info, 0, pItem->pExpr, QC_USED_IN_SET, QC_TOKEN_MIDDLE, NULL); } @@ -2281,7 +2344,7 @@ void maxscaleDeallocate(Parse* pParse, Token* pName) // this information already. if (!info->prepare_name) { - info->prepare_name = MXS_MALLOC(pName->n + 1); + info->prepare_name = (char*)MXS_MALLOC(pName->n + 1); if (info->prepare_name) { memcpy(info->prepare_name, pName->z, pName->n); @@ -2355,7 +2418,7 @@ void maxscaleExecute(Parse* pParse, Token* pName, int type_mask) // this information already. if (!info->prepare_name) { - info->prepare_name = MXS_MALLOC(pName->n + 1); + info->prepare_name = (char*)MXS_MALLOC(pName->n + 1); if (info->prepare_name) { memcpy(info->prepare_name, pName->z, pName->n); @@ -2501,7 +2564,7 @@ void maxscaleHandler(Parse* pParse, mxs_handler_t type, SrcList* pFullName, Toke info->type_mask = QUERY_TYPE_WRITE; ss_dassert(pFullName->nSrc == 1); - const struct SrcList_item* pItem = &pFullName->a[0]; + const struct SrcList::SrcList_item* pItem = &pFullName->a[0]; update_names(info, pItem->zDatabase, pItem->zName); } @@ -2689,7 +2752,8 @@ int maxscaleKeyword(int token) break; case TK_HANDLER: - info->status = QUERY_TYPE_WRITE; + info->status = QC_QUERY_TOKENIZED; + info->type_mask = QUERY_TYPE_WRITE; break; case TK_INSERT: @@ -2849,7 +2913,7 @@ void maxscaleRenameTable(Parse* pParse, SrcList* pTables) for (int i = 0; i < pTables->nSrc; ++i) { - const struct SrcList_item* pItem = &pTables->a[i]; + const struct SrcList::SrcList_item* pItem = &pTables->a[i]; ss_dassert(pItem->zName); ss_dassert(pItem->zAlias); @@ -2933,7 +2997,7 @@ void maxscalePrepare(Parse* pParse, Token* pName, Expr* pStmt) // this information already. if (!info->prepare_name) { - info->prepare_name = MXS_MALLOC(pName->n + 1); + info->prepare_name = (char*)MXS_MALLOC(pName->n + 1); if (info->prepare_name) { memcpy(info->prepare_name, pName->z, pName->n); @@ -3052,7 +3116,7 @@ void maxscaleSet(Parse* pParse, int scope, mxs_set_t kind, ExprList* pList) { for (int i = 0; i < pList->nExpr; ++i) { - const struct ExprList_item* pItem = &pList->a[i]; + const struct ExprList::ExprList_item* pItem = &pList->a[i]; switch (pItem->pExpr->op) { @@ -3398,7 +3462,7 @@ static int32_t qc_sqlite_setup(qc_sql_mode_t sql_mode, const char* cargs) if ((*end == 0) && (l >= QC_LOG_NOTHING) && (l <= QC_LOG_NON_TOKENIZED)) { - log_level = l; + log_level = static_cast(l); } else { @@ -4064,6 +4128,9 @@ int32_t qc_sqlite_set_sql_mode(qc_sql_mode_t sql_mode) * EXPORTS */ +extern "C" +{ + MXS_MODULE* MXS_CREATE_MODULE() { static QUERY_CLASSIFIER qc = @@ -4112,3 +4179,6 @@ MXS_MODULE* MXS_CREATE_MODULE() return &info; } + +} +