MXS-1307 Aliases must be stored hierarchically

Alias handling must be made so that in a subselect, aliases created
in an outer select are available, but aliases created in another
subselect are not.
This commit is contained in:
Johan Wikman 2017-08-09 15:31:05 +03:00
parent ebe9596966
commit 878bbe4a98

View File

@ -123,6 +123,8 @@ struct QcAliasValue
const char* zTable;
};
typedef std::map<std::string, QcAliasValue> QcAliases;
/**
* The state of qc_sqlite.
*/
@ -174,33 +176,44 @@ static void parse_query_string(const char* query, int len, bool suppress_logging
static bool query_is_parsed(GWBUF* query, uint32_t collect);
static bool should_exclude(const char* zName, const ExprList* pExclude);
static void update_field_infos_from_expr(QcSqliteInfo* info,
QcAliases* pAliases,
const Expr* pExpr,
uint32_t usage,
const ExprList* pExclude);
static void update_field_infos(QcSqliteInfo* info,
QcAliases* pAliases,
int prev_token,
const Expr* pExpr,
uint32_t usage,
qc_token_position_t pos,
const ExprList* pExclude);
static void update_field_infos_from_exprlist(QcSqliteInfo* info,
QcAliases* pAliases,
const ExprList* pEList,
uint32_t usage,
const ExprList* pExclude);
static void update_field_infos_from_idlist(QcSqliteInfo* info,
QcAliases* pAliases,
const IdList* pIds,
uint32_t usage,
const ExprList* pExclude);
static void update_field_infos_from_select(QcSqliteInfo* info,
QcAliases& aliases,
const Select* pSelect,
uint32_t usage,
const ExprList* pExclude);
static void update_field_infos_from_subselect(QcSqliteInfo* info,
QcAliases* pAliases,
const Select* pSelect,
uint32_t usage,
const ExprList* pExclude);
static void update_field_infos_from_with(QcSqliteInfo* info,
const With* pWith);
QcAliases* pAliases,
const With* pWith);
static void update_function_info(QcSqliteInfo* info,
const char* name,
uint32_t usage);
static void update_names_from_srclist(QcSqliteInfo* info, const SrcList* pSrc);
static void update_names_from_srclist(QcSqliteInfo* info, QcAliases* pAliases, const SrcList* pSrc);
// Defined in parse.y
extern "C"
@ -525,7 +538,8 @@ public:
return rv;
}
void update_field_info(const char* zDatabase,
void update_field_info(const QcAliases* pAliases,
const char* zDatabase,
const char* zTable,
const char* zColumn,
uint32_t usage,
@ -548,11 +562,11 @@ public:
return;
}
if (!zDatabase && zTable)
if (!zDatabase && zTable && pAliases)
{
Aliases::const_iterator i = m_aliases.find(zTable);
QcAliases::const_iterator i = pAliases->find(zTable);
if (i != m_aliases.end())
if (i != pAliases->end())
{
const QcAliasValue& value = i->second;
@ -641,11 +655,11 @@ public:
}
}
void update_names(const char* zDatabase, const char* zTable, const char* zAlias)
void update_names(const char* zDatabase, const char* zTable, const char* zAlias, QcAliases* pAliases)
{
ss_dassert(zTable);
bool should_collect_alias = zAlias && should_collect(QC_COLLECT_FIELDS);
bool should_collect_alias = pAliases && zAlias && should_collect(QC_COLLECT_FIELDS);
bool should_collect_table = should_collect_alias || should_collect(QC_COLLECT_TABLES);
bool should_collect_database = zDatabase &&
(should_collect_alias || should_collect(QC_COLLECT_DATABASES));
@ -681,11 +695,11 @@ public:
zCollected_database = update_database_names(database);
}
if (zCollected_table && zAlias)
if (pAliases && zCollected_table && zAlias)
{
QcAliasValue value(zCollected_database, zCollected_table);
m_aliases.insert(Aliases::value_type(zAlias, value));
pAliases->insert(QcAliases::value_type(zAlias, value));
}
}
@ -791,7 +805,7 @@ public:
{
ss_dassert(this_thread.initialized);
update_names_from_srclist(this, pSrcList);
update_names_from_srclist(this, NULL, pSrcList);
exposed_sqlite3SrcListDelete(pParse->db, pSrcList);
}
@ -803,7 +817,7 @@ public:
m_status = QC_QUERY_PARSED;
m_type_mask = (QUERY_TYPE_WRITE | QUERY_TYPE_COMMIT);
update_names_from_srclist(this, pSrcList);
update_names_from_srclist(this, NULL, pSrcList);
exposed_sqlite3SrcListDelete(pParse->db, pSrcList);
}
@ -843,7 +857,7 @@ public:
if (pItem->zName)
{
update_names(pItem->zDatabase, pItem->zName, pItem->zAlias);
update_names(pItem->zDatabase, pItem->zName, pItem->zAlias, NULL);
}
}
}
@ -880,11 +894,11 @@ public:
if (pTblName)
{
update_names_from_srclist(this, pTblName);
update_names_from_srclist(this, NULL, pTblName);
}
else if (pParse->pNewTable)
{
update_names(NULL, pParse->pNewTable->zName, NULL);
update_names(NULL, pParse->pNewTable->zName, NULL, NULL);
}
exposed_sqlite3ExprDelete(pParse->db, pPIWhere);
@ -914,22 +928,24 @@ public:
strncpy(name, pName->z, pName->n);
name[pName->n] = 0;
QcAliases aliases;
if (pDatabase)
{
char database[pDatabase->n + 1];
strncpy(database, pDatabase->z, pDatabase->n);
database[pDatabase->n] = 0;
update_names(database, name, NULL);
update_names(database, name, NULL, &aliases);
}
else
{
update_names(NULL, name, NULL);
update_names(NULL, name, NULL, &aliases);
}
if (pSelect)
{
update_field_infos_from_select(this, pSelect, QC_USED_IN_SELECT, NULL);
update_field_infos_from_select(this, aliases, pSelect, QC_USED_IN_SELECT, NULL);
}
exposed_sqlite3ExprListDelete(pParse->db, pCNames);
@ -948,6 +964,8 @@ public:
m_operation = QUERY_OP_DELETE;
m_has_clause = pWhere ? true : false;
QcAliases aliases;
if (pUsing)
{
// Walk through the using declaration and update
@ -956,7 +974,7 @@ public:
{
const SrcList::SrcList_item* pItem = &pUsing->a[i];
update_names(pItem->zDatabase, pItem->zName, pItem->zAlias);
update_names(pItem->zDatabase, pItem->zName, pItem->zAlias, &aliases);
}
// Walk through the tablenames while excluding alias
@ -986,18 +1004,18 @@ public:
if (!isSame)
{
// No alias name, update the table name.
update_names(pTable->zDatabase, pTable->zName, NULL);
update_names(pTable->zDatabase, pTable->zName, NULL, &aliases);
}
}
}
else
{
update_names_from_srclist(this, pTabList);
update_names_from_srclist(this, &aliases, pTabList);
}
if (pWhere)
{
update_field_infos(this, 0, pWhere, QC_USED_IN_WHERE, QC_TOKEN_MIDDLE, 0);
update_field_infos(this, &aliases, 0, pWhere, QC_USED_IN_WHERE, QC_TOKEN_MIDDLE, 0);
}
}
@ -1014,7 +1032,7 @@ public:
m_type_mask = (QUERY_TYPE_WRITE | QUERY_TYPE_COMMIT);
m_operation = QUERY_OP_DROP;
update_names_from_srclist(this, pTable);
update_names_from_srclist(this, NULL, pTable);
exposed_sqlite3SrcListDelete(pParse->db, pName);
exposed_sqlite3SrcListDelete(pParse->db, pTable);
@ -1035,7 +1053,7 @@ public:
{
m_is_drop_table = true;
}
update_names_from_srclist(this, pName);
update_names_from_srclist(this, NULL, pName);
exposed_sqlite3SrcListDelete(pParse->db, pName);
}
@ -1051,11 +1069,12 @@ public:
if (pSelect)
{
update_field_infos_from_select(this, pSelect, QC_USED_IN_SELECT, NULL);
QcAliases aliases;
update_field_infos_from_select(this, aliases, pSelect, QC_USED_IN_SELECT, NULL);
}
else if (pOldTable)
{
update_names_from_srclist(this, pOldTable);
update_names_from_srclist(this, NULL, pOldTable);
exposed_sqlite3SrcListDelete(pParse->db, pOldTable);
}
}
@ -1077,11 +1096,14 @@ public:
m_operation = QUERY_OP_INSERT;
ss_dassert(pTabList);
ss_dassert(pTabList->nSrc >= 1);
update_names_from_srclist(this, pTabList);
QcAliases aliases;
update_names_from_srclist(this, &aliases, pTabList);
if (pColumns)
{
update_field_infos_from_idlist(this, pColumns, 0, NULL);
update_field_infos_from_idlist(this, &aliases, pColumns, 0, NULL);
}
if (pSelect)
@ -1097,12 +1119,12 @@ public:
usage = QC_USED_IN_SELECT;
}
update_field_infos_from_select(this, pSelect, usage, NULL);
update_field_infos_from_select(this, aliases, pSelect, usage, NULL);
}
if (pSet)
{
update_field_infos_from_exprlist(this, pSet, 0, NULL);
update_field_infos_from_exprlist(this, &aliases, pSet, 0, NULL);
}
}
@ -1171,11 +1193,11 @@ public:
strncpy(database, pDatabase->z, pDatabase->n);
database[pDatabase->n] = 0;
update_names(database, name, NULL);
update_names(database, name, NULL, NULL);
}
else
{
update_names(NULL, name, NULL);
update_names(NULL, name, NULL, NULL);
}
if (m_collect & QC_COLLECT_TABLES)
@ -1203,9 +1225,11 @@ public:
if (m_operation != QUERY_OP_EXPLAIN)
{
QcAliases aliases;
m_type_mask = QUERY_TYPE_WRITE;
m_operation = QUERY_OP_UPDATE;
update_names_from_srclist(this, pTabList);
update_names_from_srclist(this, &aliases, pTabList);
m_has_clause = (pWhere ? true : false);
if (pChanges)
@ -1214,13 +1238,14 @@ public:
{
ExprList::ExprList_item* pItem = &pChanges->a[i];
update_field_infos(this, 0, pItem->pExpr, QC_USED_IN_SET, QC_TOKEN_MIDDLE, NULL);
update_field_infos(this, &aliases,
0, pItem->pExpr, QC_USED_IN_SET, QC_TOKEN_MIDDLE, NULL);
}
}
if (pWhere)
{
update_field_infos(this, 0, pWhere, QC_USED_IN_WHERE, QC_TOKEN_MIDDLE, pChanges);
update_field_infos(this, &aliases, 0, pWhere, QC_USED_IN_WHERE, QC_TOKEN_MIDDLE, pChanges);
}
}
@ -1256,7 +1281,8 @@ public:
uint32_t usage = sub_select ? QC_USED_IN_SUBSELECT : QC_USED_IN_SELECT;
update_field_infos_from_select(this, pSelect, usage, NULL);
QcAliases aliases;
update_field_infos_from_select(this, aliases, pSelect, usage, NULL);
}
void maxscaleAlterTable(Parse *pParse, /* Parser context. */
@ -1273,15 +1299,15 @@ public:
switch (command)
{
case MXS_ALTER_DISABLE_KEYS:
update_names_from_srclist(this, pSrc);
update_names_from_srclist(this, NULL, pSrc);
break;
case MXS_ALTER_ENABLE_KEYS:
update_names_from_srclist(this, pSrc);
update_names_from_srclist(this, NULL, pSrc);
break;
case MXS_ALTER_RENAME:
update_names_from_srclist(this, pSrc);
update_names_from_srclist(this, NULL, pSrc);
break;
default:
@ -1300,7 +1326,7 @@ public:
if (pExprList)
{
update_field_infos_from_exprlist(this, pExprList, 0, NULL);
update_field_infos_from_exprlist(this, NULL, pExprList, 0, NULL);
}
exposed_sqlite3SrcListDelete(pParse->db, pName);
@ -1314,7 +1340,7 @@ public:
m_status = QC_QUERY_PARSED;
m_type_mask = (QUERY_TYPE_WRITE | QUERY_TYPE_COMMIT);
update_names_from_srclist(this, pTables);
update_names_from_srclist(this, NULL, pTables);
exposed_sqlite3SrcListDelete(pParse->db, pTables);
}
@ -1340,7 +1366,7 @@ public:
strncpy(table, pTable->z, pTable->n);
table[pTable->n] = 0;
update_names(zDatabase, table, NULL);
update_names(zDatabase, table, NULL, NULL);
}
void maxscaleComment()
@ -1424,7 +1450,7 @@ public:
strncpy(table, pName->z, pName->n);
table[pName->n] = 0;
update_names(zDatabase, table, NULL);
update_names(zDatabase, table, NULL, NULL);
}
}
@ -1537,7 +1563,7 @@ public:
ss_dassert(pFullName->nSrc == 1);
const SrcList::SrcList_item* pItem = &pFullName->a[0];
update_names(pItem->zDatabase, pItem->zName, pItem->zAlias);
update_names(pItem->zDatabase, pItem->zName, pItem->zAlias, NULL);
}
break;
@ -1549,7 +1575,7 @@ public:
strncpy(zName, pName->z, pName->n);
zName[pName->n] = 0;
update_names("*any*", zName, NULL);
update_names("*any*", zName, NULL, NULL);
}
break;
@ -1570,7 +1596,7 @@ public:
if (pFullName)
{
update_names_from_srclist(this, pFullName);
update_names_from_srclist(this, NULL, pFullName);
exposed_sqlite3SrcListDelete(pParse->db, pFullName);
}
@ -1585,7 +1611,7 @@ public:
if (pTables)
{
update_names_from_srclist(this, pTables);
update_names_from_srclist(this, NULL, pTables);
exposed_sqlite3SrcListDelete(pParse->db, pTables);
}
@ -1872,8 +1898,8 @@ public:
ss_dassert(pItem->zName);
ss_dassert(pItem->zAlias);
update_names(pItem->zDatabase, pItem->zName, NULL);
update_names(NULL, pItem->zAlias, NULL); // The new name is passed in the alias field.
update_names(pItem->zDatabase, pItem->zName, NULL, NULL);
update_names(NULL, pItem->zAlias, NULL, NULL); // The new name is passed in the alias field.
}
exposed_sqlite3SrcListDelete(pParse->db, pTables);
@ -2128,7 +2154,8 @@ public:
if (pValue->op == TK_SELECT)
{
update_field_infos_from_select(this, pValue->x.pSelect,
QcAliases aliases;
update_field_infos_from_select(this, aliases, pValue->x.pSelect,
QC_USED_IN_SUBSELECT, NULL);
}
}
@ -2267,7 +2294,7 @@ public:
strncpy(name, pName->z, pName->n);
name[pName->n] = 0;
update_names(zDatabase, name, NULL);
update_names(zDatabase, name, NULL, NULL);
}
void maxscaleUse(Parse* pParse, Token* pToken)
@ -2496,8 +2523,6 @@ private:
}
public:
typedef std::map<std::string, QcAliasValue> Aliases;
// TODO: Make these private once everything's been updated.
qc_parse_result_t m_status; // The validity of the information in this structure.
uint32_t m_collect; // What information should be collected.
@ -2531,7 +2556,6 @@ public:
size_t m_function_infos_capacity; // The capacity of the function_infos array.
qc_sql_mode_t m_sql_mode; // The current sql_mode.
QC_NAME_MAPPING* m_pFunction_name_mappings; // How function names should be mapped.
Aliases m_aliases; // Alias names for tables
};
extern "C"
@ -3034,6 +3058,7 @@ extern void maxscale_update_function_info(const char* name, uint32_t usage)
}
static void update_field_infos_from_expr(QcSqliteInfo* info,
QcAliases* pAliases,
const Expr* pExpr,
uint32_t usage,
const ExprList* pExclude)
@ -3098,12 +3123,13 @@ static void update_field_infos_from_expr(QcSqliteInfo* info,
if (should_update)
{
info->update_field_info(item.database, item.table, item.column, usage, pExclude);
info->update_field_info(pAliases, item.database, item.table, item.column, usage, pExclude);
}
}
}
static void update_field_infos_from_with(QcSqliteInfo* info,
static void update_field_infos_from_with(QcSqliteInfo* pInfo,
QcAliases* pAliases,
const With* pWith)
{
for (int i = 0; i < pWith->nCte; ++i)
@ -3112,7 +3138,7 @@ static void update_field_infos_from_with(QcSqliteInfo* info,
if (pCte->pSelect)
{
update_field_infos_from_select(info, pCte->pSelect, QC_USED_IN_SUBSELECT, NULL);
update_field_infos_from_subselect(pInfo, pAliases, pCte->pSelect, QC_USED_IN_SUBSELECT, NULL);
}
}
}
@ -3186,6 +3212,7 @@ static const char* get_token_symbol(int token)
}
static void update_field_infos(QcSqliteInfo* info,
QcAliases* pAliases,
int prev_token,
const Expr* pExpr,
uint32_t usage,
@ -3201,15 +3228,15 @@ static void update_field_infos(QcSqliteInfo* info,
switch (pExpr->op)
{
case TK_ASTERISK: // select *
update_field_infos_from_expr(info, pExpr, usage, pExclude);
update_field_infos_from_expr(info, pAliases, pExpr, usage, pExclude);
break;
case TK_DOT: // select a.b ... select a.b.c
update_field_infos_from_expr(info, pExpr, usage, pExclude);
update_field_infos_from_expr(info, pAliases, pExpr, usage, pExclude);
break;
case TK_ID: // select a
update_field_infos_from_expr(info, pExpr, usage, pExclude);
update_field_infos_from_expr(info, pAliases, pExpr, usage, pExclude);
break;
case TK_VARIABLE:
@ -3375,7 +3402,7 @@ static void update_field_infos(QcSqliteInfo* info,
if (pLeft)
{
update_field_infos(info, pExpr->op, pExpr->pLeft, usage, QC_TOKEN_LEFT, pExclude);
update_field_infos(info, pAliases, pExpr->op, pExpr->pLeft, usage, QC_TOKEN_LEFT, pExclude);
}
if (pRight)
@ -3385,7 +3412,7 @@ static void update_field_infos(QcSqliteInfo* info,
usage &= ~QC_USED_IN_SET;
}
update_field_infos(info, pExpr->op, pExpr->pRight, usage, QC_TOKEN_RIGHT, pExclude);
update_field_infos(info, pAliases, pExpr->op, pExpr->pRight, usage, QC_TOKEN_RIGHT, pExclude);
}
if (pExpr->x.pList)
@ -3397,7 +3424,7 @@ static void update_field_infos(QcSqliteInfo* info,
case TK_FUNCTION:
if (!ignore_exprlist)
{
update_field_infos_from_exprlist(info, pExpr->x.pList, usage, pExclude);
update_field_infos_from_exprlist(info, pAliases, pExpr->x.pList, usage, pExclude);
}
break;
@ -3410,11 +3437,11 @@ static void update_field_infos(QcSqliteInfo* info,
sub_usage &= ~QC_USED_IN_SELECT;
sub_usage |= QC_USED_IN_SUBSELECT;
update_field_infos_from_select(info, pExpr->x.pSelect, sub_usage, pExclude);
update_field_infos_from_subselect(info, pAliases, pExpr->x.pSelect, sub_usage, pExclude);
}
else
{
update_field_infos_from_exprlist(info, pExpr->x.pList, usage, pExclude);
update_field_infos_from_exprlist(info, pAliases, pExpr->x.pList, usage, pExclude);
}
break;
}
@ -3424,6 +3451,7 @@ static void update_field_infos(QcSqliteInfo* info,
}
static void update_field_infos_from_exprlist(QcSqliteInfo* info,
QcAliases* pAliases,
const ExprList* pEList,
uint32_t usage,
const ExprList* pExclude)
@ -3432,11 +3460,12 @@ static void update_field_infos_from_exprlist(QcSqliteInfo* info,
{
ExprList::ExprList_item* pItem = &pEList->a[i];
update_field_infos(info, 0, pItem->pExpr, usage, QC_TOKEN_MIDDLE, pExclude);
update_field_infos(info, pAliases, 0, pItem->pExpr, usage, QC_TOKEN_MIDDLE, pExclude);
}
}
static void update_field_infos_from_idlist(QcSqliteInfo* info,
QcAliases* pAliases,
const IdList* pIds,
uint32_t usage,
const ExprList* pExclude)
@ -3445,11 +3474,12 @@ static void update_field_infos_from_idlist(QcSqliteInfo* info,
{
IdList::IdList_item* pItem = &pIds->a[i];
info->update_field_info(NULL, NULL, pItem->zName, usage, pExclude);
info->update_field_info(pAliases, NULL, NULL, pItem->zName, usage, pExclude);
}
}
static void update_field_infos_from_select(QcSqliteInfo* pInfo,
QcAliases& aliases,
const Select* pSelect,
uint32_t usage,
const ExprList* pExclude)
@ -3462,7 +3492,7 @@ static void update_field_infos_from_select(QcSqliteInfo* pInfo,
{
if (pSrc->a[i].zName)
{
pInfo->update_names(pSrc->a[i].zDatabase, pSrc->a[i].zName, pSrc->a[i].zAlias);
pInfo->update_names(pSrc->a[i].zDatabase, pSrc->a[i].zName, pSrc->a[i].zAlias, &aliases);
}
if (pSrc->a[i].pSelect)
@ -3472,7 +3502,7 @@ static void update_field_infos_from_select(QcSqliteInfo* pInfo,
sub_usage &= ~QC_USED_IN_SELECT;
sub_usage |= QC_USED_IN_SUBSELECT;
update_field_infos_from_select(pInfo, pSrc->a[i].pSelect, sub_usage, pExclude);
update_field_infos_from_select(pInfo, aliases, pSrc->a[i].pSelect, sub_usage, pExclude);
}
#ifdef QC_COLLECT_NAMES_FROM_USING
@ -3482,7 +3512,7 @@ static void update_field_infos_from_select(QcSqliteInfo* pInfo,
// does not reveal its value, right?
if (pSrc->a[i].pUsing)
{
update_field_infos_from_idlist(pInfo, pSrc->a[i].pUsing, 0, pSelect->pEList);
update_field_infos_from_idlist(pInfo, aliases, pSrc->a[i].pUsing, 0, pSelect->pEList);
}
#endif
}
@ -3490,18 +3520,20 @@ static void update_field_infos_from_select(QcSqliteInfo* pInfo,
if (pSelect->pEList)
{
update_field_infos_from_exprlist(pInfo, pSelect->pEList, usage, NULL);
update_field_infos_from_exprlist(pInfo, &aliases, pSelect->pEList, usage, NULL);
}
if (pSelect->pWhere)
{
pInfo->m_has_clause = true;
update_field_infos(pInfo, 0, pSelect->pWhere, QC_USED_IN_WHERE, QC_TOKEN_MIDDLE, pSelect->pEList);
update_field_infos(pInfo, &aliases,
0, pSelect->pWhere, QC_USED_IN_WHERE, QC_TOKEN_MIDDLE, pSelect->pEList);
}
if (pSelect->pGroupBy)
{
update_field_infos_from_exprlist(pInfo, pSelect->pGroupBy, QC_USED_IN_GROUP_BY, pSelect->pEList);
update_field_infos_from_exprlist(pInfo, &aliases,
pSelect->pGroupBy, QC_USED_IN_GROUP_BY, pSelect->pEList);
}
if (pSelect->pHaving)
@ -3510,33 +3542,46 @@ static void update_field_infos_from_select(QcSqliteInfo* pInfo,
#if defined(COLLECT_HAVING_AS_WELL)
// A HAVING clause can only refer to fields that already have been
// mentioned. Consequently, they need not be collected.
update_field_infos(pInfo, 0, pSelect->pHaving, 0, QC_TOKEN_MIDDLE, pSelect->pEList);
update_field_infos(pInfo, aliases, 0, pSelect->pHaving, 0, QC_TOKEN_MIDDLE, pSelect->pEList);
#endif
}
if (pSelect->pWith)
{
update_field_infos_from_with(pInfo, pSelect->pWith);
update_field_infos_from_with(pInfo, &aliases, pSelect->pWith);
}
if ((pSelect->op == TK_UNION) && pSelect->pPrior)
{
update_field_infos_from_select(pInfo, pSelect->pPrior, usage, pExclude);
update_field_infos_from_subselect(pInfo, &aliases, pSelect->pPrior, usage, pExclude);
}
}
static void update_names_from_srclist(QcSqliteInfo* pInfo, const SrcList* pSrc)
static void update_field_infos_from_subselect(QcSqliteInfo* pInfo,
QcAliases* pAliases,
const Select* pSelect,
uint32_t usage,
const ExprList* pExclude)
{
QcAliases aliases(*pAliases);
update_field_infos_from_select(pInfo, aliases, pSelect, usage, pExclude);
}
static void update_names_from_srclist(QcSqliteInfo* pInfo,
QcAliases* pAliases,
const SrcList* pSrc)
{
for (int i = 0; i < pSrc->nSrc; ++i)
{
if (pSrc->a[i].zName)
{
pInfo->update_names(pSrc->a[i].zDatabase, pSrc->a[i].zName, pSrc->a[i].zAlias);
pInfo->update_names(pSrc->a[i].zDatabase, pSrc->a[i].zName, pSrc->a[i].zAlias, pAliases);
}
if (pSrc->a[i].pSelect && pSrc->a[i].pSelect->pSrc)
{
update_names_from_srclist(pInfo, pSrc->a[i].pSelect->pSrc);
update_names_from_srclist(pInfo, pAliases, pSrc->a[i].pSelect->pSrc);
}
}
}