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:
282
sql/sql_view.cc
282
sql/sql_view.cc
@ -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;
|
||||
}
|
||||
|
Reference in New Issue
Block a user