diff options
author | bell@sanja.is.com.ua <> | 2004-09-10 02:22:44 +0300 |
---|---|---|
committer | bell@sanja.is.com.ua <> | 2004-09-10 02:22:44 +0300 |
commit | a23857e071f2c745c8bddc748d365ff0ab311952 (patch) | |
tree | b045cc181c0717a5a6787cfc01d4a6744ac330c6 | |
parent | 336cb5f8be3c0260a35c919ec875b8adca195d39 (diff) | |
download | mariadb-git-a23857e071f2c745c8bddc748d365ff0ab311952.tar.gz |
post merge fixes
-rw-r--r-- | mysql-test/t/merge.test | 2 | ||||
-rw-r--r-- | sql/item.h | 2 | ||||
-rw-r--r-- | sql/item_subselect.cc | 44 | ||||
-rw-r--r-- | sql/item_sum.cc | 2 | ||||
-rw-r--r-- | sql/mysql_priv.h | 5 | ||||
-rw-r--r-- | sql/sql_base.cc | 34 | ||||
-rw-r--r-- | sql/sql_class.h | 2 | ||||
-rw-r--r-- | sql/sql_handler.cc | 2 | ||||
-rw-r--r-- | sql/sql_lex.cc | 2 | ||||
-rw-r--r-- | sql/sql_parse.cc | 29 | ||||
-rw-r--r-- | sql/sql_select.cc | 13 | ||||
-rw-r--r-- | sql/sql_union.cc | 2 | ||||
-rw-r--r-- | sql/sql_view.cc | 2 | ||||
-rw-r--r-- | sql/table.cc | 2 |
14 files changed, 81 insertions, 62 deletions
diff --git a/mysql-test/t/merge.test b/mysql-test/t/merge.test index 9580c1ab44c..9d367260049 100644 --- a/mysql-test/t/merge.test +++ b/mysql-test/t/merge.test @@ -284,4 +284,6 @@ insert into t2 values (1); create table t3 engine=merge union=(t1, t2) select * from t1; --error 1093 create table t3 engine=merge union=(t1, t2) select * from t2; +--error 1093 +create table t3 engine=merge union=(t1, t2) select (select max(a) from t2); drop table t1, t2; diff --git a/sql/item.h b/sql/item.h index 1420a89c76a..d0482c44875 100644 --- a/sql/item.h +++ b/sql/item.h @@ -434,7 +434,7 @@ public: friend bool insert_fields(THD *thd,TABLE_LIST *tables, const char *db_name, const char *table_name, List_iterator<Item> *it, - bool any_privileges); + bool any_privileges, bool allocate_view_names); }; diff --git a/sql/item_subselect.cc b/sql/item_subselect.cc index 23dbcf8af48..9cd01255d43 100644 --- a/sql/item_subselect.cc +++ b/sql/item_subselect.cc @@ -316,9 +316,9 @@ Item_singlerow_subselect::select_transformer(JOIN *join) SELECT_LEX *select_lex= join->select_lex; /* Juggle with current arena only if we're in prepared statement prepare */ - Item_arena *arena= join->thd->current_arena; + Item_arena *arena= thd->current_arena; Item_arena backup; - if (!arena->is_stmt_prepare()) + if (arena->is_conventional()) arena= 0; // For easier test if (!select_lex->master_unit()->first_select()->next_select() && @@ -337,11 +337,11 @@ Item_singlerow_subselect::select_transformer(JOIN *join) { have_to_be_excluded= 1; - if (join->thd->lex->describe) + if (thd->lex->describe) { char warn_buff[MYSQL_ERRMSG_SIZE]; sprintf(warn_buff, ER(ER_SELECT_REDUCED), select_lex->select_number); - push_warning(join->thd, MYSQL_ERROR::WARN_LEVEL_NOTE, + push_warning(thd, MYSQL_ERROR::WARN_LEVEL_NOTE, ER_SELECT_REDUCED, warn_buff); } substitution= select_lex->item_list.head(); @@ -367,9 +367,9 @@ Item_singlerow_subselect::select_transformer(JOIN *join) if (!(substitution= new Item_func_if(cond, substitution, new Item_null()))) goto err; + if (arena) + thd->restore_backup_item_arena(arena, &backup); } - if (arena) - thd->restore_backup_item_arena(arena, &backup); return RES_REDUCE; } return RES_OK; @@ -654,11 +654,11 @@ Item_in_subselect::single_value_transformer(JOIN *join, } SELECT_LEX *select_lex= join->select_lex; - Item_arena *arena= join->thd->current_arena, backup; + Item_arena *arena= thd->current_arena, backup; thd->where= "scalar IN/ALL/ANY subquery"; - if (!arena->is_stmt_prepare()) + if (arena->is_conventional()) arena= 0; // For easier test else thd->set_n_backup_item_arena(arena, &backup); @@ -900,7 +900,7 @@ Item_in_subselect::row_value_transformer(JOIN *join) thd->where= "row IN/ALL/ANY subquery"; Item_arena *arena= join->thd->current_arena, backup; - if (!arena->is_stmt_prepare()) + if (arena->is_conventional()) arena= 0; else thd->set_n_backup_item_arena(arena, &backup); @@ -1192,17 +1192,17 @@ void subselect_uniquesubquery_engine::fix_length_and_dec(Item_cache **row) int subselect_single_select_engine::exec() { DBUG_ENTER("subselect_single_select_engine::exec"); - char const *save_where= join->thd->where; - SELECT_LEX *save_select= join->thd->lex->current_select; - join->thd->lex->current_select= select_lex; + char const *save_where= thd->where; + SELECT_LEX *save_select= thd->lex->current_select; + thd->lex->current_select= select_lex; if (!optimized) { optimized=1; if (join->optimize()) { - join->thd->where= save_where; + thd->where= save_where; executed= 1; - join->thd->lex->current_select= save_select; + thd->lex->current_select= save_select; DBUG_RETURN(join->error ? join->error : 1); } if (item->engine_changed) @@ -1214,8 +1214,8 @@ int subselect_single_select_engine::exec() { if (join->reinit()) { - join->thd->where= save_where; - join->thd->lex->current_select= save_select; + thd->where= save_where; + thd->lex->current_select= save_select; DBUG_RETURN(1); } item->reset(); @@ -1225,20 +1225,20 @@ int subselect_single_select_engine::exec() { join->exec(); executed= 1; - join->thd->where= save_where; - join->thd->lex->current_select= save_select; + thd->where= save_where; + thd->lex->current_select= save_select; DBUG_RETURN(join->error||thd->is_fatal_error); } - join->thd->where= save_where; - join->thd->lex->current_select= save_select; + thd->where= save_where; + thd->lex->current_select= save_select; DBUG_RETURN(0); } int subselect_union_engine::exec() { - char const *save_where= unit->thd->where; + char const *save_where= thd->where; int res= unit->exec(); - unit->thd->where= save_where; + thd->where= save_where; return res; } diff --git a/sql/item_sum.cc b/sql/item_sum.cc index bfa0f86c744..d400c198828 100644 --- a/sql/item_sum.cc +++ b/sql/item_sum.cc @@ -77,7 +77,7 @@ Item_sum::Item_sum(THD *thd, Item_sum *item): */ bool Item_sum::save_args_for_prepared_statement(THD *thd) { - if (thd->current_arena->is_stmt_prepare() && args_copy == 0) + if (!thd->current_arena->is_conventional() && args_copy == 0) return save_args(thd->current_arena); return 0; } diff --git a/sql/mysql_priv.h b/sql/mysql_priv.h index f802c77a0db..8c73c6ad738 100644 --- a/sql/mysql_priv.h +++ b/sql/mysql_priv.h @@ -756,7 +756,8 @@ bool get_key_map_from_key_list(key_map *map, TABLE *table, List<String> *index_list); bool insert_fields(THD *thd,TABLE_LIST *tables, const char *db_name, const char *table_name, - List_iterator<Item> *it, bool any_privileges); + List_iterator<Item> *it, bool any_privileges, + bool allocate_view_names); bool setup_tables(THD *thd, TABLE_LIST *tables, Item **conds); int setup_wild(THD *thd, TABLE_LIST *tables, List<Item> &fields, List<Item> *sum_func_list, uint wild_num); @@ -782,7 +783,7 @@ TABLE_LIST *find_table_in_list(TABLE_LIST *table, uint offset_to_list, const char *db_name, const char *table_name); -bool unique_table(TABLE_LIST *table, TABLE_LIST *table_list); +TABLE_LIST *unique_table(TABLE_LIST *table, TABLE_LIST *table_list); TABLE **find_temporary_table(THD *thd, const char *db, const char *table_name); bool close_temporary_table(THD *thd, const char *db, const char *table_name); void close_temporary(TABLE *table, bool delete_table=1); diff --git a/sql/sql_base.cc b/sql/sql_base.cc index aad372fd574..51c25940fac 100644 --- a/sql/sql_base.cc +++ b/sql/sql_base.cc @@ -613,14 +613,15 @@ TABLE_LIST *find_table_in_list(TABLE_LIST *table, table_list list of tables RETURN - TRUE test failed - FALSE table is unique + found duplicate + 0 if table is unique */ -bool unique_table(TABLE_LIST *table, TABLE_LIST *table_list) +TABLE_LIST* unique_table(TABLE_LIST *table, TABLE_LIST *table_list) { - char d_name_buff[MAX_ALIAS_NAME], t_name_buff[MAX_ALIAS_NAME]; + TABLE_LIST *res; const char *d_name= table->db, *t_name= table->real_name; + char d_name_buff[MAX_ALIAS_NAME], t_name_buff[MAX_ALIAS_NAME]; if (table->view) { /* it is view and table opened */ @@ -640,11 +641,17 @@ bool unique_table(TABLE_LIST *table, TABLE_LIST *table_list) } if (d_name == 0) { - /* it's temporary table */ - return FALSE; + /* it's temporary table => always unique */ + return 0; } } - return find_table_in_global_list(table_list, d_name, t_name); + if ((res= find_table_in_global_list(table_list, d_name, t_name)) && + res->table && res->table == table->table) + { + // we found entry of this table try again. + return find_table_in_global_list(res->next_global, d_name, t_name); + } + return res; } @@ -2504,7 +2511,7 @@ int setup_wild(THD *thd, TABLE_LIST *tables, List<Item> &fields, 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->state == Item_arena::CONVENTIONAL_EXECUTION) + if (arena->is_conventional()) arena= 0; // For easier test later one else thd->set_n_backup_item_arena(arena, &backup); @@ -2530,8 +2537,8 @@ int setup_wild(THD *thd, TABLE_LIST *tables, List<Item> &fields, it.replace(new Item_int("Not_used", (longlong) 1, 21)); } else if (insert_fields(thd,tables,((Item_field*) item)->db_name, - ((Item_field*) item)->table_name, &it, - any_privileges)) + ((Item_field*) item)->table_name, &it, + any_privileges, arena != 0)) { if (arena) thd->restore_backup_item_arena(arena, &backup); @@ -2717,6 +2724,7 @@ bool get_key_map_from_key_list(key_map *map, TABLE *table, any_privileges 0 If we should ensure that we have SELECT privileges for all columns 1 If any privilege is ok + allocate_view_names if true view names will be copied to current Item_arena memory (made for SP/PS) RETURN 0 ok 'it' is updated to point at last inserted @@ -2726,7 +2734,7 @@ bool get_key_map_from_key_list(key_map *map, TABLE *table, bool insert_fields(THD *thd, TABLE_LIST *tables, const char *db_name, const char *table_name, List_iterator<Item> *it, - bool any_privileges) + bool any_privileges, bool allocate_view_names) { /* allocate variables on stack to avoid pool alloaction */ Field_iterator_table table_iter; @@ -2886,7 +2894,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->is_stmt_prepare() && + else if (allocate_view_names && thd->lex->current_select->first_execution) { Item_field *item= new Item_field(thd->strdup(tables->view_db.str), @@ -2931,7 +2939,7 @@ int setup_conds(THD *thd,TABLE_LIST *tables,COND **conds) DBUG_ENTER("setup_conds"); if (select_lex->conds_processed_with_permanent_arena || - !arena->is_stmt_prepare()) + arena->is_conventional()) arena= 0; // For easier test thd->set_query_id=1; diff --git a/sql/sql_class.h b/sql/sql_class.h index 1612ab6fb17..d1a8366653f 100644 --- a/sql/sql_class.h +++ b/sql/sql_class.h @@ -476,6 +476,8 @@ public: inline bool is_stmt_prepare() const { return (int)state < (int)PREPARED; } inline bool is_first_stmt_execute() const { return state == PREPARED; } + inline bool is_conventional() const + { return state == CONVENTIONAL_EXECUTION; } inline gptr alloc(unsigned int size) { return alloc_root(&mem_root,size); } inline gptr calloc(unsigned int size) { diff --git a/sql/sql_handler.cc b/sql/sql_handler.cc index 0df3d617d7f..f95291d914e 100644 --- a/sql/sql_handler.cc +++ b/sql/sql_handler.cc @@ -249,7 +249,7 @@ int mysql_ha_read(THD *thd, TABLE_LIST *tables, it++; // Skip first NULL field - insert_fields(thd, tables, tables->db, tables->alias, &it, 0); + insert_fields(thd, tables, tables->db, tables->alias, &it, 0, 0); select_limit+=offset_limit; protocol->send_fields(&list, Protocol::SEND_NUM_ROWS | Protocol::SEND_EOF); diff --git a/sql/sql_lex.cc b/sql/sql_lex.cc index 241e9b863f1..317033512c0 100644 --- a/sql/sql_lex.cc +++ b/sql/sql_lex.cc @@ -1795,7 +1795,7 @@ void st_lex::link_first_table_back(TABLE_LIST *first, void st_select_lex::fix_prepare_information(THD *thd, Item **conds) { - if (thd->current_arena->is_stmt_prepare() && first_execution) + if (!thd->current_arena->is_conventional() && first_execution) { first_execution= 0; prep_where= where; diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc index 9bad6c05d3c..60c273500e6 100644 --- a/sql/sql_parse.cc +++ b/sql/sql_parse.cc @@ -2404,20 +2404,6 @@ mysql_execute_command(THD *thd) if (select_lex->item_list.elements) // With select { select_result *result; - if (lex->create_info.used_fields & HA_CREATE_USED_UNION) - { - TABLE_LIST *tab; - for (tab= select_tables; tab; tab= tab->next_local) - { - if (find_table_in_local_list((TABLE_LIST*) lex->create_info. - merge_list.first, - select_tables->db, tab->real_name)) - { - net_printf(thd, ER_UPDATE_TABLE_USED, tab->real_name); - goto create_error; - } - } - } if (select_tables && check_table_access(thd, SELECT_ACL, select_tables, 0)) @@ -2437,6 +2423,21 @@ mysql_execute_command(THD *thd) net_printf(thd, ER_UPDATE_TABLE_USED, create_table->real_name); goto create_error; } + /* If we create merge table, we have to test tables in merge, too */ + if (lex->create_info.used_fields & HA_CREATE_USED_UNION) + { + TABLE_LIST *tab; + for (tab= (TABLE_LIST*) lex->create_info.merge_list.first; + tab; + tab= tab->next_local) + { + if (unique_table(tab, select_tables)) + { + net_printf(thd, ER_UPDATE_TABLE_USED, tab->real_name); + goto create_error; + } + } + } if ((result= new select_create(create_table, &lex->create_info, diff --git a/sql/sql_select.cc b/sql/sql_select.cc index def641d9616..789a4dc3086 100644 --- a/sql/sql_select.cc +++ b/sql/sql_select.cc @@ -6156,16 +6156,21 @@ optimize_cond(JOIN *join, COND *conds, Item::cond_result *cond_value) MEMROOT for prepared statements and stored procedures. */ - Item_arena *arena=thd->current_arena, backup; - select->first_cond_optimization= 0; + Item_arena *arena= thd->current_arena, backup; + if (arena->is_conventional()) + arena= 0; // For easier test + else + thd->set_n_backup_item_arena(arena, &backup); - thd->set_n_backup_item_arena(arena, &backup); + select->first_cond_optimization= 0; /* Convert all outer joins to inner joins if possible */ conds= simplify_joins(join, join->join_list, conds, TRUE); select->prep_where= conds ? conds->copy_andor_structure(thd) : 0; - thd->restore_backup_item_arena(arena, &backup); + + if (arena) + thd->restore_backup_item_arena(arena, &backup); } if (!conds) diff --git a/sql/sql_union.cc b/sql/sql_union.cc index d23e11d5443..1df419d04c3 100644 --- a/sql/sql_union.cc +++ b/sql/sql_union.cc @@ -293,7 +293,7 @@ int st_select_lex_unit::prepare(THD *thd_arg, select_result *sel_result, Field **field; Item_arena *arena= thd->current_arena; Item_arena backup; - if (!arena->is_stmt_prepare()) + if (arena->is_conventional()) arena= 0; else thd->set_n_backup_item_arena(arena, &backup); diff --git a/sql/sql_view.cc b/sql/sql_view.cc index 649953897e7..91b66251fd0 100644 --- a/sql/sql_view.cc +++ b/sql/sql_view.cc @@ -523,7 +523,7 @@ mysql_make_view(File_parser *parser, TABLE_LIST *table) will be TRUE as far as we make new table cache). */ Item_arena *arena= thd->current_arena, backup; - if (!arena->is_stmt_prepare()) + if (arena->is_conventional()) arena= 0; else thd->set_n_backup_item_arena(arena, &backup); diff --git a/sql/table.cc b/sql/table.cc index d07d2ca085d..00913363635 100644 --- a/sql/table.cc +++ b/sql/table.cc @@ -1583,7 +1583,7 @@ bool st_table_list::setup_ancestor(THD *thd, Item **conds) if (where) { Item_arena *arena= thd->current_arena, backup; - if (!arena->is_stmt_prepare()) + if (arena->is_conventional()) arena= 0; // For easier test if (!where->fixed && where->fix_fields(thd, ancestor, &where)) |