From 94d1d88658e5aa75d999c308ac464014f20a3d02 Mon Sep 17 00:00:00 2001 From: unknown Date: Sat, 18 Jun 2005 01:55:42 +0200 Subject: Clean up warnings and build problems on Windows. (Bug #11045) VC++Files/sql/mysqld.dsp: Link debug server against debug yassl sql/examples/ha_archive.cc: Fix type for variables used to store number of rows Add cast when reading current position sql/examples/ha_archive.h: Fix variables used to store rows to ha_rows sql/ha_federated.cc: Remove unused variables, fix type of variable used to store query id sql/item_strfunc.cc: Remove unused variables sql/sql_acl.cc: Remove unused variables sql/sql_lex.cc: Add casts to fix type used for counting number of rows sql/sql_lex.h: Fix size of options to be ulong again sql/sql_insert.cc: Fix type of query id value sql/sql_union.cc: Cast value for number of rows to ha_rows sql/sql_yacc.yy: Remove unused variable sql/table.cc: Add casts for handling key_part lengths --- sql/sql_insert.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'sql/sql_insert.cc') diff --git a/sql/sql_insert.cc b/sql/sql_insert.cc index 5ca75554c6f..750fe373b41 100644 --- a/sql/sql_insert.cc +++ b/sql/sql_insert.cc @@ -192,7 +192,7 @@ static int check_update_fields(THD *thd, TABLE_LIST *insert_table_list, List &update_fields) { TABLE *table= insert_table_list->table; - ulong timestamp_query_id; + query_id_it timestamp_query_id; LINT_INIT(timestamp_query_id); /* -- cgit v1.2.1 From d10877ce8ce4f939f88f79e6ad42af251fd51ebe Mon Sep 17 00:00:00 2001 From: unknown Date: Mon, 27 Jun 2005 16:46:41 +0300 Subject: Better bug fix for: #9728 'Decreased functionality in "on duplicate key update #8147 'a column proclaimed ambigous in INSERT ... SELECT .. ON DUPLICATE' This ensures fields are uniquely qualified and also that one can't update other tables in the ON DUPLICATE KEY UPDATE part mysql-test/r/insert_select.result: More tests for bug #9728 and #8147 mysql-test/r/insert_update.result: Updated tests after changing how INSERT ... SELECT .. ON DUPLICATE KEY works mysql-test/t/insert_select.test: More tests for bug #9728 and #8147 mysql-test/t/insert_update.test: Updated tests after changing how INSERT ... SELECT .. ON DUPLICATE KEY works mysys/my_access.c: Cleanup (shorter loop variable names) sql/ha_ndbcluster.cc: Indentation fixes sql/item.cc: Remove item_flags sql/item.h: Remove item_flags sql/mysql_priv.h: New arguments to mysql_prepare_insert sql/sql_base.cc: Remove old fix for bug #8147 sql/sql_insert.cc: Extend mysql_prepare_insert() with new field list for tables that can be used in the values port of ON DUPLICATE KEY UPDATE sql/sql_parse.cc: Revert fix for #9728 Allow one to use other tables in ON DUPLICATE_KEY for INSERT ... SELECT if there is no GROUP BY clause sql/sql_prepare.cc: New arguments to mysql_prepare_insert sql/sql_yacc.yy: Revert bug fix for #9728 --- sql/sql_insert.cc | 34 +++++++++++++++++++++++++--------- 1 file changed, 25 insertions(+), 9 deletions(-) (limited to 'sql/sql_insert.cc') diff --git a/sql/sql_insert.cc b/sql/sql_insert.cc index f09d3214c74..deccc1d4dca 100644 --- a/sql/sql_insert.cc +++ b/sql/sql_insert.cc @@ -271,7 +271,8 @@ int mysql_insert(THD *thd,TABLE_LIST *table_list, thd->used_tables=0; values= its++; - if (mysql_prepare_insert(thd, table_list, insert_table_list, table, + if (mysql_prepare_insert(thd, table_list, insert_table_list, + insert_table_list, table, fields, values, update_fields, update_values, duplic)) goto abort; @@ -499,22 +500,37 @@ abort: SYNOPSIS mysql_prepare_insert() - thd - thread handler - table_list - global table list - insert_table_list - local table list of INSERT SELECT_LEX - values - values to insert. NULL for INSERT ... SELECT + thd thread handler + table_list global table list (not including first table for + INSERT ... SELECT) + insert_table_list Table we are inserting into (for INSERT ... SELECT) + dup_table_list Tables to be used in ON DUPLICATE KEY + It's either all global tables or only the table we + insert into, depending on if we are using GROUP BY + in the SELECT clause). + values Values to insert. NULL for INSERT ... SELECT + + TODO (in far future) + In cases of: + INSERT INTO t1 SELECT a, sum(a) as sum1 from t2 GROUP BY a + ON DUPLICATE KEY ... + we should be able to refer to sum1 in the ON DUPLICATE KEY part RETURN VALUE - 0 - OK - -1 - error (message is not sent to user) + 0 OK + -1 error (message is not sent to user) */ + int mysql_prepare_insert(THD *thd, TABLE_LIST *table_list, - TABLE_LIST *insert_table_list, TABLE *table, + TABLE_LIST *insert_table_list, + TABLE_LIST *dup_table_list, + TABLE *table, List &fields, List_item *values, List &update_fields, List &update_values, enum_duplicates duplic) { DBUG_ENTER("mysql_prepare_insert"); + if (duplic == DUP_UPDATE && !table->insert_values) { /* it should be allocated before Item::fix_fields() */ @@ -528,7 +544,7 @@ int mysql_prepare_insert(THD *thd, TABLE_LIST *table_list, (values && setup_fields(thd, 0, insert_table_list, *values, 0, 0, 0)) || (duplic == DUP_UPDATE && (check_update_fields(thd, table, insert_table_list, update_fields) || - setup_fields(thd, 0, insert_table_list, update_values, 1, 0, 0)))) + setup_fields(thd, 0, dup_table_list, update_values, 1, 0, 0)))) DBUG_RETURN(-1); if (values && find_real_table_in_list(table_list->next, table_list->db, table_list->real_name)) -- cgit v1.2.1 From 05c7edf64801efa5b0d99ca779eb0b31a4d92462 Mon Sep 17 00:00:00 2001 From: unknown Date: Tue, 28 Jun 2005 15:06:16 +0300 Subject: Move reset of insert_values to ensure it's done also during error conditions This fixed a failure of insert_update.test on some platforms mysys/thr_alarm.c: Fixed problem noticed by valgrind sql/opt_range.cc: Simple optimization for common case sql/sql_base.cc: Safety assert sql/sql_insert.cc: Added comment --- sql/sql_insert.cc | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'sql/sql_insert.cc') diff --git a/sql/sql_insert.cc b/sql/sql_insert.cc index deccc1d4dca..7d613ad6fbf 100644 --- a/sql/sql_insert.cc +++ b/sql/sql_insert.cc @@ -516,6 +516,10 @@ abort: ON DUPLICATE KEY ... we should be able to refer to sum1 in the ON DUPLICATE KEY part + WARNING + You MUST set table->insert_values to 0 after calling this function + before releasing the table object. + RETURN VALUE 0 OK -1 error (message is not sent to user) -- cgit v1.2.1 From b4f595b95f1740b7153013431080ff77de8d867a Mon Sep 17 00:00:00 2001 From: unknown Date: Fri, 1 Jul 2005 07:05:42 +0300 Subject: Name resolution context added (BUG#6443) include/my_bitmap.h: new bitmap operation mysql-test/r/view.result: added warnings Correct inserting data check (absence of default value) for view underlying tables (BUG#6443) mysql-test/t/view.test: Correct inserting data check (absence of default value) for view underlying tables (BUG#6443) mysys/my_bitmap.c: new bitmap operation sql/field.h: index of field in table added sql/item.cc: Name resolution context added table list removed from fix_fields() arguments sql/item.h: Name resolution context added table list removed from fix_fields() arguments sql/item_cmpfunc.cc: table list removed from fix_fields() arguments sql/item_cmpfunc.h: table list removed from fix_fields() arguments sql/item_func.cc: table list removed from fix_fields() arguments sql/item_func.h: table list removed from fix_fields() arguments sql/item_row.cc: table list removed from fix_fields() arguments sql/item_row.h: table list removed from fix_fields() arguments sql/item_strfunc.cc: fixed server crash on NULL argument sql/item_strfunc.h: table list removed from fix_fields() arguments sql/item_subselect.cc: table list removed from fix_fields() arguments sql/item_subselect.h: table list removed from fix_fields() arguments sql/item_sum.cc: table list removed from fix_fields() arguments sql/item_sum.h: table list removed from fix_fields() arguments sql/item_timefunc.cc: table list removed from fix_fields() arguments sql/item_timefunc.h: table list removed from fix_fields() arguments sql/item_uniq.h: table list removed from fix_fields() arguments sql/log_event.cc: Name resolution context added sql/log_event.h: Name resolution context added sql/mysql_priv.h: Name resolution context added sql/set_var.cc: table list removed from fix_fields() arguments sql/share/errmsg.txt: new error message sql/sp.cc: Name resolution context added sql/sp_head.cc: table list removed from fix_fields() arguments sql/sp_head.h: Name resolution context added sql/sql_base.cc: table list removed from fix_fields() arguments Name resolution context added sql/sql_class.cc: renamed variable sql/sql_delete.cc: Name resolution context added sql/sql_derived.cc: Name resolution context added sql/sql_do.cc: table list removed from fix_fields() arguments sql/sql_handler.cc: Name resolution context added sql/sql_help.cc: Name resolution context added sql/sql_insert.cc: Name resolution context added table list removed from fix_fields() arguments sql/sql_lex.cc: Name resolution context added sql/sql_lex.h: removed resolve mode (information stored into name resolution context) sql/sql_load.cc: table list removed from fix_fields() arguments sql/sql_olap.cc: Name resolution context added sql/sql_parse.cc: Name resolution context added sql/sql_prepare.cc: table list removed from fix_fields() arguments sql/sql_select.cc: table list removed from fix_fields() arguments sql/sql_show.cc: Name resolution context added sql/sql_trigger.cc: table list removed from fix_fields() arguments sql/sql_udf.h: table list removed from fix_fields() arguments sql/sql_union.cc: Name resolution context added sql/sql_update.cc: Name resolution context added sql/sql_view.cc: Name resolution context added sql/sql_view.h: table list removed from fix_fields() arguments sql/sql_yacc.yy: Name resolution context added sql/table.cc: Name resolution context added merged view processing moved sql/table.h: merged view processing moved --- sql/sql_insert.cc | 174 ++++++++++++++++++++++++++++++++++++------------------ 1 file changed, 118 insertions(+), 56 deletions(-) (limited to 'sql/sql_insert.cc') diff --git a/sql/sql_insert.cc b/sql/sql_insert.cc index 2ce81d8815e..53c47706734 100644 --- a/sql/sql_insert.cc +++ b/sql/sql_insert.cc @@ -31,7 +31,7 @@ static void end_delayed_insert(THD *thd); extern "C" pthread_handler_decl(handle_delayed_insert,arg); static void unlink_blobs(register TABLE *table); #endif -static bool check_view_insertability(TABLE_LIST *view, query_id_t query_id); +static bool check_view_insertability(THD *thd, TABLE_LIST *view); /* Define to force use of my_malloc() if the allocated memory block is big */ @@ -106,7 +106,11 @@ static int check_insert_fields(THD *thd, TABLE_LIST *table_list, } else { // Part field list - TABLE_LIST *save_next; + Name_resolution_context *context= &thd->lex->select_lex.context; + TABLE_LIST *save_next= table_list->next_local, + *save_context= context->table_list; + bool save_resolve_in_select_list= + thd->lex->select_lex.context.resolve_in_select_list; int res; if (fields.elements != values.elements) { @@ -115,12 +119,15 @@ static int check_insert_fields(THD *thd, TABLE_LIST *table_list, } thd->dupp_field=0; - thd->lex->select_lex.no_wrap_view_item= 1; - save_next= table_list->next_local; // fields only from first table + thd->lex->select_lex.no_wrap_view_item= TRUE; + /* fields only from first table */ table_list->next_local= 0; - res= setup_fields(thd, 0, table_list, fields, 1, 0, 0); + context->resolve_in_table_list_only(table_list); + res= setup_fields(thd, 0, fields, 1, 0, 0); table_list->next_local= save_next; - thd->lex->select_lex.no_wrap_view_item= 0; + thd->lex->select_lex.no_wrap_view_item= FALSE; + context->table_list= save_context; + context->resolve_in_select_list= save_resolve_in_select_list; if (res) return -1; if (table_list->effective_algorithm == VIEW_ALGORITHM_MERGE) @@ -159,7 +166,7 @@ static int check_insert_fields(THD *thd, TABLE_LIST *table_list, if (check_key_in_view(thd, table_list) || (table_list->view && - check_view_insertability(table_list, thd->query_id))) + check_view_insertability(thd, table_list))) { my_error(ER_NON_UPDATABLE_TABLE, MYF(0), table_list->alias, "INSERT"); return -1; @@ -209,7 +216,7 @@ static int check_update_fields(THD *thd, TABLE_LIST *insert_table_list, Check the fields we are going to modify. This will set the query_id of all used fields to the threads query_id. */ - if (setup_fields(thd, 0, insert_table_list, update_fields, 1, 0, 0)) + if (setup_fields(thd, 0, update_fields, 1, 0, 0)) return -1; if (table->timestamp_field) @@ -247,6 +254,7 @@ bool mysql_insert(THD *thd,TABLE_LIST *table_list, ulonglong id; COPY_INFO info; TABLE *table= 0; + TABLE_LIST *next_local; List_iterator_fast its(values_list); List_item *values; #ifndef EMBEDDED_LIBRARY @@ -327,7 +335,9 @@ bool mysql_insert(THD *thd,TABLE_LIST *table_list, /* mysql_prepare_insert set table_list->table if it was not set */ table= table_list->table; - // is table which we are changing used somewhere in other parts of query + next_local= table_list->next_local; + table_list->next_local= 0; + thd->lex->select_lex.context.resolve_in_table_list_only(table_list); value_count= values->elements; while ((values= its++)) { @@ -337,10 +347,11 @@ bool mysql_insert(THD *thd,TABLE_LIST *table_list, my_error(ER_WRONG_VALUE_COUNT_ON_ROW, MYF(0), counter); goto abort; } - if (setup_fields(thd, 0, table_list, *values, 0, 0, 0)) + if (setup_fields(thd, 0, *values, 0, 0, 0)) goto abort; } its.rewind (); + table_list->next_local= next_local; /* Fill in the given fields and dump it to the table file */ @@ -387,12 +398,16 @@ bool mysql_insert(THD *thd,TABLE_LIST *table_list, MODE_STRICT_ALL_TABLES))); if ((fields.elements || !value_count) && - check_that_all_fields_are_given_values(thd, table)) + check_that_all_fields_are_given_values(thd, table, table_list)) { /* thd->net.report_error is now set, which will abort the next loop */ error= 1; } + if (table_list->prepare_where(thd, 0, TRUE) || + table_list->prepare_check_option(thd)) + error= 1; + while ((values= its++)) { if (fields.elements || !value_count) @@ -596,6 +611,7 @@ abort: SYNOPSIS check_view_insertability() + thd - thread handler view - reference on VIEW IMPLEMENTATION @@ -612,7 +628,7 @@ abort: TRUE - can't be used for insert */ -static bool check_view_insertability(TABLE_LIST *view, query_id_t query_id) +static bool check_view_insertability(THD * thd, TABLE_LIST *view) { uint num= view->view->select_lex.item_list.elements; TABLE *table= view->table; @@ -620,15 +636,25 @@ static bool check_view_insertability(TABLE_LIST *view, query_id_t query_id) *trans_end= trans_start + num; Field_translator *trans; Field **field_ptr= table->field; - query_id_t other_query_id= query_id - 1; + uint used_fields_buff_size= (table->s->fields + 7) / 8; + uchar *used_fields_buff= (uchar*)thd->alloc(used_fields_buff_size); + MY_BITMAP used_fields; DBUG_ENTER("check_key_in_view"); + if (!used_fields_buff) + DBUG_RETURN(TRUE); // EOM + DBUG_ASSERT(view->table != 0 && view->field_translation != 0); + bitmap_init(&used_fields, used_fields_buff, used_fields_buff_size * 8, 0); + bitmap_clear_all(&used_fields); + view->contain_auto_increment= 0; /* check simplicity and prepare unique test of view */ for (trans= trans_start; trans != trans_end; trans++) { + if (!trans->item->fixed && trans->item->fix_fields(thd, &trans->item)) + return TRUE; Item_field *field; /* simple SELECT list entry (field without expression) */ if (!(field= trans->item->filed_for_view_update())) @@ -636,7 +662,6 @@ static bool check_view_insertability(TABLE_LIST *view, query_id_t query_id) if (field->field->unireg_check == Field::NEXT_NUMBER) view->contain_auto_increment= 1; /* prepare unique test */ - field->field->query_id= other_query_id; /* remove collation (or other transparent for update function) if we have it @@ -648,29 +673,12 @@ static bool check_view_insertability(TABLE_LIST *view, query_id_t query_id) { /* Thanks to test above, we know that all columns are of type Item_field */ Item_field *field= (Item_field *)trans->item; - if (field->field->query_id == query_id) + /* check fields belong to table in which we are inserting */ + if (field->field->table == table && + bitmap_fast_test_and_set(&used_fields, field->field->field_index)) DBUG_RETURN(TRUE); - field->field->query_id= query_id; } - /* VIEW contain all fields without default value */ - for (; *field_ptr; field_ptr++) - { - Field *field= *field_ptr; - /* field have not default value */ - if ((field->type() == FIELD_TYPE_BLOB) && - (table->timestamp_field != field || - field->unireg_check == Field::TIMESTAMP_UN_FIELD)) - { - for (trans= trans_start; ; trans++) - { - if (trans == trans_end) - DBUG_RETURN(TRUE); // Field was not part of view - if (((Item_field *)trans->item)->field == *field_ptr) - break; // ok - } - } - } DBUG_RETURN(FALSE); } @@ -698,7 +706,8 @@ static bool mysql_prepare_insert_check_table(THD *thd, TABLE_LIST *table_list, bool insert_into_view= (table_list->view != 0); DBUG_ENTER("mysql_prepare_insert_check_table"); - if (setup_tables(thd, table_list, where, &thd->lex->select_lex.leaf_tables, + if (setup_tables(thd, &thd->lex->select_lex.context, + table_list, where, &thd->lex->select_lex.leaf_tables, select_insert)) DBUG_RETURN(TRUE); @@ -711,7 +720,7 @@ static bool mysql_prepare_insert_check_table(THD *thd, TABLE_LIST *table_list, table_list->view_db.str, table_list->view_name.str); DBUG_RETURN(TRUE); } - DBUG_RETURN(insert_view_fields(&fields, table_list)); + DBUG_RETURN(insert_view_fields(thd, &fields, table_list)); } DBUG_RETURN(FALSE); @@ -741,8 +750,10 @@ bool mysql_prepare_insert(THD *thd, TABLE_LIST *table_list, TABLE *table, enum_duplicates duplic, COND **where, bool select_insert) { + TABLE_LIST *save_table_list= thd->lex->select_lex.context.table_list; bool insert_into_view= (table_list->view != 0); - /* TODO: use this condition for 'WITH CHECK OPTION' */ + bool save_resolve_in_select_list= + thd->lex->select_lex.context.resolve_in_select_list; bool res; TABLE_LIST *next_local; DBUG_ENTER("mysql_prepare_insert"); @@ -750,6 +761,26 @@ bool mysql_prepare_insert(THD *thd, TABLE_LIST *table_list, TABLE *table, (ulong)table_list, (ulong)table, (int)insert_into_view)); + /* + For subqueries in VALUES() we should not see the table in which we are + inserting (for INSERT ... SELECT this is done by changing table_list, + because INSERT ... SELECT share SELECT_LEX it with SELECT. + */ + if (!select_insert) + { + for (SELECT_LEX_UNIT *un= thd->lex->select_lex.first_inner_unit(); + un; + un= un->next_unit()) + { + for (SELECT_LEX *sl= un->first_select(); + sl; + sl= sl->next_select()) + { + sl->context.outer_context= 0; + } + } + } + if (duplic == DUP_UPDATE) { /* it should be allocated before Item::fix_fields() */ @@ -763,29 +794,37 @@ bool mysql_prepare_insert(THD *thd, TABLE_LIST *table_list, TABLE *table, next_local= table_list->next_local; table_list->next_local= 0; + thd->lex->select_lex.context.resolve_in_table_list_only(table_list); if ((values && check_insert_fields(thd, table_list, fields, *values, !insert_into_view)) || - (values && setup_fields(thd, 0, table_list, *values, 0, 0, 0)) || + (values && setup_fields(thd, 0, *values, 0, 0, 0)) || (duplic == DUP_UPDATE && - ((thd->lex->select_lex.no_wrap_view_item= 1, + ((thd->lex->select_lex.no_wrap_view_item= TRUE, (res= check_update_fields(thd, table_list, update_fields)), - thd->lex->select_lex.no_wrap_view_item= 0, + thd->lex->select_lex.no_wrap_view_item= FALSE, res) || - setup_fields(thd, 0, table_list, update_values, 1, 0, 0)))) + setup_fields(thd, 0, update_values, 1, 0, 0)))) DBUG_RETURN(TRUE); table_list->next_local= next_local; - + thd->lex->select_lex.context.table_list= save_table_list; + thd->lex->select_lex.context.resolve_in_select_list= + save_resolve_in_select_list; if (!table) table= table_list->table; - if (!select_insert && unique_table(table_list, table_list->next_global)) + if (!select_insert) { - my_error(ER_UPDATE_TABLE_USED, MYF(0), table_list->table_name); - DBUG_RETURN(TRUE); + Item *fake_conds= 0; + if (unique_table(table_list, table_list->next_global)) + { + my_error(ER_UPDATE_TABLE_USED, MYF(0), table_list->table_name); + DBUG_RETURN(TRUE); + } + thd->lex->select_lex.fix_prepare_information(thd, &fake_conds); + thd->lex->select_lex.first_execution= 0; } if (duplic == DUP_UPDATE || duplic == DUP_REPLACE) table->file->extra(HA_EXTRA_RETRIEVE_PRIMARY_KEY); - thd->lex->select_lex.first_execution= 0; DBUG_RETURN(FALSE); } @@ -1038,7 +1077,8 @@ before_trg_err: Check that all fields with arn't null_fields are used ******************************************************************************/ -int check_that_all_fields_are_given_values(THD *thd, TABLE *entry) +int check_that_all_fields_are_given_values(THD *thd, TABLE *entry, + TABLE_LIST *table_list) { int err= 0; for (Field **field=entry->field ; *field ; field++) @@ -1047,10 +1087,29 @@ int check_that_all_fields_are_given_values(THD *thd, TABLE *entry) ((*field)->flags & NO_DEFAULT_VALUE_FLAG) && ((*field)->real_type() != FIELD_TYPE_ENUM)) { - push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_WARN, - ER_NO_DEFAULT_FOR_FIELD, - ER(ER_NO_DEFAULT_FOR_FIELD), - (*field)->field_name); + bool view= FALSE; + if (table_list) + { + table_list= (table_list->belong_to_view ? + table_list->belong_to_view : + table_list); + view= (table_list->view); + } + if (view) + { + push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_WARN, + ER_NO_DEFAULT_FOR_VIEW_FIELD, + ER(ER_NO_DEFAULT_FOR_VIEW_FIELD), + table_list->view_db.str, + table_list->view_name.str); + } + else + { + push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_WARN, + ER_NO_DEFAULT_FOR_FIELD, + ER(ER_NO_DEFAULT_FOR_FIELD), + (*field)->field_name); + } err= 1; } } @@ -1938,7 +1997,6 @@ bool mysql_insert_select_prepare(THD *thd) SELECT_LEX do not belong to INSERT statement, so we can't add WHERE clause if table is VIEW */ - lex->query_tables->no_where_clause= 1; if (mysql_prepare_insert(thd, lex->query_tables, lex->query_tables->table, lex->field_list, 0, lex->update_list, lex->value_list, @@ -1988,8 +2046,8 @@ select_insert::select_insert(TABLE_LIST *table_list_par, TABLE *table_par, int select_insert::prepare(List &values, SELECT_LEX_UNIT *u) { - int res; LEX *lex= thd->lex; + int res; SELECT_LEX *lex_current_select_save= lex->current_select; DBUG_ENTER("select_insert::prepare"); @@ -2043,8 +2101,11 @@ select_insert::prepare(List &values, SELECT_LEX_UNIT *u) (thd->variables.sql_mode & (MODE_STRICT_TRANS_TABLES | MODE_STRICT_ALL_TABLES))); - DBUG_RETURN(fields->elements && - check_that_all_fields_are_given_values(thd, table)); + res= ((fields->elements && + check_that_all_fields_are_given_values(thd, table, table_list)) || + table_list->prepare_where(thd, 0, TRUE) || + table_list->prepare_check_option(thd)); + DBUG_RETURN(res); } @@ -2290,7 +2351,8 @@ select_create::prepare(List &values, SELECT_LEX_UNIT *u) (thd->variables.sql_mode & (MODE_STRICT_TRANS_TABLES | MODE_STRICT_ALL_TABLES))); - DBUG_RETURN(check_that_all_fields_are_given_values(thd, table)); + DBUG_RETURN(check_that_all_fields_are_given_values(thd, table, + table_list)); } -- cgit v1.2.1 From 428830c50024475e85e12f6b188879c2de536529 Mon Sep 17 00:00:00 2001 From: unknown Date: Mon, 4 Jul 2005 03:24:25 +0300 Subject: After merge fixes Better fix for ON DUPLICATE KEY UPDATE mysql-test/r/group_by.result: After merge fixes mysql-test/r/select.result: Reorder test to match 4.1 tests (will make future merges easier) mysql-test/t/group_by.test: Added --disable_ps_protocol to avoid extra warning mysql-test/t/select.test: Reorder test to match 4.1 tests (will make future merges easier) sql/mysql_priv.h: Better fix for ON DUPLICATE KEY UPDATE sql/sql_base.cc: After merge fixes sql/sql_insert.cc: Better fix for ON DUPLICATE KEY UPDATE (old solution gave problem with item->cached_table) sql/sql_prepare.cc: Better fix for ON DUPLICATE KEY UPDATE --- sql/sql_insert.cc | 51 ++++++++++++++++++++++----------------------------- 1 file changed, 22 insertions(+), 29 deletions(-) (limited to 'sql/sql_insert.cc') diff --git a/sql/sql_insert.cc b/sql/sql_insert.cc index adb1eb01292..576866cb17d 100644 --- a/sql/sql_insert.cc +++ b/sql/sql_insert.cc @@ -327,7 +327,7 @@ bool mysql_insert(THD *thd,TABLE_LIST *table_list, thd->used_tables=0; values= its++; - if (mysql_prepare_insert(thd, table_list, table_list, table, fields, values, + if (mysql_prepare_insert(thd, table_list, table, fields, values, update_fields, update_values, duplic, &unused_conds, FALSE)) goto abort; @@ -734,10 +734,6 @@ static bool mysql_prepare_insert_check_table(THD *thd, TABLE_LIST *table_list, mysql_prepare_insert() thd Thread handler table_list Global/local table list - dup_table_list Tables to be used in ON DUPLICATE KEY - It's either all global tables or only the table we - insert into, depending on if we are using GROUP BY - in the SELECT clause). table Table to insert into (can be NULL if table should be taken from table_list->table) where Where clause (for insert ... select) @@ -759,18 +755,17 @@ static bool mysql_prepare_insert_check_table(THD *thd, TABLE_LIST *table_list, */ bool mysql_prepare_insert(THD *thd, TABLE_LIST *table_list, - TABLE_LIST *dup_table_list, TABLE *table, - List &fields, List_item *values, + TABLE *table, List &fields, List_item *values, List &update_fields, List &update_values, enum_duplicates duplic, COND **where, bool select_insert) { - SELECT_LEX= &thd->lex->select_lex; + SELECT_LEX *select_lex= &thd->lex->select_lex; TABLE_LIST *save_table_list; TABLE_LIST *save_next_local; bool insert_into_view= (table_list->view != 0); bool save_resolve_in_select_list; - bool res; + bool res= 0; DBUG_ENTER("mysql_prepare_insert"); DBUG_PRINT("enter", ("table_list 0x%lx, table 0x%lx, view %d", (ulong)table_list, (ulong)table, @@ -815,15 +810,23 @@ bool mysql_prepare_insert(THD *thd, TABLE_LIST *table_list, select_lex->context.resolve_in_table_list_only(table_list); if ((values && check_insert_fields(thd, table_list, fields, *values, !insert_into_view)) || - (values && setup_fields(thd, 0, *values, 0, 0, 0)) || - setup_fields(thd, 0, update_values, 1, 0, 0)) + (values && setup_fields(thd, 0, *values, 0, 0, 0))) res= TRUE; else if (duplic == DUP_UPDATE) { - select_lex->context.resolve_in_table_list_only(dup_table_list); select_lex->no_wrap_view_item= TRUE; res= check_update_fields(thd, table_list, update_fields); select_lex->no_wrap_view_item= FALSE; + if (select_lex->group_list.elements == 0) + { + /* + When we are not using GROUP BY we can refer to other tables in the + ON DUPLICATE KEY part + */ + table_list->next_local= save_next_local; + } + if (!res) + res= setup_fields(thd, 0, update_values, 1, 0, 0); } table_list->next_local= save_next_local; select_lex->context.table_list= save_table_list; @@ -2013,8 +2016,8 @@ bool delayed_insert::handle_inserts(void) bool mysql_insert_select_prepare(THD *thd) { LEX *lex= thd->lex; + SELECT_LEX *select_lex= &lex->select_lex; TABLE_LIST *first_select_leaf_table; - TABLE_LIST dup_tables; DBUG_ENTER("mysql_insert_select_prepare"); /* @@ -2022,38 +2025,28 @@ bool mysql_insert_select_prepare(THD *thd) clause if table is VIEW */ - dup_tables= *lex->query_tables; - if (lex->select_lex->group_list.elements != 0) - { - /* - When we are using GROUP BY we can't refere to other tables in the - ON DUPLICATE KEY part - */ - dup_tables.local_next= 0; - } - - if (mysql_prepare_insert(thd, lex->query_tables, &dup_tables + if (mysql_prepare_insert(thd, lex->query_tables, lex->query_tables->table, lex->field_list, 0, lex->update_list, lex->value_list, lex->duplicates, - &lex->select_lex.where, TRUE)) + &select_lex->where, TRUE)) DBUG_RETURN(TRUE); /* exclude first table from leaf tables list, because it belong to INSERT */ - DBUG_ASSERT(lex->select_lex.leaf_tables != 0); - lex->leaf_tables_insert= lex->select_lex.leaf_tables; + DBUG_ASSERT(select_lex->leaf_tables != 0); + lex->leaf_tables_insert= select_lex->leaf_tables; /* skip all leaf tables belonged to view where we are insert */ - for (first_select_leaf_table= lex->select_lex.leaf_tables->next_leaf; + for (first_select_leaf_table= select_lex->leaf_tables->next_leaf; first_select_leaf_table && first_select_leaf_table->belong_to_view && first_select_leaf_table->belong_to_view == lex->leaf_tables_insert->belong_to_view; first_select_leaf_table= first_select_leaf_table->next_leaf) {} - lex->select_lex.leaf_tables= first_select_leaf_table; + select_lex->leaf_tables= first_select_leaf_table; DBUG_RETURN(FALSE); } -- cgit v1.2.1 From f56102ae062e637c6af59a521bc60a7ffa2737c4 Mon Sep 17 00:00:00 2001 From: unknown Date: Wed, 6 Jul 2005 18:56:10 -0700 Subject: Fix typos that crept into ChangeSet for fix for Bug #11045. sql/ha_federated.cc: Fix typo sql/sql_insert.cc: Fix typo --- sql/sql_insert.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'sql/sql_insert.cc') diff --git a/sql/sql_insert.cc b/sql/sql_insert.cc index a2f3334d13d..f5d30f69978 100644 --- a/sql/sql_insert.cc +++ b/sql/sql_insert.cc @@ -199,7 +199,7 @@ static int check_update_fields(THD *thd, TABLE_LIST *insert_table_list, List &update_fields) { TABLE *table= insert_table_list->table; - query_id_it timestamp_query_id; + query_id_t timestamp_query_id; LINT_INIT(timestamp_query_id); /* -- cgit v1.2.1 From 799299a5e50b872fb71d55e353983d6c15d782ab Mon Sep 17 00:00:00 2001 From: unknown Date: Mon, 11 Jul 2005 04:33:19 -0600 Subject: sql_insert.cc: Added cast to bool to fix windows compile problem sql/sql_insert.cc: Added cast to bool to fix windows compile problem --- sql/sql_insert.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'sql/sql_insert.cc') diff --git a/sql/sql_insert.cc b/sql/sql_insert.cc index f5d30f69978..7774fce97c0 100644 --- a/sql/sql_insert.cc +++ b/sql/sql_insert.cc @@ -1118,7 +1118,7 @@ int check_that_all_fields_are_given_values(THD *thd, TABLE *entry, table_list= (table_list->belong_to_view ? table_list->belong_to_view : table_list); - view= (table_list->view); + view= (bool)(table_list->view); } if (view) { -- cgit v1.2.1