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.
This commit is contained in:
Johan Wikman
2017-07-31 12:30:17 +03:00
parent 3eb99139f5
commit e4f0598743
2 changed files with 103 additions and 33 deletions

View File

@ -19,7 +19,7 @@ include_directories(${MARIADB_CONNECTOR_INCLUDE_DIR})
# GCC thinks there is an array-bounds error in sqlite code. # GCC thinks there is an array-bounds error in sqlite code.
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wno-error=array-bounds") 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_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) add_definitions(-DMAXSCALE -DSQLITE_THREADSAFE=0 -DSQLITE_ENABLE_UPDATE_DELETE_LIMIT -DSQLITE_OMIT_ATTACH -DSQLITE_OMIT_REINDEX -DSQLITE_OMIT_AUTOVACUUM -DSQLITE_OMIT_PRAGMA)

View File

@ -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); static void update_names_from_srclist(QC_SQLITE_INFO* info, const SrcList* pSrc);
// Defined in parse.y // Defined in parse.y
extern "C"
{
extern void exposed_sqlite3ExprDelete(sqlite3 *db, Expr *pExpr); extern void exposed_sqlite3ExprDelete(sqlite3 *db, Expr *pExpr);
extern void exposed_sqlite3ExprListDelete(sqlite3 *db, ExprList *pList); extern void exposed_sqlite3ExprListDelete(sqlite3 *db, ExprList *pList);
extern void exposed_sqlite3IdListDelete(sqlite3 *db, IdList *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 isView, /* True if this is a VIEW */
int isVirtual, /* True if this is a VIRTUAL table */ int isVirtual, /* True if this is a VIRTUAL table */
int noErr); /* Do nothing if table already exists */ 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 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. * 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) 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].database);
MXS_FREE(infos[i].table); MXS_FREE(infos[i].table);
@ -343,7 +404,7 @@ static void free_function_infos(QC_FUNCTION_INFO* infos, size_t n_infos)
{ {
if (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); 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) 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); MXS_ABORT_IF_NULL(info);
info_init(info, collect); 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 (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); 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; int i;
for (i = 0; i < pExclude->nExpr; ++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 // 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 // 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 }; 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) for (i = 0; i < info->field_infos_len; ++i)
{ {
QC_FIELD_INFO* field_info = info->field_infos + i; QC_FIELD_INFO* field_info = info->field_infos + i;
@ -897,7 +958,8 @@ static void update_field_info(QC_SQLITE_INFO* info,
else else
{ {
size_t capacity = info->field_infos_capacity ? 2 * info->field_infos_capacity : 8; 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) if (field_infos)
{ {
@ -946,7 +1008,7 @@ static void update_function_info(QC_SQLITE_INFO* info,
QC_FUNCTION_INFO item = { (char*)name, usage }; QC_FUNCTION_INFO item = { (char*)name, usage };
int i; size_t i;
for (i = 0; i < info->function_infos_len; ++i) for (i = 0; i < info->function_infos_len; ++i)
{ {
QC_FUNCTION_INFO* function_info = info->function_infos + i; QC_FUNCTION_INFO* function_info = info->function_infos + i;
@ -968,7 +1030,8 @@ static void update_function_info(QC_SQLITE_INFO* info,
else else
{ {
size_t capacity = info->function_infos_capacity ? 2 * info->function_infos_capacity : 8; 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) if (function_infos)
{ {
@ -1011,7 +1074,7 @@ static void update_field_infos_from_expr(QC_SQLITE_INFO* info,
if (pExpr->op == TK_ASTERISK) if (pExpr->op == TK_ASTERISK)
{ {
item.column = "*"; item.column = (char*)"*";
} }
else if (pExpr->op == TK_ID) else if (pExpr->op == TK_ID)
{ {
@ -1031,7 +1094,7 @@ static void update_field_infos_from_expr(QC_SQLITE_INFO* info,
} }
else else
{ {
item.column = "*"; item.column = (char*)"*";
} }
} }
else if (pExpr->pLeft->op == TK_ID && else if (pExpr->pLeft->op == TK_ID &&
@ -1048,7 +1111,7 @@ static void update_field_infos_from_expr(QC_SQLITE_INFO* info,
} }
else 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) 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) 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) 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); 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) 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); 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) 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); MXS_ABORT_IF_NULL(zCopy);
strcpy(zCopy, zDatabase); strcpy(zCopy, zDatabase);
@ -1650,9 +1713,9 @@ void mxs_sqlite3BeginTrigger(Parse *pParse, /* The parse context of the CRE
if (pTableName) 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) if (pItem->zName)
{ {
@ -1778,7 +1841,7 @@ void mxs_sqlite3DeleteFrom(Parse* pParse, SrcList* pTabList, Expr* pWhere, SrcLi
// table and database names. // table and database names.
for (int i = 0; i < pUsing->nSrc; ++i) 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); 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. // names from the using declaration.
for (int i = 0; i < pTabList->nSrc; ++i) 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); ss_dassert(pTable->zName);
int j = 0; int j = 0;
bool isSame = false; bool isSame = false;
do do
{ {
struct SrcList_item* pItem = &pUsing->a[j++]; SrcList::SrcList_item* pItem = &pUsing->a[j++];
if (strcasecmp(pTable->zName, pItem->zName) == 0) 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) 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); 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. // this information already.
if (!info->prepare_name) 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) if (info->prepare_name)
{ {
memcpy(info->prepare_name, pName->z, pName->n); memcpy(info->prepare_name, pName->z, pName->n);
@ -2355,7 +2418,7 @@ void maxscaleExecute(Parse* pParse, Token* pName, int type_mask)
// this information already. // this information already.
if (!info->prepare_name) 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) if (info->prepare_name)
{ {
memcpy(info->prepare_name, pName->z, pName->n); 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; info->type_mask = QUERY_TYPE_WRITE;
ss_dassert(pFullName->nSrc == 1); 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); update_names(info, pItem->zDatabase, pItem->zName);
} }
@ -2689,7 +2752,8 @@ int maxscaleKeyword(int token)
break; break;
case TK_HANDLER: case TK_HANDLER:
info->status = QUERY_TYPE_WRITE; info->status = QC_QUERY_TOKENIZED;
info->type_mask = QUERY_TYPE_WRITE;
break; break;
case TK_INSERT: case TK_INSERT:
@ -2849,7 +2913,7 @@ void maxscaleRenameTable(Parse* pParse, SrcList* pTables)
for (int i = 0; i < pTables->nSrc; ++i) 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->zName);
ss_dassert(pItem->zAlias); ss_dassert(pItem->zAlias);
@ -2933,7 +2997,7 @@ void maxscalePrepare(Parse* pParse, Token* pName, Expr* pStmt)
// this information already. // this information already.
if (!info->prepare_name) 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) if (info->prepare_name)
{ {
memcpy(info->prepare_name, pName->z, pName->n); 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) 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) 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)) if ((*end == 0) && (l >= QC_LOG_NOTHING) && (l <= QC_LOG_NON_TOKENIZED))
{ {
log_level = l; log_level = static_cast<qc_log_level_t>(l);
} }
else else
{ {
@ -4064,6 +4128,9 @@ int32_t qc_sqlite_set_sql_mode(qc_sql_mode_t sql_mode)
* EXPORTS * EXPORTS
*/ */
extern "C"
{
MXS_MODULE* MXS_CREATE_MODULE() MXS_MODULE* MXS_CREATE_MODULE()
{ {
static QUERY_CLASSIFIER qc = static QUERY_CLASSIFIER qc =
@ -4112,3 +4179,6 @@ MXS_MODULE* MXS_CREATE_MODULE()
return &info; return &info;
} }
}