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

Yet another manual merge with main tree for patch for WL#1218 "Triggers"

sql/item.cc:
  Auto merged
sql/item.h:
  Auto merged
sql/item_func.cc:
  Auto merged
sql/item_func.h:
  Auto merged
sql/lex.h:
  Auto merged
sql/sql_base.cc:
  Auto merged
sql/sql_delete.cc:
  Auto merged
sql/sql_insert.cc:
  Auto merged
sql/sql_lex.h:
  Auto merged
sql/sql_parse.cc:
  Auto merged
sql/sql_table.cc:
  Auto merged
sql/share/czech/errmsg.txt:
  Auto merged
sql/share/danish/errmsg.txt:
  Auto merged
sql/share/dutch/errmsg.txt:
  Auto merged
sql/share/english/errmsg.txt:
  Auto merged
sql/share/estonian/errmsg.txt:
  Auto merged
sql/share/french/errmsg.txt:
  Auto merged
sql/share/german/errmsg.txt:
  Auto merged
sql/share/greek/errmsg.txt:
  Auto merged
sql/share/hungarian/errmsg.txt:
  Auto merged
sql/share/italian/errmsg.txt:
  Auto merged
sql/share/japanese/errmsg.txt:
  Auto merged
sql/share/korean/errmsg.txt:
  Auto merged
sql/share/norwegian-ny/errmsg.txt:
  Auto merged
sql/share/norwegian/errmsg.txt:
  Auto merged
sql/share/polish/errmsg.txt:
  Auto merged
sql/share/portuguese/errmsg.txt:
  Auto merged
sql/share/romanian/errmsg.txt:
  Auto merged
sql/share/russian/errmsg.txt:
  Auto merged
sql/share/serbian/errmsg.txt:
  Auto merged
sql/share/slovak/errmsg.txt:
  Auto merged
sql/share/spanish/errmsg.txt:
  Auto merged
sql/share/swedish/errmsg.txt:
  Auto merged
sql/share/ukrainian/errmsg.txt:
  Auto merged
include/mysqld_error.h:
  Manual merge.
sql/Makefile.am:
  Manual merge.
sql/mysql_priv.h:
  Manual merge.
sql/sp_head.cc:
  Manual merge.
sql/sql_lex.cc:
  Manual merge.
sql/sql_yacc.yy:
  Manual merge.
This commit is contained in:
unknown
2004-09-09 19:52:10 +04:00
760 changed files with 40075 additions and 18780 deletions

View File

@ -1727,6 +1727,27 @@ int open_and_lock_tables(THD *thd, TABLE_LIST *tables)
if (open_tables(thd, tables, &counter) || lock_tables(thd, tables, counter)
|| mysql_handle_derived(thd->lex))
DBUG_RETURN(thd->net.report_error ? -1 : 1); /* purecov: inspected */
/*
Let us propagate pointers to open tables from global table list
to table lists in particular selects if needed.
*/
if (thd->lex->all_selects_list->next_select_in_list() ||
thd->lex->time_zone_tables_used)
{
for (SELECT_LEX *sl= thd->lex->all_selects_list;
sl;
sl= sl->next_select_in_list())
{
for (TABLE_LIST *cursor= (TABLE_LIST *) sl->table_list.first;
cursor;
cursor=cursor->next_local)
{
if (cursor->correspondent_table)
cursor->table= cursor->correspondent_table->table;
}
}
}
DBUG_RETURN(0);
}
@ -1935,13 +1956,8 @@ find_field_in_table(THD *thd, TABLE_LIST *table_list,
*ref= trans[i];
else
{
Item_arena *arena= thd->current_arena, backup;
if (arena)
thd->set_n_backup_item_arena(arena, &backup);
*ref= new Item_ref(trans + i, 0, table_list->view_name.str,
*ref= new Item_ref(trans + i, ref, table_list->view_name.str,
item_name);
if (arena)
thd->restore_backup_item_arena(arena, &backup);
/* as far as Item_ref have defined refernce it do not need tables */
if (*ref)
(*ref)->fix_fields(thd, 0, ref);
@ -2268,10 +2284,12 @@ find_item_in_list(Item *find, List<Item> &items, uint *counter,
find_item_error_report_type report_error)
{
List_iterator<Item> li(items);
Item **found=0,*item;
Item **found=0, **found_unaliased= 0, *item;
const char *db_name=0;
const char *field_name=0;
const char *table_name=0;
bool found_unaliased_non_uniq= 0;
uint unaliased_counter;
if (find->type() == Item::FIELD_ITEM || find->type() == Item::REF_ITEM)
{
field_name= ((Item_ident*) find)->field_name;
@ -2284,42 +2302,93 @@ find_item_in_list(Item *find, List<Item> &items, uint *counter,
if (field_name && item->type() == Item::FIELD_ITEM)
{
Item_field *item_field= (Item_field*) item;
/*
In case of group_concat() with ORDER BY condition in the QUERY
item_field can be field of temporary table without item name
(if this field created from expression argument of group_concat()),
=> we have to check presence of name before compare
*/
if (item_field->name &&
(!my_strcasecmp(system_charset_info, item_field->name, field_name) ||
!my_strcasecmp(system_charset_info,
item_field->field_name, field_name)))
if (!item_field->name)
continue;
if (table_name)
{
if (!table_name)
{
if (found)
{
if ((*found)->eq(item,0))
continue; // Same field twice (Access?)
if (report_error != IGNORE_ERRORS)
my_printf_error(ER_NON_UNIQ_ERROR,ER(ER_NON_UNIQ_ERROR),MYF(0),
find->full_name(), current_thd->where);
return (Item**) 0;
}
found= li.ref();
*counter= i;
}
else
{
if (!strcmp(item_field->table_name,table_name) &&
(!db_name || (db_name && item_field->db_name &&
!strcmp(item_field->db_name, db_name))))
{
found= li.ref();
*counter= i;
break;
}
}
/*
If table name is specified we should find field 'field_name' in
table 'table_name'. According to SQL-standard we should ignore
aliases in this case. Note that we should prefer fields from the
select list over other fields from the tables participating in
this select in case of ambiguity.
We use strcmp for table names and database names as these may be
case sensitive.
In cases where they are not case sensitive, they are always in lower
case.
*/
if (!my_strcasecmp(system_charset_info, item_field->field_name,
field_name) &&
!strcmp(item_field->table_name, table_name) &&
(!db_name || (item_field->db_name &&
!strcmp(item_field->db_name, db_name))))
{
if (found)
{
if ((*found)->eq(item, 0))
continue; // Same field twice
if (report_error != IGNORE_ERRORS)
my_printf_error(ER_NON_UNIQ_ERROR, ER(ER_NON_UNIQ_ERROR),
MYF(0), find->full_name(), current_thd->where);
return (Item**) 0;
}
found= li.ref();
*counter= i;
if (db_name)
break; // Perfect match
}
}
else if (!my_strcasecmp(system_charset_info, item_field->name,
field_name))
{
/*
If table name was not given we should scan through aliases
(or non-aliased fields) first. We are also checking unaliased
name of the field in then next else-if, to be able to find
instantly field (hidden by alias) if no suitable alias (or
non-aliased field) was found.
*/
if (found)
{
if ((*found)->eq(item, 0))
continue; // Same field twice
if (report_error != IGNORE_ERRORS)
my_printf_error(ER_NON_UNIQ_ERROR, ER(ER_NON_UNIQ_ERROR),
MYF(0), find->full_name(), current_thd->where);
return (Item**) 0;
}
found= li.ref();
*counter= i;
}
else if (!my_strcasecmp(system_charset_info, item_field->field_name,
field_name))
{
/*
We will use un-aliased field or react on such ambiguities only if
we won't be able to find aliased field.
Again if we have ambiguity with field outside of select list
we should prefer fields from select list.
*/
if (found_unaliased)
{
if ((*found_unaliased)->eq(item, 0))
continue; // Same field twice
found_unaliased_non_uniq= 1;
}
else
{
found_unaliased= li.ref();
unaliased_counter= i;
}
}
}
else if (!table_name && (item->eq(find,0) ||
@ -2332,9 +2401,24 @@ find_item_in_list(Item *find, List<Item> &items, uint *counter,
break;
}
}
if (!found)
{
if (found_unaliased_non_uniq)
{
if (report_error != IGNORE_ERRORS)
my_printf_error(ER_NON_UNIQ_ERROR, ER(ER_NON_UNIQ_ERROR), MYF(0),
find->full_name(), current_thd->where);
return (Item **) 0;
}
if (found_unaliased)
{
found= found_unaliased;
*counter= unaliased_counter;
}
}
if (found)
return found;
else if (report_error != REPORT_EXCEPT_NOT_FOUND)
if (report_error != REPORT_EXCEPT_NOT_FOUND)
{
if (report_error == REPORT_ALL_ERRORS)
my_printf_error(ER_BAD_FIELD_ERROR, ER(ER_BAD_FIELD_ERROR), MYF(0),
@ -2353,19 +2437,22 @@ int setup_wild(THD *thd, TABLE_LIST *tables, List<Item> &fields,
List<Item> *sum_func_list,
uint wild_num)
{
Item *item;
if (!wild_num)
return 0;
Item_arena *arena= thd->current_arena, backup;
/*
If we are in preparing prepared statement phase then we have change
temporary mem_root to statement mem root to save changes of SELECT list
Don't use arena if we are not in prepared statements or stored procedures
For PS/SP we have to use arena to remember the changes
*/
if (arena)
if (arena->state == Item_arena::CONVENTIONAL_EXECUTION)
arena= 0; // For easier test later one
else
thd->set_n_backup_item_arena(arena, &backup);
reg2 Item *item;
List_iterator<Item> it(fields);
while ( wild_num && (item= it++))
while (wild_num && (item= it++))
{
if (item->type() == Item::FIELD_ITEM && ((Item_field*) item)->field_name &&
((Item_field*) item)->field_name[0] == '*' &&
@ -2587,8 +2674,21 @@ insert_fields(THD *thd, TABLE_LIST *tables, const char *db_name,
Field_iterator_table table_iter;
Field_iterator_view view_iter;
uint found;
char name_buff[NAME_LEN+1];
DBUG_ENTER("insert_fields");
if (db_name && lower_case_table_names)
{
/*
convert database to lower case for comparison
We can't do this in Item_field as this would change the
'name' of the item which may be used in the select list
*/
strmake(name_buff, db_name, sizeof(name_buff)-1);
my_casedn_str(files_charset_info, name_buff);
db_name= name_buff;
}
found= 0;
for (; tables; tables= tables->next_local)
{
@ -2728,7 +2828,7 @@ insert_fields(THD *thd, TABLE_LIST *tables, const char *db_name,
field->query_id=thd->query_id;
table->used_keys.intersect(field->part_of_key);
}
else if (thd->current_arena &&
else if (thd->current_arena->is_stmt_prepare() &&
thd->lex->current_select->first_execution)
{
Item_field *item= new Item_field(thd->strdup(tables->view_db.str),
@ -2768,13 +2868,14 @@ int setup_conds(THD *thd,TABLE_LIST *tables,COND **conds)
{
table_map not_null_tables= 0;
SELECT_LEX *select_lex= thd->lex->current_select;
Item_arena *arena= ((thd->current_arena &&
!select_lex->conds_processed_with_permanent_arena) ?
thd->current_arena :
0);
Item_arena *arena= thd->current_arena;
Item_arena backup;
DBUG_ENTER("setup_conds");
if (select_lex->conds_processed_with_permanent_arena ||
!arena->is_stmt_prepare())
arena= 0; // For easier test
thd->set_query_id=1;
select_lex->cond_count= 0;
@ -2786,7 +2887,6 @@ int setup_conds(THD *thd,TABLE_LIST *tables,COND **conds)
DBUG_RETURN(1);
}
/* Check if we are using outer joins */
for (TABLE_LIST *table= tables; table; table= table->next_local)
{
@ -2907,31 +3007,34 @@ int setup_conds(THD *thd,TABLE_LIST *tables,COND **conds)
// to prevent natural join processing during PS re-execution
embedding->natural_join= 0;
COND *on_expr= cond_and;
on_expr->fix_fields(thd, 0, &on_expr);
if (!embedded->outer_join) // Not left join
if (cond_and->list.elements)
{
*conds= and_conds(*conds, cond_and);
// fix_fields() should be made with temporary memory pool
if (arena)
thd->restore_backup_item_arena(arena, &backup);
if (*conds && !(*conds)->fixed)
{
if ((*conds)->fix_fields(thd, tables, conds))
DBUG_RETURN(1);
}
}
else
{
embedded->on_expr= and_conds(embedded->on_expr, cond_and);
// fix_fields() should be made with temporary memory pool
if (arena)
thd->restore_backup_item_arena(arena, &backup);
if (embedded->on_expr && !embedded->on_expr->fixed)
{
if (embedded->on_expr->fix_fields(thd, tables, &table->on_expr))
DBUG_RETURN(1);
}
COND *on_expr= cond_and;
on_expr->fix_fields(thd, 0, &on_expr);
if (!embedded->outer_join) // Not left join
{
*conds= and_conds(*conds, cond_and);
// fix_fields() should be made with temporary memory pool
if (arena)
thd->restore_backup_item_arena(arena, &backup);
if (*conds && !(*conds)->fixed)
{
if ((*conds)->fix_fields(thd, tables, conds))
DBUG_RETURN(1);
}
}
else
{
embedded->on_expr= and_conds(embedded->on_expr, cond_and);
// fix_fields() should be made with temporary memory pool
if (arena)
thd->restore_backup_item_arena(arena, &backup);
if (embedded->on_expr && !embedded->on_expr->fixed)
{
if (embedded->on_expr->fix_fields(thd, tables, &table->on_expr))
DBUG_RETURN(1);
}
}
}
}
embedding= embedded->embedding;
@ -2955,7 +3058,7 @@ int setup_conds(THD *thd,TABLE_LIST *tables,COND **conds)
err:
if (arena)
thd->restore_backup_item_arena(arena, &backup);
thd->restore_backup_item_arena(arena, &backup);
DBUG_RETURN(1);
}
@ -2979,7 +3082,7 @@ fill_record(List<Item> &fields,List<Item> &values, bool ignore_errors)
Field *rfield= field->field;
TABLE *table= rfield->table;
if (rfield == table->next_number_field)
table->auto_increment_field_not_null= true;
table->auto_increment_field_not_null= TRUE;
if ((value->save_in_field(rfield, 0) < 0) && !ignore_errors)
DBUG_RETURN(1);
}
@ -3000,7 +3103,7 @@ fill_record(Field **ptr,List<Item> &values, bool ignore_errors)
value=v++;
TABLE *table= field->table;
if (field == table->next_number_field)
table->auto_increment_field_not_null= true;
table->auto_increment_field_not_null= TRUE;
if ((value->save_in_field(field, 0) < 0) && !ignore_errors)
DBUG_RETURN(1);
}