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.
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)

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);
// 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<qc_log_level_t>(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;
}
}