MXS-942: Don't return information_schema as the parsed database

When a DESCRIBE <table> or a SHOW COLUMNS IN <table> query is done, the
actual query is performed on tables in the information_schema
database. This might be what actually happens on the backend server but
this information is not really useful when we need to know which database
the query targets.

By passing the actual table names instead of the underlying table names,
the schemarouter is able to detect where these statements should be
routed.
This commit is contained in:
Markus Makela
2016-10-21 00:34:21 +03:00
parent 8e9012f514
commit d53a6d2899
3 changed files with 28 additions and 8 deletions

View File

@ -95,7 +95,7 @@ static parsing_info_t* parsing_info_init(void (*donefun)(void *));
static void parsing_info_set_plain_str(void* ptr, char* str);
/** Free THD context and close MYSQL */
static void parsing_info_done(void* ptr);
static void* skygw_get_affected_tables(void* lexptr);
static TABLE_LIST* skygw_get_affected_tables(void* lexptr);
static bool ensure_query_is_parsed(GWBUF* query);
static bool parse_query(GWBUF* querybuf);
static bool query_is_parsed(GWBUF* buf);
@ -1063,7 +1063,7 @@ LEX* get_lex(GWBUF* querybuf)
* @param thd Pointer to a valid THD
* @return Pointer to the head of the TABLE_LIST chain or NULL in case of an error
*/
static void* skygw_get_affected_tables(void* lexptr)
static TABLE_LIST* skygw_get_affected_tables(void* lexptr)
{
LEX* lex = (LEX*) lexptr;
@ -1073,7 +1073,23 @@ static void* skygw_get_affected_tables(void* lexptr)
return NULL;
}
return (void*) lex->current_select->table_list.first;
TABLE_LIST *tbl = lex->current_select->table_list.first;
if (tbl && tbl->schema_select_lex && tbl->schema_select_lex->table_list.elements &&
lex->sql_command != SQLCOM_SHOW_KEYS)
{
/**
* Some statements e.g. EXPLAIN or SHOW COLUMNS give `information_schema`
* as the underlying table and the table in the query is stored in
* @c schema_select_lex.
*
* SHOW [KEYS | INDEX] does the reverse so we need to skip the
* @c schema_select_lex when processing a SHOW [KEYS | INDEX] statement.
*/
tbl = tbl->schema_select_lex->table_list.first;
}
return tbl;
}
/**
@ -1111,7 +1127,7 @@ char** qc_get_table_names(GWBUF* querybuf, int* tblsize, bool fullnames)
while (lex->current_select)
{
tbl = (TABLE_LIST*) skygw_get_affected_tables(lex);
tbl = skygw_get_affected_tables(lex);
while (tbl)
{
@ -1803,7 +1819,7 @@ char** qc_get_database_names(GWBUF* querybuf, int* size)
while (lex->current_select)
{
tbl = lex->current_select->table_list.first;
tbl = skygw_get_affected_tables(lex);
while (tbl)
{

View File

@ -1629,7 +1629,7 @@ void maxscaleExplain(Parse* pParse, SrcList* pName)
info->status = QC_QUERY_PARSED;
info->types = QUERY_TYPE_READ;
update_names(info, "information_schema", "COLUMNS");
update_names(info, pName->a[0].zDatabase, pName->a[0].zName);
append_affected_field(info,
"COLUMN_DEFAULT COLUMN_KEY COLUMN_NAME "
"COLUMN_TYPE EXTRA IS_NULLABLE");
@ -2191,7 +2191,7 @@ extern void maxscaleShow(Parse* pParse, MxsShow* pShow)
case MXS_SHOW_COLUMNS:
{
info->types = QUERY_TYPE_READ;
update_names(info, "information_schema", "COLUMNS");
update_names(info, zDatabase, zName);
if (pShow->data == MXS_SHOW_COLUMNS_FULL)
{
append_affected_field(info,

View File

@ -3010,13 +3010,17 @@ like_or_where_opt ::= WHERE expr.
%type show {MxsShow}
show(A) ::= SHOW full_opt(X) COLUMNS from_or_in nm(Y) dbnm(Z) from_or_in_db_opt like_or_where_opt . {
show(A) ::= SHOW full_opt(X) COLUMNS from_or_in nm(Y) dbnm(Z) from_or_in_db_opt(W) like_or_where_opt . {
A.what = MXS_SHOW_COLUMNS;
A.data = X;
if (Z.z) {
A.pName = &Z;
A.pDatabase = &Y;
}
else if (W.z) {
A.pName = &Y;
A.pDatabase = &W;
}
else {
A.pName = &Y;
A.pDatabase = NULL;