1
0
mirror of https://github.com/MariaDB/server.git synced 2025-07-29 05:21:33 +03:00

Cleanup of new code pushed into 5.0 since last pull

Merged the different find_xxxx_table_in_list functions to one + some inline functions


mysql-test/r/view.result:
  Fix result (remove not used view from show tables)
sql/item_subselect.cc:
  Remove not used functions
sql/item_subselect.h:
  Remove not used functions
sql/mysql_priv.h:
  Merged the different find_xxxx_table_in_list functions to one + some inline functions
sql/sql_acl.cc:
  More debugging + simple cleanups
sql/sql_base.cc:
  Merged the different find_xxxx_table_in_list functions to one + some inline functions
  Indentation cleanups & more comments
sql/sql_delete.cc:
  Namechange
sql/sql_insert.cc:
  Simple optimizations & Style cleanups
  Merged common code (in mysql_prepare_insert_check_table)
sql/sql_lex.cc:
  function name changes
  More comments
sql/sql_parse.cc:
  Function name changes
  Made check_one_table_access returning bool
  More debugging in 'check_access'
  Added function 'check_some_access', which is used when creating a view
sql/sql_prepare.cc:
  Resetting flag directly after test makes code easier to read
sql/sql_select.cc:
  Code simplifications
sql/sql_show.cc:
  Indentation cleanups.
  Fixed typo in name
sql/sql_update.cc:
  Function name change
sql/sql_view.cc:
  Simple optimizations.
  Style fixes.
  Remove view_field_names[]
  Simplified 'check_key_in_view()'
sql/table.cc:
  Simplified new code in openfrm()
  variable name change i -> item
  Indentation changes
sql/table.h:
  Fixed typo in variable name
  Method name change in field iterator: end() -> end_of_fields()
tests/client_test.c:
  Changed number to macro
This commit is contained in:
unknown
2004-09-03 21:43:04 +03:00
parent 10d0dca6b4
commit d0211cf5be
18 changed files with 491 additions and 458 deletions

View File

@ -79,25 +79,8 @@ int mysql_create_view(THD *thd,
/*
Ensure that we have some privilage on this table, more strict check
will be done on column level after preparation,
SELECT_ACL will be checked for sure for all fields because it is
listed first (if we have not rights to SELECT from whole table this
right will be written as tbl->grant.want_privilege and will be checked
later (except fields which need any privilege and can be updated).
*/
if ((check_access(thd, SELECT_ACL, tbl->db,
&tbl->grant.privilege, 0, 1) ||
grant_option && check_grant(thd, SELECT_ACL, tbl, 0, 1, 1)) &&
(check_access(thd, INSERT_ACL, tbl->db,
&tbl->grant.privilege, 0, 1) ||
grant_option && check_grant(thd, INSERT_ACL, tbl, 0, 1, 1)) &&
(check_access(thd, DELETE_ACL, tbl->db,
&tbl->grant.privilege, 0, 1) ||
grant_option && check_grant(thd, DELETE_ACL, tbl, 0, 1, 1)) &&
(check_access(thd, UPDATE_ACL, tbl->db,
&tbl->grant.privilege, 0, 1) ||
grant_option && check_grant(thd, UPDATE_ACL, tbl, 0, 1, 1))
)
if (check_some_access(thd, VIEW_ANY_ACL, tbl))
{
my_printf_error(ER_TABLEACCESS_DENIED_ERROR,
ER(ER_TABLEACCESS_DENIED_ERROR),
@ -113,7 +96,7 @@ int mysql_create_view(THD *thd,
/*
We need to check only SELECT_ACL for all normal fields, fields
where we need any privilege will be pmarked later
where we need any privilege will be marked later
*/
tbl->grant.want_privilege= SELECT_ACL;
/*
@ -166,7 +149,7 @@ int mysql_create_view(THD *thd,
/* check that tables are not temporary */
for (tbl= tables; tbl; tbl= tbl->next_global)
{
if (tbl->table->tmp_table != NO_TMP_TABLE && !test(tbl->view))
if (tbl->table->tmp_table != NO_TMP_TABLE && !tbl->view)
{
my_error(ER_VIEW_SELECT_TMPTABLE, MYF(0), tbl->alias);
res= -1;
@ -189,19 +172,18 @@ int mysql_create_view(THD *thd,
/* view list (list of view fields names) */
if (lex->view_list.elements)
{
List_iterator_fast<Item> it(select_lex->item_list);
List_iterator_fast<LEX_STRING> nm(lex->view_list);
Item *item;
LEX_STRING *name;
if (lex->view_list.elements != select_lex->item_list.elements)
{
my_message(ER_VIEW_WRONG_LIST, ER(ER_VIEW_WRONG_LIST), MYF(0));
goto err;
}
List_iterator_fast<Item> it(select_lex->item_list);
List_iterator_fast<LEX_STRING> nm(lex->view_list);
Item *item;
LEX_STRING *name;
while((item= it++, name= nm++))
{
while ((item= it++, name= nm++))
item->set_name(name->str, name->length, system_charset_info);
}
}
#ifndef NO_EMBEDDED_ACCESS_CHECKS
@ -214,7 +196,7 @@ int mysql_create_view(THD *thd,
Item *item;
fill_effective_table_privileges(thd, &view->grant, db,
view->real_name);
while((item= it++))
while ((item= it++))
{
uint priv= (get_column_grant(thd, &view->grant, db,
view->real_name, item->name) &
@ -223,10 +205,10 @@ int mysql_create_view(THD *thd,
{
Item_field *fld= (Item_field *)item;
/*
There are no any privileges on VIWE column or there are
There are no any privileges on VIEW column or there are
some other privileges then we have for underlaying table
*/
if (priv == 0 || test(~fld->have_privileges & priv))
if (priv == 0 || (~fld->have_privileges & priv))
{
/* VIEW column has more privileges */
my_printf_error(ER_COLUMNACCESS_DENIED_ERROR,
@ -242,7 +224,7 @@ int mysql_create_view(THD *thd,
}
else
{
if (!test(priv & SELECT_ACL))
if (!(priv & SELECT_ACL))
{
/* user have not privilege to SELECT expression */
my_printf_error(ER_COLUMNACCESS_DENIED_ERROR,
@ -266,14 +248,11 @@ int mysql_create_view(THD *thd,
goto err;
}
VOID(pthread_mutex_lock(&LOCK_open));
if ((res= mysql_register_view(thd, view, mode)))
{
VOID(pthread_mutex_unlock(&LOCK_open));
start_waiting_global_read_lock(thd);
goto err;
}
res= mysql_register_view(thd, view, mode);
VOID(pthread_mutex_unlock(&LOCK_open));
start_waiting_global_read_lock(thd);
if (res)
goto err;
send_ok(thd);
lex->link_first_table_back(view, link_to_local);
@ -292,40 +271,36 @@ err:
// index of revision number in following table
static const int revision_number_position= 4;
static char *view_field_names[]=
{
(char*)"query",
(char*)"md5",
(char*)"updatable",
(char*)"algorithm",
(char*)"revision",
(char*)"timestamp",
(char*)"create-version",
(char*)"source"
};
/*
table of VIEW .frm field descriptors
Note that one should NOT change the order for this, as it's used by
parse()
*/
// table of VIEW .frm field descriprors
static File_option view_parameters[]=
{{{view_field_names[0], 5}, offsetof(TABLE_LIST, query),
{{{(char*) "query", 5}, offsetof(TABLE_LIST, query),
FILE_OPTIONS_STRING},
{{view_field_names[1], 3}, offsetof(TABLE_LIST, md5),
{{(char*) "md5", 3}, offsetof(TABLE_LIST, md5),
FILE_OPTIONS_STRING},
{{view_field_names[2], 9}, offsetof(TABLE_LIST, updatable),
{{(char*) "updatable", 9}, offsetof(TABLE_LIST, updatable),
FILE_OPTIONS_ULONGLONG},
{{view_field_names[3], 9}, offsetof(TABLE_LIST, algorithm),
{{(char*) "algorithm", 9}, offsetof(TABLE_LIST, algorithm),
FILE_OPTIONS_ULONGLONG},
{{view_field_names[4], 8}, offsetof(TABLE_LIST, revision),
{{(char*) "revision", 8}, offsetof(TABLE_LIST, revision),
FILE_OPTIONS_REV},
{{view_field_names[5], 9}, offsetof(TABLE_LIST, timestamp),
{{(char*) "timestamp", 9}, offsetof(TABLE_LIST, timestamp),
FILE_OPTIONS_TIMESTAMP},
{{view_field_names[6], 14}, offsetof(TABLE_LIST, file_version),
{{(char*)"create-version", 14},offsetof(TABLE_LIST, file_version),
FILE_OPTIONS_ULONGLONG},
{{view_field_names[7], 6}, offsetof(TABLE_LIST, source),
{{(char*) "source", 6}, offsetof(TABLE_LIST, source),
FILE_OPTIONS_ESTRING},
{{NULL, 0}, 0,
FILE_OPTIONS_STRING}
};
static const uint required_view_parameters= 6;
static LEX_STRING view_file_type[]= {{(char*)"VIEW", 4}};
@ -368,16 +343,18 @@ static int mysql_register_view(THD *thd, TABLE_LIST *view,
dir.length= strlen(dir_buff);
file.str= file_buff;
file.length= my_snprintf(file_buff, FN_REFLEN, "%s%s",
view->real_name, reg_ext);
file.length= (strxnmov(file_buff, FN_REFLEN, view->real_name, reg_ext,
NullS) - file_buff);
/* init timestamp */
if (!test(view->timestamp.str))
if (!view->timestamp.str)
view->timestamp.str= view->timestamp_buffer;
// check old .frm
{
char path_buff[FN_REFLEN];
LEX_STRING path;
File_parser *parser;
path.str= path_buff;
fn_format(path_buff, file.str, dir.str, 0, MY_UNPACK_FILENAME);
path.length= strlen(path_buff);
@ -390,34 +367,27 @@ static int mysql_register_view(THD *thd, TABLE_LIST *view,
DBUG_RETURN(1);
}
File_parser *parser= sql_parse_prepare(&path, &thd->mem_root, 0);
if (parser)
{
if(parser->ok() &&
!strncmp("VIEW", parser->type()->str, parser->type()->length))
{
/*
read revision number
TODO: read dependense list, too, to process cascade/restrict
TODO: special cascade/restrict procedure for alter?
*/
if (parser->parse((gptr)view, &thd->mem_root,
view_parameters + revision_number_position, 1))
{
DBUG_RETURN(1);
}
}
else
{
my_error(ER_WRONG_OBJECT, MYF(0), (view->db?view->db:thd->db),
view->real_name, "VIEW");
DBUG_RETURN(1);
}
}
else
{
if (!(parser= sql_parse_prepare(&path, &thd->mem_root, 0)))
DBUG_RETURN(1);
if (!parser->ok() ||
strncmp("VIEW", parser->type()->str, parser->type()->length))
{
my_error(ER_WRONG_OBJECT, MYF(0), (view->db ? view->db : thd->db),
view->real_name, "VIEW");
DBUG_RETURN(1);
}
/*
read revision number
TODO: read dependense list, too, to process cascade/restrict
TODO: special cascade/restrict procedure for alter?
*/
if (parser->parse((gptr)view, &thd->mem_root,
view_parameters + revision_number_position, 1))
{
DBUG_RETURN(1);
}
}
else
@ -448,14 +418,14 @@ static int mysql_register_view(THD *thd, TABLE_LIST *view,
}
view->algorithm= thd->lex->create_view_algorithm;
if ((view->updatable= (can_be_merged &&
view->algorithm != VIEW_ALGORITHM_TMEPTABLE)))
view->algorithm != VIEW_ALGORITHM_TMPTABLE)))
{
// TODO: change here when we will support UNIONs
for (TABLE_LIST *tbl= (TABLE_LIST *)thd->lex->select_lex.table_list.first;
tbl;
tbl= tbl->next_local)
{
if (tbl->view != 0 && !tbl->updatable)
if (tbl->view && !tbl->updatable)
{
view->updatable= 0;
break;
@ -478,7 +448,13 @@ static int mysql_register_view(THD *thd, TABLE_LIST *view,
mysql_make_view()
parser - parser object;
table - TABLE_LIST structure for filling
RETURN
0 ok
1 error
*/
my_bool
mysql_make_view(File_parser *parser, TABLE_LIST *table)
{
@ -487,7 +463,7 @@ mysql_make_view(File_parser *parser, TABLE_LIST *table)
if (table->view)
{
DBUG_PRINT("info",
("VIEW %s.%s is already processed on previos PS/SP execution",
("VIEW %s.%s is already processed on previous PS/SP execution",
table->view_db.str, table->view_name.str));
DBUG_RETURN(0);
}
@ -507,13 +483,14 @@ mysql_make_view(File_parser *parser, TABLE_LIST *table)
thd->set_n_backup_item_arena(arena, &backup);
/* init timestamp */
if (!test(table->timestamp.str))
if (!table->timestamp.str)
table->timestamp.str= table->timestamp_buffer;
/*
TODO: when VIEWs will be stored in cache, table mem_root should
be used here
*/
if (parser->parse((gptr)table, &thd->mem_root, view_parameters, 6))
if (parser->parse((gptr)table, &thd->mem_root, view_parameters,
required_view_parameters))
goto err;
/*
@ -535,7 +512,7 @@ mysql_make_view(File_parser *parser, TABLE_LIST *table)
*/
table->view= lex= thd->lex= (LEX*) new(&thd->mem_root) st_lex_local;
lex_start(thd, (uchar*)table->query.str, table->query.length);
mysql_init_query(thd, true);
mysql_init_query(thd, TRUE);
lex->select_lex.select_number= ++thd->select_number;
old_lex->derived_tables|= DERIVED_VIEW;
{
@ -613,7 +590,7 @@ mysql_make_view(File_parser *parser, TABLE_LIST *table)
- VIEW SELECT allow marging
- VIEW used in subquery or command support MERGE algorithm
*/
if (table->algorithm != VIEW_ALGORITHM_TMEPTABLE &&
if (table->algorithm != VIEW_ALGORITHM_TMPTABLE &&
lex->can_be_merged() &&
(table->select_lex->master_unit() != &old_lex->unit ||
old_lex->can_use_merged()))
@ -656,11 +633,13 @@ mysql_make_view(File_parser *parser, TABLE_LIST *table)
goto ok;
}
table->effective_algorithm= VIEW_ALGORITHM_TMEPTABLE;
table->effective_algorithm= VIEW_ALGORITHM_TMPTABLE;
if (table->updatable)
{
//TOTO: warning: can't be updateable, .frm edited by hand. version
//downgrade?
/*
TODO: warning: can't be updateable, .frm edited by hand. version
downgrade?
*/
table->updatable= 0;
}
@ -672,7 +651,8 @@ mysql_make_view(File_parser *parser, TABLE_LIST *table)
{
if ((tbl_end= table->next_global))
{
for (; (tbl_next= tbl_end->next_global); tbl_end= tbl_next);
for (; (tbl_next= tbl_end->next_global); tbl_end= tbl_next)
;
if ((tbl_end->next_global= old_next))
tbl_end->next_global->prev_global= &tbl_end->next_global;
}
@ -720,6 +700,7 @@ err:
-1 Error
1 Error and error message given
*/
int mysql_drop_view(THD *thd, TABLE_LIST *views, enum_drop_mode drop_mode)
{
DBUG_ENTER("mysql_drop_view");
@ -729,8 +710,8 @@ int mysql_drop_view(THD *thd, TABLE_LIST *views, enum_drop_mode drop_mode)
for (view= views; view; view= view->next_local)
{
strxmov(path, mysql_data_home, "/", view->db, "/", view->real_name,
reg_ext, NullS);
strxnmov(path, FN_REFLEN, mysql_data_home, "/", view->db, "/",
view->real_name, reg_ext, NullS);
(void) unpack_filename(path, path);
VOID(pthread_mutex_lock(&LOCK_open));
if (access(path, F_OK) || (type= (mysql_frm_type(path) != FRMTYPE_VIEW)))
@ -782,21 +763,20 @@ frm_type_enum mysql_frm_type(char *path)
{
File file;
char header[10]; //"TYPE=VIEW\n" it is 10 characters
int length;
DBUG_ENTER("mysql_frm_type");
if ((file= my_open(path, O_RDONLY | O_SHARE, MYF(MY_WME))) < 0)
{
DBUG_RETURN(FRMTYPE_ERROR);
}
if (my_read(file, header, 10, MYF(MY_WME)) == MY_FILE_ERROR)
{
my_close(file, MYF(MY_WME));
DBUG_RETURN(FRMTYPE_ERROR);
}
length= my_read(file, header, 10, MYF(MY_WME));
my_close(file, MYF(MY_WME));
if (strncmp(header, "TYPE=VIEW\n", 10) != 0)
DBUG_RETURN(FRMTYPE_TABLE);
DBUG_RETURN(FRMTYPE_VIEW);
if (length == (int) MY_FILE_ERROR)
DBUG_RETURN(FRMTYPE_ERROR);
if (!strncmp(header, "TYPE=VIEW\n", 10))
DBUG_RETURN(FRMTYPE_VIEW);
DBUG_RETURN(FRMTYPE_TABLE); // Is probably a .frm table
}
@ -815,72 +795,81 @@ frm_type_enum mysql_frm_type(char *path)
bool check_key_in_view(THD *thd, TABLE_LIST *view)
{
TABLE *table;
Item **trans;
KEY *key_info, *key_info_end;
uint i, elements_in_view;
DBUG_ENTER("check_key_in_view");
if (!view->view)
DBUG_RETURN(FALSE); /* it is normal table */
table= view->table;
trans= view->field_translation;
key_info_end= (key_info= table->key_info)+ table->keys;
TABLE *table= view->table;
Item **trans= view->field_translation;
KEY *key_info= table->key_info;
uint primary_key= table->primary_key;
uint num= view->view->select_lex.item_list.elements;
elements_in_view= view->view->select_lex.item_list.elements;
DBUG_ASSERT(view->table != 0 && view->field_translation != 0);
/* try to find key */
for (uint i=0; i < table->keys; i++, key_info++)
/* Loop over all keys to see if a unique-not-null key is used */
for (;key_info != key_info_end ; key_info++)
{
if (i == primary_key && !strcmp(key_info->name, primary_key_name) ||
key_info->flags & HA_NOSAME)
if ((key_info->flags & (HA_NOSAME | HA_NULL_PART_KEY)) == HA_NOSAME)
{
KEY_PART_INFO *key_part= key_info->key_part;
bool found= 1;
for (uint j=0; j < key_info->key_parts && found; j++, key_part++)
KEY_PART_INFO *key_part_end= key_part + key_info->key_parts;
/* check that all key parts are used */
for (;;)
{
found= 0;
for (uint k= 0; k < num; k++)
uint k;
for (k= 0; k < elements_in_view; k++)
{
if (trans[k]->type() == Item::FIELD_ITEM &&
((Item_field *)trans[k])->field == key_part->field &&
(key_part->field->flags & NOT_NULL_FLAG))
{
found= 1;
((Item_field *)trans[k])->field == key_part->field)
break;
}
}
if (k == elements_in_view)
break; // Key is not possible
if (++key_part == key_part_end)
DBUG_RETURN(FALSE); // Found usable key
}
if (found)
DBUG_RETURN(FALSE);
}
}
DBUG_PRINT("info", ("checking if all fields of table are used"));
/* check all fields presence */
{
Field **field_ptr= table->field;
for (; *field_ptr; ++field_ptr)
Field **field_ptr;
for (field_ptr= table->field; *field_ptr; field_ptr++)
{
uint i= 0;
for (; i < num; i++)
for (i= 0; i < elements_in_view; i++)
{
if (trans[i]->type() == Item::FIELD_ITEM &&
((Item_field *)trans[i])->field == *field_ptr)
break;
}
if (i >= num)
if (i == elements_in_view) // If field didn't exists
{
ulong mode= thd->variables.sql_updatable_view_key;
/* 1 == YES, 2 == LIMIT1 */
/*
0 == NO ; Don't give any errors
1 == YES ; Give always an error
2 == LIMIT1 ; Give an error if this is used with LIMIT 1
This is used to protect against gui programs that
uses LIMIT 1 to update just the current row. This
doesn't work reliable if the view doesn't have a
unique key or if the view doesn't use all fields in
table.
*/
if (mode == 1 ||
(mode == 2 &&
thd->lex->select_lex.select_limit == 1))
thd->lex->unit.global_parameters->select_limit == 1))
{
DBUG_RETURN(TRUE);
}
else
{
push_warning(thd, MYSQL_ERROR::WARN_LEVEL_NOTE,
ER_WARN_VIEW_WITHOUT_KEY, ER(ER_WARN_VIEW_WITHOUT_KEY));
DBUG_RETURN(FALSE);
}
push_warning(thd, MYSQL_ERROR::WARN_LEVEL_NOTE,
ER_WARN_VIEW_WITHOUT_KEY, ER(ER_WARN_VIEW_WITHOUT_KEY));
DBUG_RETURN(FALSE);
}
}
}
@ -899,18 +888,17 @@ bool check_key_in_view(THD *thd, TABLE_LIST *view)
void insert_view_fields(List<Item> *list, TABLE_LIST *view)
{
uint num= view->view->select_lex.item_list.elements;
Item **trans= view->field_translation;
uint elements_in_view= view->view->select_lex.item_list.elements;
Item **trans;
DBUG_ENTER("insert_view_fields");
if (!trans)
if (!(trans= view->field_translation))
DBUG_VOID_RETURN;
for (uint i= 0; i < num; i++)
for (uint i= 0; i < elements_in_view; i++)
{
if (trans[i]->type() == Item::FIELD_ITEM)
{
list->push_back(trans[i]);
}
}
DBUG_VOID_RETURN;
}