1
0
mirror of https://github.com/MariaDB/server.git synced 2025-07-30 16:24:05 +03:00
two TABLE_LIST copy eliminated


include/mysqld_error.h:
  errors of view
libmysqld/Makefile.am:
  new view file
mysql-test/r/connect.result:
  SHOW TABLE show type of table
mysql-test/r/ctype_recoding.result:
  SHOW TABLE show type of table
mysql-test/r/drop.result:
  SHOW TABLE show type of table
mysql-test/r/grant.result:
  new two privileges (CRETEA|SHOW VIEW)
mysql-test/r/lowercase_table.result:
  SHOW TABLE show type of table
mysql-test/r/ps_1general.result:
  SHOW TABLE show type of table
mysql-test/r/rename.result:
  SHOW TABLE show type of table
mysql-test/r/rpl000009.result:
  SHOW TABLE show type of table
mysql-test/r/rpl_error_ignored_table.result:
  SHOW TABLE show type of table
mysql-test/r/select.result:
  SHOW TABLE show type of table
mysql-test/r/system_mysql_db.result:
  SHOW TABLE show type of table
  new two privileges (CRETEA|SHOW VIEW)
mysql-test/t/system_mysql_db_fix.test:
  removing all system tables
scripts/mysql_fix_privilege_tables.sql:
  new two privileges (CRETEA|SHOW VIEW)
sql/Makefile.am:
  new VIEW related file
sql/ha_myisammrg.cc:
  two TABLE_LIST copy eliminated
sql/item.cc:
  VIEW
sql/item.h:
  VIEW
sql/item_subselect.cc:
  VIEW
sql/item_subselect.h:
  VIEW
sql/lex.h:
  VIEW
sql/lock.cc:
  VIEW
sql/mysql_priv.h:
  VIEW
sql/mysqld.cc:
  VIEW
  new parameter - sql_updatable_view_key
sql/opt_sum.cc:
  two TABLE_LIST copy eliminated
sql/set_var.cc:
  new parameter - sql_updatable_view_key
sql/share/czech/errmsg.txt:
  errors messages of views
sql/share/danish/errmsg.txt:
  errors messages of views
sql/share/dutch/errmsg.txt:
  errors messages of views
sql/share/english/errmsg.txt:
  errors messages of views
sql/share/estonian/errmsg.txt:
  errors messages of views
sql/share/french/errmsg.txt:
  errors messages of views
sql/share/german/errmsg.txt:
  errors messages of views
sql/share/greek/errmsg.txt:
  errors messages of views
sql/share/hungarian/errmsg.txt:
  errors messages of views
sql/share/italian/errmsg.txt:
  errors messages of views
sql/share/japanese/errmsg.txt:
  errors messages of views
sql/share/korean/errmsg.txt:
  errors messages of views
sql/share/norwegian-ny/errmsg.txt:
  errors messages of views
sql/share/norwegian/errmsg.txt:
  errors messages of views
sql/share/polish/errmsg.txt:
  errors messages of views
sql/share/portuguese/errmsg.txt:
  errors messages of views
sql/share/romanian/errmsg.txt:
  errors messages of views
sql/share/russian/errmsg.txt:
  errors messages of views
sql/share/serbian/errmsg.txt:
  errors messages of views
sql/share/slovak/errmsg.txt:
  errors messages of views
sql/share/spanish/errmsg.txt:
  errors messages of views
sql/share/swedish/errmsg.txt:
  errors messages of views
sql/share/ukrainian/errmsg.txt:
  errors messages of views
sql/slave.cc:
  two TABLE_LIST copy eliminated
sql/sp.cc:
  VIEW
sql/sql_acl.cc:
  VIEW
sql/sql_acl.h:
  VIEW
sql/sql_base.cc:
  VIEW
sql/sql_cache.cc:
  two TABLE_LIST copy eliminated
sql/sql_class.h:
  VIEW
sql/sql_db.cc:
  two TABLE_LIST copy eliminated
sql/sql_delete.cc:
  VIEW
sql/sql_derived.cc:
  VIEW
sql/sql_handler.cc:
  two TABLE_LIST copy eliminated
sql/sql_help.cc:
  two TABLE_LIST copy eliminated
sql/sql_insert.cc:
  VIEW
sql/sql_lex.cc:
  VIEW
sql/sql_lex.h:
  VIEW
sql/sql_load.cc:
  VIEW
sql/sql_olap.cc:
  VIEW
sql/sql_parse.cc:
  two TABLE_LIST copy eliminated
  VIEW
sql/sql_prepare.cc:
  VIEW
sql/sql_rename.cc:
  two TABLE_LIST copy eliminated
sql/sql_select.cc:
  VIEW
sql/sql_show.cc:
  VIEW
sql/sql_table.cc:
  VIEW
sql/sql_union.cc:
  VIEW
sql/sql_update.cc:
  VIEW
sql/sql_yacc.yy:
  VIEW
sql/table.cc:
  VIEW
sql/table.h:
  VIEW
sql/tztime.cc:
  two TABLE_LIST copy eliminated
sql/unireg.h:
  VIEW
tests/client_test.c:
  VIEW
This commit is contained in:
unknown
2004-07-16 01:15:55 +03:00
parent b0df20349d
commit 8790b1e65c
85 changed files with 6126 additions and 1250 deletions

View File

@ -995,7 +995,7 @@ void st_select_lex::init_query()
embedding= 0;
item_list.empty();
join= 0;
where= 0;
where= prep_where= 0;
olap= UNSPECIFIED_OLAP_TYPE;
having_fix_field= 0;
resolve_mode= NOMATTER_MODE;
@ -1003,7 +1003,6 @@ void st_select_lex::init_query()
conds_processed_with_permanent_arena= 0;
ref_pointer_array= 0;
select_n_having_items= 0;
prep_where= 0;
subquery_in_having= explicit_limit= 0;
first_execution= 1;
first_cond_optimization= 1;
@ -1269,122 +1268,6 @@ bool st_select_lex::test_limit()
return(0);
}
/*
Interface method of table list creation for query
SYNOPSIS
st_select_lex_unit::create_total_list()
thd THD pointer
result pointer on result list of tables pointer
check_derived force derived table chacking (used for creating
table list for derived query)
DESCRIPTION
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.
RETURN
0 - OK
!0 - error
*/
bool st_select_lex_unit::create_total_list(THD *thd_arg, st_lex *lex,
TABLE_LIST **result_arg)
{
*result_arg= 0;
res= create_total_list_n_last_return(thd_arg, lex, &result_arg);
return res;
}
/*
Table list creation for query
SYNOPSIS
st_select_lex_unit::create_total_list()
thd THD pointer
lex pointer on LEX stricture
result pointer on pointer on result list of tables pointer
DESCRIPTION
This is used for UNION & subselect to create a new table list of all used
tables.
The table_list->table_list in all tables of global list are set to point
to the local SELECT_LEX entries.
RETURN
0 - OK
!0 - error
*/
bool st_select_lex_unit::
create_total_list_n_last_return(THD *thd_arg,
st_lex *lex,
TABLE_LIST ***result_arg)
{
TABLE_LIST *slave_list_first=0, **slave_list_last= &slave_list_first;
TABLE_LIST **new_table_list= *result_arg, *aux;
SELECT_LEX *sl= (SELECT_LEX*)slave;
/*
iterate all inner selects + fake_select (if exists),
fake_select->next_select() always is 0
*/
for (;
sl;
sl= (sl->next_select() ?
sl->next_select() :
(sl == fake_select_lex ?
0 :
fake_select_lex)))
{
// check usage of ORDER BY in union
if (sl->order_list.first && sl->next_select() && !sl->braces &&
sl->linkage != GLOBAL_OPTIONS_TYPE)
{
net_printf(thd_arg,ER_WRONG_USAGE,"UNION","ORDER BY");
return 1;
}
for (SELECT_LEX_UNIT *inner= sl->first_inner_unit();
inner;
inner= inner->next_unit())
{
if (inner->create_total_list_n_last_return(thd, lex,
&slave_list_last))
return 1;
}
if ((aux= (TABLE_LIST*) sl->table_list.first))
{
TABLE_LIST *next_table;
for (; aux; aux= next_table)
{
TABLE_LIST *cursor;
next_table= aux->next;
/* Add to the total table list */
if (!(cursor= (TABLE_LIST *) thd->memdup((char*) aux,
sizeof(*aux))))
{
send_error(thd,0);
return 1;
}
*new_table_list= cursor;
cursor->table_list= aux;
new_table_list= &cursor->next;
*new_table_list= 0; // end result list
aux->table_list= cursor;
}
}
}
if (slave_list_first)
{
*new_table_list= slave_list_first;
new_table_list= slave_list_last;
}
*result_arg= new_table_list;
return 0;
}
st_select_lex_unit* st_select_lex_unit::master_unit()
{
@ -1539,7 +1422,7 @@ bool st_select_lex_unit::check_updateable(char *db, char *table)
*/
bool st_select_lex::check_updateable(char *db, char *table)
{
if (find_real_table_in_list(get_table_list(), db, table))
if (find_real_table_in_local_list(get_table_list(), db, table))
return 1;
for (SELECT_LEX_UNIT *un= first_inner_unit();
@ -1599,6 +1482,16 @@ void st_select_lex::print_order(String *str, ORDER *order)
void st_select_lex::print_limit(THD *thd, String *str)
{
Item_subselect *item= master_unit()->item;
if (item &&
(item->substype() == Item_subselect::EXISTS_SUBS ||
item->substype() == Item_subselect::IN_SUBS ||
item->substype() == Item_subselect::ALL_SUBS))
{
DBUG_ASSERT(select_limit == 1L && offset_limit == 0L);
return;
}
if (!thd)
thd= current_thd;
@ -1619,6 +1512,98 @@ void st_select_lex::print_limit(THD *thd, String *str)
}
}
/*
Check is merging algorithm can be used on this VIEW
SYNOPSIS
st_lex::can_be_merged()
RETURN
FALSE - only temporary table algorithm can be used
TRUE - merge algorithm can be used
*/
bool st_lex::can_be_merged()
{
// TODO: do not forget implement case when select_lex.table_list.elements==0
/* find non VIEW subqueries/unions */
uint selects= 0;
for (SELECT_LEX *sl= all_selects_list;
sl && selects <= 1;
sl= sl->next_select_in_list())
if (sl->parent_lex == this)
selects++;
return (selects <= 1 &&
select_lex.order_list.elements == 0 &&
select_lex.group_list.elements == 0 &&
select_lex.having == 0 &&
select_lex.table_list.elements == 1 &&
!(select_lex.options & SELECT_DISTINCT) &&
select_lex.select_limit == HA_POS_ERROR);
}
/*
check if command can use VIEW with MERGE algorithm
SYNOPSIS
st_lex::can_use_merged()
RETURN
FALSE - command can't use merged VIEWs
TRUE - VIEWs with MERGE algorithms can be used
*/
bool st_lex::can_use_merged()
{
switch (sql_command)
{
case SQLCOM_SELECT:
case SQLCOM_CREATE_TABLE:
case SQLCOM_UPDATE:
case SQLCOM_UPDATE_MULTI:
case SQLCOM_DELETE:
case SQLCOM_DELETE_MULTI:
case SQLCOM_INSERT:
case SQLCOM_INSERT_SELECT:
case SQLCOM_REPLACE:
case SQLCOM_REPLACE_SELECT:
return TRUE;
default:
return FALSE;
}
}
/*
Detect that we need only table structure of derived table/view
SYNOPSIS
only_view_structure()
RETURN
TRUE yes, we need only structure
FALSE no, we need data
*/
bool st_lex::only_view_structure()
{
switch(sql_command)
{
case SQLCOM_SHOW_CREATE:
case SQLCOM_SHOW_TABLES:
case SQLCOM_SHOW_FIELDS:
case SQLCOM_REVOKE_ALL:
case SQLCOM_REVOKE:
case SQLCOM_GRANT:
case SQLCOM_CREATE_VIEW:
return TRUE;
default:
return FALSE;
}
}
/*
initialize limit counters
@ -1627,6 +1612,7 @@ void st_select_lex::print_limit(THD *thd, String *str)
values - SELECT_LEX with initial values for counters
sl - SELECT_LEX for options set
*/
void st_select_lex_unit::set_limit(SELECT_LEX *values,
SELECT_LEX *sl)
{
@ -1645,35 +1631,83 @@ void st_select_lex_unit::set_limit(SELECT_LEX *values,
SYNOPSIS
unlink_first_table()
tables Global table list
global_first Save first global table here
local_first Save first local table here
link_to_local do we need link this table to local
NORES
global_first & local_first are used to save result for link_first_table_back
NOTES
We rely on fact that first table in both list are same or local list
is empty
RETURN
global list without first table
unlinked table
*/
TABLE_LIST *st_lex::unlink_first_table(TABLE_LIST *tables,
TABLE_LIST **global_first,
TABLE_LIST **local_first)
TABLE_LIST *st_lex::unlink_first_table(bool *link_to_local)
{
*global_first= tables;
*local_first= (TABLE_LIST*)select_lex.table_list.first;
/*
Exclude from global table list
*/
tables= tables->next;
/*
and from local list if it is not the same
*/
select_lex.table_list.first= ((&select_lex != all_selects_list) ?
(byte*) (*local_first)->next :
(byte*) tables);
(*global_first)->next= 0;
return tables;
TABLE_LIST *first;
if ((first= query_tables))
{
/*
Exclude from global table list
*/
if ((query_tables= query_tables->next_global))
query_tables->prev_global= &query_tables;
first->next_global= 0;
/*
and from local list if it is not empty
*/
if ((*link_to_local= test(select_lex.table_list.first)))
{
select_lex.table_list.first= (byte*) first->next_local;
select_lex.table_list.elements--; //safety
first->next_local= 0;
/*
reorder global list to keep first tables the same in both lists
(if it is need)
*/
first_lists_tables_same();
}
}
return first;
}
/*
Bring first local table of first most outer select to first place in global
table list
SYNOPSYS
st_lex::first_lists_tables_same()
NOTES
In many cases first table of main SELECT_LEX have special meaning =>
check that it is first table in global list and relink it first in
queries_tables list if it is necessary (we need such relinking only
for queries with subqueries in select list, in this case tables of
subqueries will go to global list first)
*/
void st_lex::first_lists_tables_same()
{
TABLE_LIST *first_table= (TABLE_LIST*) select_lex.table_list.first;
if (query_tables != first_table && first_table != 0)
{
if (query_tables_last == &first_table->next_global)
query_tables_last= first_table->prev_global;
TABLE_LIST *next= *first_table->prev_global= first_table->next_global;
first_table->next_global= 0;
if (next)
next->prev_global= first_table->prev_global;
/* include in new place */
first_table->next_global= query_tables;
/*
we are sure that above is not 0, because first_table was not
first table in global list => we can do following without check
*/
query_tables->prev_global= &first_table->next_global;
first_table->prev_global= &query_tables;
query_tables= first_table;
}
}
@ -1682,36 +1716,54 @@ TABLE_LIST *st_lex::unlink_first_table(TABLE_LIST *tables,
SYNOPSIS
link_first_table_back()
tables Global table list
global_first Saved first global table
local_first Saved first local table
link_to_local do we need link this table to local
RETURN
global list
*/
TABLE_LIST *st_lex::link_first_table_back(TABLE_LIST *tables,
TABLE_LIST *global_first,
TABLE_LIST *local_first)
void st_lex::link_first_table_back(TABLE_LIST *first,
bool link_to_local)
{
global_first->next= tables;
if (&select_lex != all_selects_list)
if (first)
{
/*
we do not touch local table 'next' field => we need just
put the table in the list
*/
select_lex.table_list.first= (byte*) local_first;
if ((first->next_global= query_tables))
query_tables->prev_global= &first->next_global;
query_tables= first;
if (link_to_local)
{
first->next_local= (TABLE_LIST*) select_lex.table_list.first;
select_lex.table_list.first= (byte*) first;
select_lex.table_list.elements++; //safety
}
}
}
/*
fix some structures at the end of preparation
SYNOPSIS
st_select_lex::fix_prepare_information
thd thread handler
conds pointer on conditions which will be used for execution statement
*/
void st_select_lex::fix_prepare_information(THD *thd, Item **conds)
{
if (thd->current_arena && first_execution)
{
prep_where= where;
first_execution= 0;
}
else
select_lex.table_list.first= (byte*) global_first;
return global_first;
}
/*
There are st_select_lex::add_table_to_list &
There are st_select_lex::add_table_to_list &
st_select_lex::set_lock_for_tables are in sql_parse.cc
st_select_lex::print is in sql_select.h
st_select_lex::print is in sql_select.cc
st_select_lex_unit::prepare, st_select_lex_unit::exec,
st_select_lex_unit::cleanup, st_select_lex_unit::reinit_exec_mechanism,