MXS-1248: Report fields from CTE expressions

Now field and function information of CTE expressions are
collected.
This commit is contained in:
Johan Wikman
2017-06-29 15:03:44 +02:00
parent 48a67eeef2
commit 84c5aa9934
2 changed files with 78 additions and 1 deletions

View File

@ -74,6 +74,20 @@
#include <string.h>
#include <stdarg.h>
#if MYSQL_VERSION_MAJOR >= 10 && MYSQL_VERSION_MINOR >= 2
#define CTE_SUPPORTED
#endif
#if defined(CTE_SUPPORTED)
// We need to be able to access private data of With_element that has no
// public access methods. So, we use this very questionable method of
// making the private parts public. Ok, as qc_myselembedded is only
// used for verifying the output of qc_sqlite.
#define private public
#include <sql_cte.h>
#undef private
#endif
/**
* Defines what a particular name should be mapped to.
*/
@ -159,7 +173,6 @@ static bool parse_query(GWBUF* querybuf);
static bool query_is_parsed(GWBUF* buf);
int32_t qc_mysql_get_field_info(GWBUF* buf, const QC_FIELD_INFO** infos, uint32_t* n_infos);
#if MYSQL_VERSION_MAJOR >= 10 && MYSQL_VERSION_MINOR >= 3
inline void get_string_and_length(const LEX_CSTRING& ls, const char** s, size_t* length)
{
@ -2725,6 +2738,22 @@ static void update_field_infos(parsing_info_t* pi,
}
}
#ifdef CTE_SUPPORTED
static void update_field_infos(parsing_info_t* pi,
LEX* lex,
st_select_lex_unit* select,
uint32_t usage,
List<Item>* excludep)
{
st_select_lex* s = select->first_select();
if (s)
{
update_field_infos(pi, lex, s, usage, excludep);
}
}
#endif
static void update_field_infos(parsing_info_t* pi,
LEX* lex,
st_select_lex* select,
@ -2840,6 +2869,33 @@ int32_t qc_mysql_get_field_info(GWBUF* buf, const QC_FIELD_INFO** infos, uint32_
update_field_infos(pi, lex, &lex->select_lex, usage, NULL);
#ifdef CTE_SUPPORTED
if (lex->with_clauses_list)
{
With_clause* with_clause = lex->with_clauses_list;
while (with_clause)
{
SQL_I_List<With_element>& with_list = with_clause->with_list;
With_element* element = with_list.first;
while (element)
{
update_field_infos(pi, lex, element->spec, usage, NULL);
if (element->first_recursive)
{
update_field_infos(pi, lex, element->first_recursive, usage, NULL);
}
element = element->next;
}
with_clause = with_clause->next_with_clause;
}
}
#endif
List_iterator<Item> ilist(lex->value_list);
while (Item* item = ilist++)
{