MXS-3535 Collect information from ON clause
In the case of qc_sqlite, it is done "precisely", while in the case of qc_mysqlembedded rather bluntly. Not time well spent to figure out exactly which pointer chains need to be walked.
This commit is contained in:
@ -71,6 +71,9 @@
|
|||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <stdarg.h>
|
#include <stdarg.h>
|
||||||
|
#include <set>
|
||||||
|
|
||||||
|
using std::set;
|
||||||
|
|
||||||
#if MYSQL_VERSION_MAJOR >= 10 && MYSQL_VERSION_MINOR >= 2
|
#if MYSQL_VERSION_MAJOR >= 10 && MYSQL_VERSION_MINOR >= 2
|
||||||
#define CTE_SUPPORTED
|
#define CTE_SUPPORTED
|
||||||
@ -3434,6 +3437,51 @@ static void update_field_infos(parsing_info_t* pi,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
namespace
|
||||||
|
{
|
||||||
|
|
||||||
|
void collect_from_list(set<TABLE_LIST*>& seen, parsing_info_t* pi, SELECT_LEX* select_lex, TABLE_LIST* pList)
|
||||||
|
{
|
||||||
|
if (seen.find(pList) != seen.end())
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
seen.insert(pList);
|
||||||
|
|
||||||
|
if (pList->on_expr)
|
||||||
|
{
|
||||||
|
update_field_infos(pi, select_lex, COLLECT_SELECT, pList->on_expr, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (pList->next_global)
|
||||||
|
{
|
||||||
|
collect_from_list(seen, pi, select_lex, pList->next_global);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (pList->next_local)
|
||||||
|
{
|
||||||
|
collect_from_list(seen, pi, select_lex, pList->next_local);
|
||||||
|
}
|
||||||
|
|
||||||
|
st_nested_join* pJoin = pList->nested_join;
|
||||||
|
|
||||||
|
if (pJoin)
|
||||||
|
{
|
||||||
|
List_iterator<TABLE_LIST> it(pJoin->join_list);
|
||||||
|
|
||||||
|
TABLE_LIST* pList2 = it++;
|
||||||
|
|
||||||
|
while (pList2)
|
||||||
|
{
|
||||||
|
collect_from_list(seen, pi, select_lex, pList2);
|
||||||
|
pList2 = it++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
int32_t qc_mysql_get_field_info(GWBUF* buf, const QC_FIELD_INFO** infos, uint32_t* n_infos)
|
int32_t qc_mysql_get_field_info(GWBUF* buf, const QC_FIELD_INFO** infos, uint32_t* n_infos)
|
||||||
{
|
{
|
||||||
*infos = NULL;
|
*infos = NULL;
|
||||||
@ -3474,6 +3522,33 @@ int32_t qc_mysql_get_field_info(GWBUF* buf, const QC_FIELD_INFO** infos, uint32_
|
|||||||
|
|
||||||
update_field_infos(pi, lex, select_lex, NULL);
|
update_field_infos(pi, lex, select_lex, NULL);
|
||||||
|
|
||||||
|
set<TABLE_LIST*> seen;
|
||||||
|
|
||||||
|
if (lex->query_tables)
|
||||||
|
{
|
||||||
|
collect_from_list(seen, pi, select_lex, lex->query_tables);
|
||||||
|
}
|
||||||
|
|
||||||
|
List_iterator<TABLE_LIST> it1(select_lex->top_join_list);
|
||||||
|
|
||||||
|
TABLE_LIST* pList = it1++;
|
||||||
|
|
||||||
|
while (pList)
|
||||||
|
{
|
||||||
|
collect_from_list(seen, pi, select_lex, pList);
|
||||||
|
pList = it1++;
|
||||||
|
}
|
||||||
|
|
||||||
|
List_iterator<TABLE_LIST> it2(select_lex->sj_nests);
|
||||||
|
|
||||||
|
/*TABLE_LIST**/ pList = it2++;
|
||||||
|
|
||||||
|
while (pList)
|
||||||
|
{
|
||||||
|
collect_from_list(seen, pi, select_lex, pList);
|
||||||
|
pList = it2++;
|
||||||
|
}
|
||||||
|
|
||||||
QC_FUNCTION_INFO* fi = NULL;
|
QC_FUNCTION_INFO* fi = NULL;
|
||||||
|
|
||||||
if ((lex->sql_command == SQLCOM_UPDATE) || (lex->sql_command == SQLCOM_UPDATE_MULTI))
|
if ((lex->sql_command == SQLCOM_UPDATE) || (lex->sql_command == SQLCOM_UPDATE_MULTI))
|
||||||
|
@ -1303,6 +1303,11 @@ public:
|
|||||||
pExclude);
|
pExclude);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (pSrc->a[i].pOn)
|
||||||
|
{
|
||||||
|
update_field_infos(&aliases, context, 0, pSrc->a[i].pOn, QC_TOKEN_MIDDLE, pExclude);
|
||||||
|
}
|
||||||
|
|
||||||
#ifdef QC_COLLECT_NAMES_FROM_USING
|
#ifdef QC_COLLECT_NAMES_FROM_USING
|
||||||
// With this enabled, the affected fields of
|
// With this enabled, the affected fields of
|
||||||
// select * from (t1 as t2 left join t1 as t3 using (a)), t1;
|
// select * from (t1 as t2 left join t1 as t3 using (a)), t1;
|
||||||
@ -1436,6 +1441,11 @@ public:
|
|||||||
{
|
{
|
||||||
update_names_from_srclist(pAliases, pSrc->a[i].pSelect->pSrc);
|
update_names_from_srclist(pAliases, pSrc->a[i].pSelect->pSrc);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (pSrc->a[i].pOn)
|
||||||
|
{
|
||||||
|
update_field_infos(pAliases, 0, 0, pSrc->a[i].pOn, QC_TOKEN_MIDDLE, NULL);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1615,12 +1615,16 @@ table_reference(A) ::= join_table(X). {
|
|||||||
join_opt ::= .
|
join_opt ::= .
|
||||||
join_opt ::= JOIN_KW.
|
join_opt ::= JOIN_KW.
|
||||||
|
|
||||||
join_table(A) ::= table_reference(X) join_opt JOIN table_reference(Y) join_condition. {
|
%type join_condition {ExprSpan}
|
||||||
|
%destructor join_condition {sqlite3ExprDelete(pParse->db, $$.pExpr);}
|
||||||
|
|
||||||
|
join_table(A) ::= table_reference(X) join_opt JOIN table_reference(Y) join_condition(Z). {
|
||||||
|
Y->a[Y->nSrc - 1].pOn = Z.pExpr;
|
||||||
A = sqlite3SrcListCat(pParse->db, X, Y);
|
A = sqlite3SrcListCat(pParse->db, X, Y);
|
||||||
}
|
}
|
||||||
|
|
||||||
join_condition ::= ON expr(X). {
|
join_condition(A) ::= ON expr(X). {
|
||||||
sqlite3ExprDelete(pParse->db, X.pExpr);
|
A = X;
|
||||||
}
|
}
|
||||||
|
|
||||||
%type escaped_table_reference {SrcList*}
|
%type escaped_table_reference {SrcList*}
|
||||||
|
Reference in New Issue
Block a user