1
0
mirror of https://github.com/MariaDB/server.git synced 2025-08-08 11:22:35 +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

@@ -46,10 +46,11 @@ static void unlink_blobs(register TABLE *table);
to timestamp field, depending on if timestamp should be updated or not.
*/
int
check_insert_fields(THD *thd,TABLE *table,List<Item> &fields,
List<Item> &values, ulong counter)
static int
check_insert_fields(THD *thd, TABLE_LIST *table_list, List<Item> &fields,
List<Item> &values, ulong counter, bool check_unique)
{
TABLE *table= table_list->table;
if (fields.elements == 0 && values.elements != 0)
{
if (values.elements != table->fields)
@@ -60,14 +61,21 @@ check_insert_fields(THD *thd,TABLE *table,List<Item> &fields,
return -1;
}
#ifndef NO_EMBEDDED_ACCESS_CHECKS
if (grant_option &&
check_grant_all_columns(thd,INSERT_ACL,table))
return -1;
{
Field_iterator_table fields;
fields.set_table(table);
if (grant_option &&
check_grant_all_columns(thd, INSERT_ACL, &table->grant,
table->table_cache_key, table->real_name,
&fields))
return -1;
}
#endif
table->timestamp_default_now= table->timestamp_on_update_now= 0;
}
else
{ // Part field list
TABLE_LIST *save_next= table_list->next_local;
if (fields.elements != values.elements)
{
my_printf_error(ER_WRONG_VALUE_COUNT_ON_ROW,
@@ -75,19 +83,17 @@ check_insert_fields(THD *thd,TABLE *table,List<Item> &fields,
MYF(0),counter);
return -1;
}
TABLE_LIST table_list;
bzero((char*) &table_list,sizeof(table_list));
table_list.db= table->table_cache_key;
table_list.real_name= table_list.alias= table->table_name;
table_list.table=table;
table_list.grant=table->grant;
table_list->next_local= 0;
thd->dupp_field=0;
if (setup_tables(&table_list) ||
setup_fields(thd, 0, &table_list,fields,1,0,0))
if (setup_fields(thd, 0, table_list, fields, 1, 0, 0))
{
table_list->next_local= save_next;
return -1;
}
table_list->next_local= save_next;
if (thd->dupp_field)
if (check_unique && thd->dupp_field)
{
my_error(ER_FIELD_SPECIFIED_TWICE,MYF(0), thd->dupp_field->field_name);
return -1;
@@ -130,8 +136,6 @@ int mysql_insert(THD *thd,TABLE_LIST *table_list,
char *query= thd->query;
#endif
thr_lock_type lock_type = table_list->lock_type;
TABLE_LIST *insert_table_list= (TABLE_LIST*)
thd->lex->select_lex.table_list.first;
DBUG_ENTER("mysql_insert");
/*
@@ -170,8 +174,14 @@ int mysql_insert(THD *thd,TABLE_LIST *table_list,
if ((table= delayed_get_table(thd,table_list)) && !thd->is_fatal_error)
{
res= 0;
if (table_list->next) /* if sub select */
res= open_and_lock_tables(thd, table_list->next);
if (table_list->next_global) /* if sub select */
res= open_and_lock_tables(thd, table_list->next_global);
/*
First is not processed by open_and_lock_tables() => we need set
updateability flags "by hands".
*/
if (!table_list->derived && !table_list->view)
table_list->updatable= 1; // usual table
}
else
{
@@ -194,17 +204,17 @@ int mysql_insert(THD *thd,TABLE_LIST *table_list,
if (duplic == DUP_UPDATE && !table->insert_values)
{
/* it should be allocated before Item::fix_fields() */
table->insert_values=
table->insert_values=
(byte *)alloc_root(&thd->mem_root, table->rec_buff_length);
if (!table->insert_values)
goto abort;
}
if (mysql_prepare_insert(thd, table_list, insert_table_list, table,
fields, values, update_fields,
update_values, duplic))
if (mysql_prepare_insert(thd, table_list, table, fields, values,
update_fields, update_values, duplic))
goto abort;
// is table which we are changing used somewhere in other parts of query
value_count= values->elements;
while ((values= its++))
{
@@ -216,7 +226,7 @@ int mysql_insert(THD *thd,TABLE_LIST *table_list,
MYF(0),counter);
goto abort;
}
if (setup_fields(thd, 0, insert_table_list, *values, 0, 0, 0))
if (setup_fields(thd, 0, table_list, *values, 0, 0, 0))
goto abort;
}
its.rewind ();
@@ -427,34 +437,122 @@ abort:
}
/*
Additional check for insertability for VIEW
SYNOPSIS
check_view_insertability()
view - reference on VIEW
RETURN
FALSE - OK
TRUE - can't be used for insert
*/
static bool check_view_insertability(TABLE_LIST *view, ulong query_id)
{
DBUG_ENTER("check_key_in_view");
TABLE *table= view->table;
Item **trans= view->field_translation;
Field **field_ptr= table->field;
uint num= view->view->select_lex.item_list.elements;
ulong other_query_id= query_id - 1;
DBUG_ASSERT(view->table != 0 && view->field_translation != 0);
view->contain_auto_increment= 0;
/* check simplicity and prepare unique test of view */
for (uint i= 0; i < num; i++)
{
/* simple SELECT list entry (field without expression) */
if (trans[i]->type() != Item::FIELD_ITEM)
DBUG_RETURN(TRUE);
if (((Item_field *)trans[i])->field->type() == Field::NEXT_NUMBER)
view->contain_auto_increment= 1;
/* prepare unique test */
((Item_field *)trans[i])->field->query_id= other_query_id;
}
/* unique test */
for (uint i= 0; i < num; i++)
{
Item_field *field= (Item_field *)trans[i];
if (field->field->query_id == query_id)
DBUG_RETURN(TRUE);
field->field->query_id= query_id;
}
/* VIEW contain all fields without default value */
for (; *field_ptr; ++field_ptr)
{
Field *field= *field_ptr;
/* field have not default value */
if ((field->type() == FIELD_TYPE_BLOB) &&
(table->timestamp_field != field ||
field->unireg_check == Field::TIMESTAMP_UN_FIELD))
{
uint i= 0;
for (; i < num; i++)
{
if (((Item_field *)trans[i])->field == *field_ptr)
break;
}
if (i >= num)
DBUG_RETURN(TRUE);
}
}
DBUG_RETURN(FALSE);
}
/*
Prepare items in INSERT statement
SYNOPSIS
mysql_prepare_insert()
thd - thread handler
table_list - global table list
insert_table_list - local table list of INSERT SELECT_LEX
table_list - global/local table list
RETURN VALUE
0 - OK
-1 - error (message is not sent to user)
*/
int mysql_prepare_insert(THD *thd, TABLE_LIST *table_list,
TABLE_LIST *insert_table_list, TABLE *table,
int mysql_prepare_insert(THD *thd, TABLE_LIST *table_list, TABLE *table,
List<Item> &fields, List_item *values,
List<Item> &update_fields, List<Item> &update_values,
enum_duplicates duplic)
{
bool insert_into_view= (table_list->view != 0);
DBUG_ENTER("mysql_prepare_insert");
if (check_insert_fields(thd, table, fields, *values, 1) ||
setup_tables(insert_table_list) ||
setup_fields(thd, 0, insert_table_list, *values, 0, 0, 0) ||
(duplic == DUP_UPDATE &&
(setup_fields(thd, 0, insert_table_list, update_fields, 0, 0, 0) ||
setup_fields(thd, 0, insert_table_list, update_values, 0, 0, 0))))
/* TODO: use this condition for 'WHITH CHECK OPTION' */
Item *unused_conds= 0;
if (setup_tables(thd, table_list, &unused_conds))
DBUG_RETURN(-1);
if (find_real_table_in_list(table_list->next,
if (insert_into_view && !fields.elements)
{
thd->lex->empty_field_list_on_rset= 1;
insert_view_fields(&fields, table_list);
}
if (!table_list->updatable ||
check_key_in_view(thd, table_list) ||
(insert_into_view &&
check_view_insertability(table_list, thd->query_id)))
{
my_error(ER_NON_UPDATABLE_TABLE, MYF(0), table_list->alias, "INSERT");
DBUG_RETURN(-1);
}
if (check_insert_fields(thd, table_list, fields, *values, 1,
!insert_into_view) ||
setup_fields(thd, 0, table_list, *values, 0, 0, 0) ||
(duplic == DUP_UPDATE &&
(setup_fields(thd, 0, table_list, update_fields, 0, 0, 0) ||
setup_fields(thd, 0, table_list, update_values, 0, 0, 0))))
DBUG_RETURN(-1);
if (find_real_table_in_list(table_list->next_global,
table_list->db, table_list->real_name))
{
my_error(ER_UPDATE_TABLE_USED, MYF(0), table_list->real_name);
@@ -1440,13 +1538,55 @@ bool delayed_insert::handle_inserts(void)
Store records in INSERT ... SELECT *
***************************************************************************/
/*
make insert specific preparation and checks after opening tables
SYNOPSIS
mysql_insert_select_prepare()
thd thread handler
RETURN
0 OK
-1 Error
*/
int mysql_insert_select_prepare(THD *thd)
{
LEX *lex= thd->lex;
TABLE_LIST *table_list= lex->query_tables;
bool insert_into_view= (table_list->view != 0);
DBUG_ENTER("mysql_insert_select_prepare");
if (setup_tables(thd, table_list, &lex->select_lex.where))
DBUG_RETURN(-1);
if (insert_into_view && !lex->field_list.elements)
{
lex->empty_field_list_on_rset= 1;
insert_view_fields(&lex->field_list, table_list);
}
if (!table_list->updatable ||
check_key_in_view(thd, table_list) ||
(insert_into_view &&
check_view_insertability(table_list, thd->query_id)))
{
my_error(ER_NON_UPDATABLE_TABLE, MYF(0), table_list->alias, "INSERT");
DBUG_RETURN(-1);
}
DBUG_RETURN(0)
}
int
select_insert::prepare(List<Item> &values, SELECT_LEX_UNIT *u)
{
DBUG_ENTER("select_insert::prepare");
unit= u;
if (check_insert_fields(thd,table,*fields,values,1))
if (check_insert_fields(thd, table_list, *fields, values, 1,
!insert_into_view))
DBUG_RETURN(1);
restore_record(table,default_values); // Get empty record
@@ -1603,7 +1743,7 @@ select_create::prepare(List<Item> &values, SELECT_LEX_UNIT *u)
DBUG_ENTER("select_create::prepare");
unit= u;
table= create_table_from_items(thd, create_info, db, name,
table= create_table_from_items(thd, create_info, create_table,
extra_fields, keys, &values, &lock);
if (!table)
DBUG_RETURN(-1); // abort() deletes table
@@ -1694,7 +1834,7 @@ void select_create::abort()
if (!table->tmp_table)
hash_delete(&open_cache,(byte*) table);
if (!create_info->table_existed)
quick_rm_table(table_type,db,name);
quick_rm_table(table_type, create_table->db, create_table->real_name);
table=0;
}
VOID(pthread_mutex_unlock(&LOCK_open));