mirror of
https://github.com/MariaDB/server.git
synced 2025-01-16 12:02:42 +01:00
total table list managment is changed
This commit is contained in:
parent
0e29107fa1
commit
4cb3760b44
5 changed files with 95 additions and 68 deletions
|
@ -996,3 +996,79 @@ void st_select_lex_node::exclude()
|
|||
master->slave= next;
|
||||
*/
|
||||
}
|
||||
|
||||
/*
|
||||
This is used for UNION & subselect to create a new table list of all used
|
||||
tables.
|
||||
The table_list->table entry in all used tables are set to point
|
||||
to the entries in this list.
|
||||
*/
|
||||
|
||||
// interface
|
||||
bool st_select_lex_unit::create_total_list(THD *thd, st_lex *lex,
|
||||
TABLE_LIST **result)
|
||||
{
|
||||
*result= 0;
|
||||
return create_total_list_n_last_return(thd, lex, &result);
|
||||
}
|
||||
|
||||
// list creator
|
||||
bool st_select_lex_unit::create_total_list_n_last_return(THD *thd, st_lex *lex,
|
||||
TABLE_LIST ***result)
|
||||
{
|
||||
TABLE_LIST *slave_list_first=0, **slave_list_last= &slave_list_first;
|
||||
TABLE_LIST **new_table_list= *result, *aux;
|
||||
SELECT_LEX *sl= (SELECT_LEX*)slave;
|
||||
for (; sl; sl= (SELECT_LEX*)sl->next)
|
||||
{
|
||||
// check usage of ORDER BY in union
|
||||
if (sl->order_list.first && sl->next && !sl->braces)
|
||||
{
|
||||
net_printf(&thd->net,ER_WRONG_USAGE,"UNION","ORDER BY");
|
||||
return 1;
|
||||
}
|
||||
if (sl->slave)
|
||||
if (((SELECT_LEX_UNIT *)
|
||||
sl->slave)->create_total_list_n_last_return(thd, lex,
|
||||
&slave_list_last))
|
||||
return 1;
|
||||
if ((aux= (TABLE_LIST*) sl->table_list.first))
|
||||
{
|
||||
TABLE_LIST *next;
|
||||
for (; aux; aux= next)
|
||||
{
|
||||
TABLE_LIST *cursor;
|
||||
next= aux->next;
|
||||
for (cursor= **result; cursor; cursor= cursor->next)
|
||||
if (!strcmp(cursor->db, aux->db) &&
|
||||
!strcmp(cursor->real_name, aux->real_name) &&
|
||||
!strcmp(cursor->name, aux->name))
|
||||
break;
|
||||
if (!cursor)
|
||||
{
|
||||
/* Add not used table to the total table list */
|
||||
aux->lock_type= lex->lock_option;
|
||||
if (!(cursor= (TABLE_LIST *) thd->memdup((char*) aux,
|
||||
sizeof(*aux))))
|
||||
{
|
||||
send_error(&thd->net,0);
|
||||
return 1;
|
||||
}
|
||||
*new_table_list= cursor;
|
||||
new_table_list= &cursor->next;
|
||||
*new_table_list= 0; // end result list
|
||||
}
|
||||
else
|
||||
aux->shared= 1; // Mark that it's used twice
|
||||
aux->table_list= cursor;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (slave_list_first)
|
||||
{
|
||||
*new_table_list= slave_list_first;
|
||||
new_table_list= slave_list_last;
|
||||
}
|
||||
*result= new_table_list;
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -207,6 +207,7 @@ private:
|
|||
SELECT_LEX_UNIT - unit of selects (UNION, INTERSECT, ...) group
|
||||
SELECT_LEXs
|
||||
*/
|
||||
struct st_lex;
|
||||
struct st_select_lex_unit: public st_select_lex_node {
|
||||
/*
|
||||
Pointer to 'last' select or pointer to unit where stored
|
||||
|
@ -216,6 +217,10 @@ struct st_select_lex_unit: public st_select_lex_node {
|
|||
/* LIMIT clause runtime counters */
|
||||
ha_rows select_limit_cnt, offset_limit_cnt;
|
||||
void init_query();
|
||||
bool create_total_list(THD *thd, st_lex *lex, TABLE_LIST **result);
|
||||
private:
|
||||
bool create_total_list_n_last_return(THD *thd, st_lex *lex,
|
||||
TABLE_LIST ***result);
|
||||
};
|
||||
typedef struct st_select_lex_unit SELECT_LEX_UNIT;
|
||||
|
||||
|
|
|
@ -70,7 +70,6 @@ static void remove_escape(char *name);
|
|||
static void refresh_status(void);
|
||||
static bool append_file_to_dir(THD *thd, char **filename_ptr,
|
||||
char *table_name);
|
||||
static bool create_total_list(THD *thd, LEX *lex, TABLE_LIST **result);
|
||||
|
||||
const char *any_db="*any*"; // Special symbol for check_access
|
||||
|
||||
|
@ -1247,7 +1246,8 @@ mysql_execute_command(void)
|
|||
cursor))
|
||||
DBUG_VOID_RETURN;
|
||||
}
|
||||
if ((lex->select_lex.next && create_total_list(thd,lex,&tables)) ||
|
||||
if ((lex->select_lex.link_next &&
|
||||
lex->unit.create_total_list(thd, lex, &tables)) ||
|
||||
(table_rules_on && tables && thd->slave_thread &&
|
||||
!tables_ok(thd,tables)))
|
||||
DBUG_VOID_RETURN;
|
||||
|
@ -1942,7 +1942,7 @@ mysql_execute_command(void)
|
|||
goto error;
|
||||
}
|
||||
auxi->lock_type=walk->lock_type=TL_WRITE;
|
||||
auxi->table= (TABLE *) walk; // Remember corresponding table
|
||||
auxi->table_list= walk; // Remember corresponding table
|
||||
}
|
||||
tables->grant.want_privilege=(SELECT_ACL & ~tables->grant.privilege);
|
||||
if (add_item_to_list(new Item_null()))
|
||||
|
@ -1955,7 +1955,7 @@ mysql_execute_command(void)
|
|||
break;
|
||||
/* Fix tables-to-be-deleted-from list to point at opened tables */
|
||||
for (auxi=(TABLE_LIST*) aux_tables ; auxi ; auxi=auxi->next)
|
||||
auxi->table= ((TABLE_LIST*) auxi->table)->table;
|
||||
auxi->table= auxi->table_list->table;
|
||||
if (!thd->fatal_error && (result=new multi_delete(thd,aux_tables,
|
||||
lex->lock_option,table_count)))
|
||||
{
|
||||
|
@ -3193,68 +3193,6 @@ TABLE_LIST *add_table_to_list(Table_ident *table, LEX_STRING *alias,
|
|||
}
|
||||
|
||||
|
||||
/*
|
||||
** This is used for UNION to create a new table list of all used tables
|
||||
** The table_list->table entry in all used tables are set to point
|
||||
** to the entries in this list.
|
||||
*/
|
||||
|
||||
static bool create_total_list(THD *thd, LEX *lex, TABLE_LIST **result)
|
||||
{
|
||||
/* Handle the case when we are not using union */
|
||||
if (!lex->select_lex.next)
|
||||
{
|
||||
*result= (TABLE_LIST*) lex->select_lex.table_list.first;
|
||||
return 0;
|
||||
}
|
||||
|
||||
SELECT_LEX *sl;
|
||||
TABLE_LIST **new_table_list= result, *aux;
|
||||
|
||||
*new_table_list= 0; // end result list
|
||||
for (sl= &lex->select_lex; sl; sl= (SELECT_LEX *) sl->next)
|
||||
{
|
||||
if (sl->order_list.first && sl->next && !sl->braces)
|
||||
{
|
||||
net_printf(&thd->net,ER_WRONG_USAGE,"UNION","ORDER BY");
|
||||
return 1;
|
||||
}
|
||||
if ((aux= (TABLE_LIST*) sl->table_list.first))
|
||||
{
|
||||
TABLE_LIST *next;
|
||||
for (; aux; aux=next)
|
||||
{
|
||||
TABLE_LIST *cursor;
|
||||
next= aux->next;
|
||||
for (cursor= *result; cursor; cursor=cursor->next)
|
||||
if (!strcmp(cursor->db,aux->db) &&
|
||||
!strcmp(cursor->real_name,aux->real_name) &&
|
||||
!strcmp(cursor->name, aux->name))
|
||||
break;
|
||||
if (!cursor)
|
||||
{
|
||||
/* Add not used table to the total table list */
|
||||
aux->lock_type= lex->lock_option;
|
||||
if (!(cursor = (TABLE_LIST *) thd->memdup((char*) aux,
|
||||
sizeof(*aux))))
|
||||
{
|
||||
send_error(&thd->net,0);
|
||||
return 1;
|
||||
}
|
||||
*new_table_list= cursor;
|
||||
new_table_list= &cursor->next;
|
||||
*new_table_list=0; // end result list
|
||||
}
|
||||
else
|
||||
aux->shared=1; // Mark that it's used twice
|
||||
aux->table=(TABLE *) cursor;
|
||||
}
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
void add_join_on(TABLE_LIST *b,Item *expr)
|
||||
{
|
||||
if (!b->on_expr)
|
||||
|
|
|
@ -48,7 +48,7 @@ int mysql_union(THD *thd, LEX *lex,select_result *result)
|
|||
for (TABLE_LIST *cursor= (TABLE_LIST *)sl->table_list.first;
|
||||
cursor;
|
||||
cursor=cursor->next)
|
||||
cursor->table= ((TABLE_LIST*) cursor->table)->table;
|
||||
cursor->table= cursor->table_list->table;
|
||||
}
|
||||
|
||||
/* Global option */
|
||||
|
|
10
sql/table.h
10
sql/table.h
|
@ -143,7 +143,15 @@ typedef struct st_table_list {
|
|||
struct st_table_list *natural_join; /* natural join on this table*/
|
||||
/* ... join ... USE INDEX ... IGNORE INDEX */
|
||||
List<String> *use_index, *ignore_index;
|
||||
TABLE *table;
|
||||
/*
|
||||
Usually hold reference on opened table, but may hold reference
|
||||
to node of complete list of tables used in UNION & subselect.
|
||||
*/
|
||||
union
|
||||
{
|
||||
TABLE *table; /* opened table */
|
||||
st_table_list *table_list; /* pointer to node of list of all tables */
|
||||
};
|
||||
GRANT_INFO grant;
|
||||
thr_lock_type lock_type;
|
||||
uint outer_join; /* Which join type */
|
||||
|
|
Loading…
Reference in a new issue