1
0
mirror of https://github.com/MariaDB/server.git synced 2025-07-27 18:02:13 +03:00
This commit is contained in:
bell@sanja.is.com.ua
2004-10-05 13:41:51 +03:00
51 changed files with 1292 additions and 259 deletions

View File

@ -554,10 +554,10 @@ void close_temporary_tables(THD *thd)
SYNOPSIS
find_table_in_list()
table Pointer to table list
table Pointer to table list
offset Offset to which list in table structure to use
db_name Data base name
table_name Table name
db_name Data base name
table_name Table name
NOTES:
This is called by find_table_in_local_list() and
@ -577,13 +577,14 @@ TABLE_LIST *find_table_in_list(TABLE_LIST *table,
{
for (; table; table= *(TABLE_LIST **) ((char*) table + offset))
{
if ((!strcmp(table->db, db_name) &&
!strcmp(table->real_name, table_name)) ||
(table->view &&
!my_strcasecmp(table_alias_charset,
table->table->table_cache_key, db_name) &&
!my_strcasecmp(table_alias_charset,
table->table->table_name, table_name)))
if (table->table->tmp_table == NO_TMP_TABLE &&
((!strcmp(table->db, db_name) &&
!strcmp(table->real_name, table_name)) ||
(table->view &&
!my_strcasecmp(table_alias_charset,
table->table->table_cache_key, db_name) &&
!my_strcasecmp(table_alias_charset,
table->table->table_name, table_name))))
break;
}
}
@ -591,11 +592,12 @@ TABLE_LIST *find_table_in_list(TABLE_LIST *table,
{
for (; table; table= *(TABLE_LIST **) ((char*) table + offset))
{
if ((!strcmp(table->db, db_name) &&
!strcmp(table->real_name, table_name)) ||
(table->view &&
!strcmp(table->table->table_cache_key, db_name) &&
!strcmp(table->table->table_name, table_name)))
if (table->table->tmp_table == NO_TMP_TABLE &&
((!strcmp(table->db, db_name) &&
!strcmp(table->real_name, table_name)) ||
(table->view &&
!strcmp(table->table->table_cache_key, db_name) &&
!strcmp(table->table->table_name, table_name))))
break;
}
}
@ -2036,15 +2038,18 @@ find_field_in_table(THD *thd, TABLE_LIST *table_list,
bool allow_rowid,
uint *cached_field_index_ptr)
{
DBUG_ENTER("find_field_in_table");
DBUG_PRINT("enter", ("table:%s name: %s item name %s, ref 0x%lx",
table_list->alias, name, item_name, (ulong)ref));
Field *fld;
if (table_list->field_translation)
{
DBUG_ASSERT(ref != 0 && table_list->view != 0);
uint num= table_list->view->select_lex.item_list.elements;
Item **trans= table_list->field_translation;
Field_translator *trans= table_list->field_translation;
for (uint i= 0; i < num; i ++)
{
if (strcmp(trans[i]->name, name) == 0)
if (strcmp(trans[i].name, name) == 0)
{
#ifndef NO_EMBEDDED_ACCESS_CHECKS
if (check_grants_view &&
@ -2052,22 +2057,22 @@ find_field_in_table(THD *thd, TABLE_LIST *table_list,
table_list->view_db.str,
table_list->view_name.str,
name, length))
return WRONG_GRANT;
DBUG_RETURN(WRONG_GRANT);
#endif
if (thd->lex->current_select->no_wrap_view_item)
*ref= trans[i];
*ref= trans[i].item;
else
{
*ref= new Item_ref(trans + i, ref, table_list->view_name.str,
*ref= new Item_ref(&trans[i].item, ref, table_list->view_name.str,
item_name);
/* as far as Item_ref have defined refernce it do not need tables */
if (*ref)
(*ref)->fix_fields(thd, 0, ref);
}
return (Field*) view_ref_found;
DBUG_RETURN((Field*) view_ref_found);
}
}
return 0;
DBUG_RETURN(0);
}
fld= find_field_in_real_table(thd, table_list->table, name, length,
check_grants_table, allow_rowid,
@ -2081,10 +2086,10 @@ find_field_in_table(THD *thd, TABLE_LIST *table_list,
table_list->view_name.str,
name, length))
{
return WRONG_GRANT;
DBUG_RETURN(WRONG_GRANT);
}
#endif
return fld;
DBUG_RETURN(fld);
}
@ -2213,17 +2218,33 @@ find_field_in_tables(THD *thd, Item_ident *item, TABLE_LIST *tables,
field makes some prepared query ambiguous and so erronous, but we
accept this trade off.
*/
found= find_field_in_real_table(thd, item->cached_table->table,
name, length,
test(item->cached_table->
table->grant.want_privilege) &&
check_privileges,
1, &(item->cached_field_index));
if (item->cached_table->table)
{
found= find_field_in_real_table(thd, item->cached_table->table,
name, length,
test(item->cached_table->
table->grant.want_privilege) &&
check_privileges,
1, &(item->cached_field_index));
}
else
{
TABLE_LIST *table= item->cached_table;
Field *find= find_field_in_table(thd, table, name, item->name, length,
ref,
(table->table &&
test(table->table->grant.
want_privilege) &&
check_privileges),
(test(table->grant.want_privilege) &&
check_privileges),
1, &(item->cached_field_index));
}
if (found)
{
if (found == WRONG_GRANT)
return (Field*) 0;
return (Field*) 0;
return found;
}
}
@ -2251,7 +2272,8 @@ find_field_in_tables(THD *thd, Item_ident *item, TABLE_LIST *tables,
found_table=1;
Field *find= find_field_in_table(thd, tables, name, item->name,
length, ref,
(test(tables->table->grant.
(tables->table &&
test(tables->table->grant.
want_privilege) &&
check_privileges),
(test(tables->grant.want_privilege) &&
@ -2305,7 +2327,7 @@ find_field_in_tables(THD *thd, Item_ident *item, TABLE_LIST *tables,
bool allow_rowid= tables && !tables->next_local; // Only one table
for (; tables ; tables= tables->next_local)
{
if (!tables->table)
if (!tables->table && !tables->ancestor)
{
if (report_error)
my_printf_error(ER_BAD_FIELD_ERROR,ER(ER_BAD_FIELD_ERROR),MYF(0),
@ -2315,7 +2337,8 @@ find_field_in_tables(THD *thd, Item_ident *item, TABLE_LIST *tables,
Field *field= find_field_in_table(thd, tables, name, item->name,
length, ref,
(test(tables->table->grant.
(tables->table &&
test(tables->table->grant.
want_privilege) &&
check_privileges),
(test(tables->grant.want_privilege) &&
@ -2628,7 +2651,6 @@ int setup_fields(THD *thd, Item **ref_pointer_array, TABLE_LIST *tables,
if (!item->fixed && item->fix_fields(thd, tables, it.ref()) ||
(item= *(it.ref()))->check_cols(1))
{
select_lex->no_wrap_view_item= 0;
DBUG_RETURN(-1); /* purecov: inspected */
}
if (ref)
@ -2642,14 +2664,46 @@ int setup_fields(THD *thd, Item **ref_pointer_array, TABLE_LIST *tables,
}
/*
make list of leaves of join table tree
SYNOPSIS
make_leaves_list()
list pointer to pointer on list first element
tables table list
RETURN pointer on pointer to next_leaf of last element
*/
TABLE_LIST **make_leaves_list(TABLE_LIST **list, TABLE_LIST *tables)
{
for (TABLE_LIST *table= tables; table; table= table->next_local)
{
if (table->view && !table->table)
{
/* it is for multi table views only, check it */
DBUG_ASSERT(table->ancestor->next_local);
list= make_leaves_list(list, table->ancestor);
}
else
{
*list= table;
list= &table->next_leaf;
}
}
return list;
}
/*
prepare tables
SYNOPSIS
setup_tables()
thd - thread handler
tables - tables list
conds - condition of current SELECT (can be changed by VIEW)
thd - thread handler
tables - tables list
conds - condition of current SELECT (can be changed by VIEW)
leaves - list of join table leaves list
refresh - it is onle refresh for subquery
RETURN
0 ok; In this case *map will includes the choosed index
@ -2666,16 +2720,23 @@ int setup_fields(THD *thd, Item **ref_pointer_array, TABLE_LIST *tables,
if tables do not contain VIEWs it is OK to pass 0 as conds
*/
bool setup_tables(THD *thd, TABLE_LIST *tables, Item **conds)
bool setup_tables(THD *thd, TABLE_LIST *tables, Item **conds,
TABLE_LIST **leaves, bool refresh)
{
DBUG_ENTER("setup_tables");
if (!tables || tables->setup_is_done)
DBUG_RETURN(0);
tables->setup_is_done= 1;
if (!(*leaves))
{
make_leaves_list(leaves, tables);
}
uint tablenr=0;
for (TABLE_LIST *table_list= tables;
for (TABLE_LIST *table_list= *leaves;
table_list;
table_list= table_list->next_local, tablenr++)
table_list= table_list->next_leaf, tablenr++)
{
TABLE *table= table_list->table;
setup_table_map(table, table_list, tablenr);
@ -2697,14 +2758,22 @@ bool setup_tables(THD *thd, TABLE_LIST *tables, Item **conds)
table->keys_in_use_for_query.subtract(map);
}
table->used_keys.intersect(table->keys_in_use_for_query);
if (table_list->ancestor && table_list->setup_ancestor(thd, conds))
DBUG_RETURN(1);
}
if (tablenr > MAX_TABLES)
{
my_error(ER_TOO_MANY_TABLES,MYF(0),MAX_TABLES);
DBUG_RETURN(1);
}
if (!refresh)
{
for (TABLE_LIST *table_list= tables;
table_list;
table_list= table_list->next_local)
{
if (table_list->ancestor && table_list->setup_ancestor(thd, conds))
DBUG_RETURN(1);
}
}
DBUG_RETURN(0);
}
@ -2807,9 +2876,12 @@ insert_fields(THD *thd, TABLE_LIST *tables, const char *db_name,
tables->alias) &&
(!db_name || !strcmp(tables->db,db_name))))
{
bool view;
#ifndef NO_EMBEDDED_ACCESS_CHECKS
/* Ensure that we have access right to all columns */
if (!(table->grant.privilege & SELECT_ACL) && !any_privileges)
if (!((table && (table->grant.privilege & SELECT_ACL) ||
tables->view && (tables->grant.privilege & SELECT_ACL))) &&
!any_privileges)
{
if (tables->view)
{
@ -2822,6 +2894,7 @@ insert_fields(THD *thd, TABLE_LIST *tables, const char *db_name,
}
else
{
DBUG_ASSERT(table != 0);
table_iter.set(tables);
if (check_grant_all_columns(thd, SELECT_ACL, &table->grant,
table->table_cache_key, table->real_name,
@ -2830,8 +2903,17 @@ insert_fields(THD *thd, TABLE_LIST *tables, const char *db_name,
}
}
#endif
if (table)
thd->used_tables|= table->map;
else
{
view_iter.set(tables);
for (; !view_iter.end_of_fields(); view_iter.next())
{
thd->used_tables|= view_iter.item(thd)->used_tables();
}
}
natural_join_table= 0;
thd->used_tables|= table->map;
last= embedded= tables;
while ((embedding= embedded->embedding) &&
@ -2858,9 +2940,15 @@ insert_fields(THD *thd, TABLE_LIST *tables, const char *db_name,
natural_join_table= embedding;
}
if (tables->field_translation)
{
iterator= &view_iter;
view= 1;
}
else
{
iterator= &table_iter;
view= 0;
}
iterator->set(tables);
for (; !iterator->end_of_fields(); iterator->next())
@ -2880,6 +2968,11 @@ insert_fields(THD *thd, TABLE_LIST *tables, const char *db_name,
(void) it->replace(item); // Replace '*'
else
it->after(item);
if (view && !thd->lex->current_select->no_wrap_view_item)
{
item= new Item_ref(it->ref(), NULL, tables->view_name.str,
field_name);
}
#ifndef NO_EMBEDDED_ACCESS_CHECKS
if (any_privileges)
{
@ -2945,8 +3038,12 @@ insert_fields(THD *thd, TABLE_LIST *tables, const char *db_name,
}
}
/* All fields are used */
table->used_fields=table->fields;
/*
All fields are used in case if usual tables (in case of view used
fields merked in setu_tables during fix_fields of view columns
*/
if (table)
table->used_fields=table->fields;
}
}
if (found)
@ -2964,10 +3061,16 @@ err:
/*
** Fix all conditions and outer join expressions
Fix all conditions and outer join expressions
SYNOPSIS
setup_conds()
thd thread handler
tables list of tables for name resolving
leaves list of leaves of join table tree
*/
int setup_conds(THD *thd,TABLE_LIST *tables,COND **conds)
int setup_conds(THD *thd, TABLE_LIST *tables, TABLE_LIST *leaves, COND **conds)
{
table_map not_null_tables= 0;
SELECT_LEX *select_lex= thd->lex->current_select;
@ -2991,7 +3094,7 @@ int setup_conds(THD *thd,TABLE_LIST *tables,COND **conds)
}
/* Check if we are using outer joins */
for (TABLE_LIST *table= tables; table; table= table->next_local)
for (TABLE_LIST *table= leaves; table; table= table->next_leaf)
{
TABLE_LIST *embedded;
TABLE_LIST *embedding= table;
@ -3055,8 +3158,8 @@ int setup_conds(THD *thd,TABLE_LIST *tables,COND **conds)
Field_iterator_view view_iter;
Field_iterator *iterator;
Field *t1_field, *t2_field;
Item *item_t2;
Item_cond_and *cond_and=new Item_cond_and();
Item *item_t2= 0;
Item_cond_and *cond_and= new Item_cond_and();
if (!cond_and) // If not out of memory
DBUG_RETURN(1);
@ -3092,6 +3195,13 @@ int setup_conds(THD *thd,TABLE_LIST *tables,COND **conds)
t2_field->query_id= thd->query_id;
t2->used_keys.intersect(t2_field->part_of_key);
}
else
{
DBUG_ASSERT(t2_field == view_ref_found &&
item_t2->type() == Item::REF_ITEM);
/* remove hooking to stack variable */
((Item_ref*) item_t2)->hook_ptr= 0;
}
if ((t1_field= iterator->field()))
{
/* Mark field used for table cache */