diff options
author | unknown <pappa@c-4a09e253.1238-1-64736c10.cust.bredbandsbolaget.se> | 2005-08-25 13:11:38 -0400 |
---|---|---|
committer | unknown <pappa@c-4a09e253.1238-1-64736c10.cust.bredbandsbolaget.se> | 2005-08-25 13:11:38 -0400 |
commit | 5c0dc1ace8b803f799c328fae1c6d40c2b47f5ea (patch) | |
tree | 86faf87634c19937967b360a0dd1413fc9eb2879 /sql/sql_insert.cc | |
parent | da2ff990c7e7f0a8796f43513277b8a8322102ce (diff) | |
parent | 7887d8b808b4938e1d3673824afb4c4604018274 (diff) | |
download | mariadb-git-5c0dc1ace8b803f799c328fae1c6d40c2b47f5ea.tar.gz |
Merge mronstrom@bk-internal.mysql.com:/home/bk/mysql-5.0
into c-4a09e253.1238-1-64736c10.cust.bredbandsbolaget.se:/home/pappa/mysql-5.1
BitKeeper/deleted/.del-Grep.cpp~ad798e9ae519d667:
Auto merged
BitKeeper/deleted/.del-Grep.hpp~b05e3af6cfabe387:
Auto merged
BitKeeper/deleted/.del-GrepInit.cpp~df28ab3a892455fd:
Auto merged
BitKeeper/deleted/.del-Makefile.am~f73be89578d3b6cc:
Auto merged
BitKeeper/deleted/.del-Makefile~b293ae88e4394490:
Auto merged
BitKeeper/deleted/.del-Makefile~e0b7d67078f0fae0:
Auto merged
BitKeeper/deleted/.del-grep_systab_test.cpp~c7305578bec8cb62:
Auto merged
BitKeeper/etc/config:
Auto merged
config/ac-macros/ha_ndbcluster.m4:
Auto merged
include/my_global.h:
Auto merged
mysql-test/mysql-test-run.pl:
Auto merged
BitKeeper/deleted/.del-testGrep.cpp~2106eb0a6bf2a1b5:
Auto merged
mysql-test/r/alter_table.result:
Auto merged
mysql-test/r/grant.result:
Auto merged
mysql-test/r/ps_6bdb.result:
Auto merged
mysql-test/r/ps_7ndb.result:
Auto merged
mysys/Makefile.am:
Auto merged
scripts/make_win_src_distribution.sh:
Auto merged
sql/field.cc:
Auto merged
sql/ha_berkeley.cc:
Auto merged
sql/ha_berkeley.h:
Auto merged
sql/ha_heap.h:
Auto merged
sql/ha_innodb.cc:
Auto merged
sql/ha_innodb.h:
Auto merged
sql/ha_ndbcluster.cc:
Auto merged
sql/handler.cc:
Auto merged
sql/handler.h:
Auto merged
sql/item.cc:
Auto merged
sql/item_subselect.cc:
Auto merged
sql/lex.h:
Auto merged
sql/lock.cc:
Auto merged
sql/log_event.cc:
Auto merged
sql/mysqld.cc:
Auto merged
sql/set_var.cc:
Auto merged
sql/slave.cc:
Auto merged
sql/sp.cc:
Auto merged
sql/sql_acl.cc:
Auto merged
sql/sql_cache.cc:
Auto merged
sql/sql_class.h:
Auto merged
sql/sql_delete.cc:
Auto merged
sql/sql_handler.cc:
Auto merged
sql/sql_help.cc:
Auto merged
sql/sql_insert.cc:
Auto merged
sql/sql_lex.cc:
Auto merged
sql/sql_lex.h:
Auto merged
sql/sql_load.cc:
Auto merged
sql/sql_parse.cc:
Auto merged
sql/sql_select.cc:
Auto merged
sql/sql_select.h:
Auto merged
sql/sql_show.cc:
Auto merged
sql/sql_table.cc:
Auto merged
sql/sql_update.cc:
Auto merged
sql/sql_yacc.yy:
Auto merged
sql/table.cc:
Auto merged
sql/table.h:
Auto merged
storage/heap/hp_delete.c:
Auto merged
storage/innobase/btr/btr0pcur.c:
Auto merged
storage/innobase/btr/btr0sea.c:
Auto merged
storage/innobase/include/read0read.h:
Auto merged
storage/innobase/include/srv0srv.h:
Auto merged
storage/innobase/include/trx0trx.h:
Auto merged
storage/innobase/include/univ.i:
Auto merged
storage/innobase/lock/lock0lock.c:
Auto merged
storage/innobase/read/read0read.c:
Auto merged
storage/innobase/row/row0ins.c:
Auto merged
storage/innobase/row/row0sel.c:
Auto merged
storage/innobase/row/row0umod.c:
Auto merged
storage/innobase/row/row0upd.c:
Auto merged
storage/innobase/srv/srv0srv.c:
Auto merged
storage/innobase/srv/srv0start.c:
Auto merged
storage/innobase/trx/trx0trx.c:
Auto merged
storage/myisam/ft_boolean_search.c:
Auto merged
storage/myisam/myisampack.c:
Auto merged
storage/myisammrg/myrg_static.c:
Auto merged
storage/ndb/include/kernel/AttributeDescriptor.hpp:
Auto merged
storage/ndb/include/kernel/BlockNumbers.h:
Auto merged
storage/ndb/include/kernel/GlobalSignalNumbers.h:
Auto merged
storage/ndb/include/kernel/kernel_types.h:
Auto merged
storage/ndb/include/kernel/signaldata/AlterTable.hpp:
Auto merged
storage/ndb/include/ndbapi/NdbDictionary.hpp:
Auto merged
storage/ndb/include/portlib/NdbTCP.h:
Auto merged
storage/ndb/src/common/debugger/BlockNames.cpp:
Auto merged
storage/ndb/src/common/logger/LogHandler.cpp:
Auto merged
storage/ndb/src/common/portlib/NdbTCP.cpp:
Auto merged
storage/ndb/src/common/portlib/win32/NdbTCP.c:
Auto merged
storage/ndb/src/common/transporter/TransporterRegistry.cpp:
Auto merged
storage/ndb/src/kernel/Makefile.am:
Auto merged
storage/ndb/src/kernel/SimBlockList.cpp:
Auto merged
storage/ndb/src/kernel/blocks/Makefile.am:
Auto merged
storage/ndb/src/kernel/blocks/cmvmi/Cmvmi.cpp:
Auto merged
storage/ndb/src/kernel/blocks/dbacc/Dbacc.hpp:
Auto merged
storage/ndb/src/kernel/blocks/dbacc/DbaccInit.cpp:
Auto merged
storage/ndb/src/kernel/blocks/dbacc/DbaccMain.cpp:
Auto merged
storage/ndb/src/kernel/blocks/dbdict/Dbdict.cpp:
Auto merged
storage/ndb/src/kernel/blocks/dbdict/Dbdict.hpp:
Auto merged
storage/ndb/src/kernel/blocks/dbdict/printSchemaFile.cpp:
Auto merged
storage/ndb/src/kernel/blocks/dbdih/DbdihMain.cpp:
Auto merged
storage/ndb/src/kernel/blocks/dblqh/Dblqh.hpp:
Auto merged
storage/ndb/src/kernel/blocks/dblqh/DblqhMain.cpp:
Auto merged
storage/ndb/src/kernel/blocks/dblqh/redoLogReader/redoLogFileReader.cpp:
Auto merged
storage/ndb/src/kernel/blocks/dbtc/Dbtc.hpp:
Auto merged
storage/ndb/src/kernel/blocks/dbtc/DbtcMain.cpp:
Auto merged
storage/ndb/src/kernel/blocks/ndbcntr/NdbcntrMain.cpp:
Auto merged
storage/ndb/src/kernel/blocks/qmgr/Qmgr.hpp:
Auto merged
storage/ndb/src/kernel/blocks/qmgr/QmgrInit.cpp:
Auto merged
storage/ndb/src/kernel/blocks/qmgr/QmgrMain.cpp:
Auto merged
storage/ndb/src/kernel/blocks/suma/Suma.cpp:
Auto merged
storage/ndb/src/kernel/vm/SimulatedBlock.cpp:
Auto merged
storage/ndb/src/kernel/vm/SimulatedBlock.hpp:
Auto merged
storage/ndb/src/mgmapi/mgmapi.cpp:
Auto merged
storage/ndb/src/mgmsrv/MgmtSrvr.cpp:
Auto merged
storage/ndb/src/ndbapi/DictCache.cpp:
Auto merged
storage/ndb/src/ndbapi/DictCache.hpp:
Auto merged
storage/ndb/src/ndbapi/NdbDictionaryImpl.cpp:
Auto merged
storage/ndb/src/ndbapi/TransporterFacade.cpp:
Auto merged
storage/ndb/tools/Makefile.am:
Auto merged
storage/ndb/tools/ndb_condig.cpp:
Auto merged
strings/ctype-big5.c:
Auto merged
strings/ctype-ucs2.c:
Auto merged
support-files/mysql.spec.sh:
Auto merged
VC++Files/sql/mysqld.dsp:
Manual 5.0 - 5.1 merge
configure.in:
Manual 5.0 - 5.1 merge
sql/mysql_priv.h:
Manual 5.0 - 5.1 merge
sql/share/errmsg.txt:
Manual 5.0 - 5.1 merge
sql/sql_base.cc:
Manual 5.0 - 5.1 merge
sql/sql_prepare.cc:
Manual 5.0 - 5.1 merge
storage/ndb/src/common/util/version.c:
Manual 5.0 - 5.1 merge
storage/ndb/src/kernel/blocks/dblqh/Makefile.am:
Manual 5.0 - 5.1 merge
Diffstat (limited to 'sql/sql_insert.cc')
-rw-r--r-- | sql/sql_insert.cc | 191 |
1 files changed, 158 insertions, 33 deletions
diff --git a/sql/sql_insert.cc b/sql/sql_insert.cc index 6e83017a4e4..869ae688e34 100644 --- a/sql/sql_insert.cc +++ b/sql/sql_insert.cc @@ -111,12 +111,15 @@ static int check_insert_fields(THD *thd, TABLE_LIST *table_list, } else { // Part field list - 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; + SELECT_LEX *select_lex= &thd->lex->select_lex; + Name_resolution_context *context= &select_lex->context; + TABLE_LIST *save_next_local; + TABLE_LIST *save_table_list; + TABLE_LIST *save_first_name_resolution_table; + TABLE_LIST *save_next_name_resolution_table; + bool save_resolve_in_select_list; int res; + if (fields.elements != values.elements) { my_error(ER_WRONG_VALUE_COUNT_ON_ROW, MYF(0), 1L); @@ -124,8 +127,22 @@ static int check_insert_fields(THD *thd, TABLE_LIST *table_list, } thd->dupp_field=0; - thd->lex->select_lex.no_wrap_view_item= TRUE; - /* fields only from first table */ + select_lex->no_wrap_view_item= TRUE; + + /* Save the state of the current name resolution context. */ + save_table_list= context->table_list; + save_first_name_resolution_table= context->first_name_resolution_table; + save_next_name_resolution_table= (context->first_name_resolution_table) ? + context->first_name_resolution_table-> + next_name_resolution_table : + NULL; + save_resolve_in_select_list= context->resolve_in_select_list; + save_next_local= table_list->next_local; + + /* + Perform name resolution only in the first table - 'table_list', + which is the table that is inserted into. + */ table_list->next_local= 0; context->resolve_in_table_list_only(table_list); /* @@ -133,12 +150,20 @@ static int check_insert_fields(THD *thd, TABLE_LIST *table_list, parameter to 2. This sets the bit in the write_set for each field. */ res= setup_fields(thd, 0, fields, 2, 0, 0); - table_list->next_local= save_next; + + /* Restore the current context. */ + table_list->next_local= save_next_local; + context->table_list= save_table_list; + context->first_name_resolution_table= save_first_name_resolution_table; + if (context->first_name_resolution_table) + context->first_name_resolution_table-> + next_name_resolution_table= save_next_name_resolution_table; + context->resolve_in_select_list= save_resolve_in_select_list; 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) { /* it is join view => we need to find table for update */ @@ -267,9 +292,13 @@ bool mysql_insert(THD *thd,TABLE_LIST *table_list, ulonglong id; COPY_INFO info; TABLE *table= 0; - TABLE_LIST *next_local; + TABLE_LIST *save_table_list; + TABLE_LIST *save_next_local; + TABLE_LIST *save_first_name_resolution_table; + TABLE_LIST *save_next_name_resolution_table; List_iterator_fast<List_item> its(values_list); List_item *values; + Name_resolution_context *context; #ifndef EMBEDDED_LIBRARY char *query= thd->query; #endif @@ -348,9 +377,23 @@ 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; - next_local= table_list->next_local; + context= &thd->lex->select_lex.context; + /* Save the state of the current name resolution context. */ + save_table_list= context->table_list; + save_first_name_resolution_table= context->first_name_resolution_table; + save_next_name_resolution_table= (context->first_name_resolution_table) ? + context->first_name_resolution_table-> + next_name_resolution_table : + NULL; + save_next_local= table_list->next_local; + + /* + Perform name resolution only in the first table - 'table_list', + which is the table that is inserted into. + */ table_list->next_local= 0; - thd->lex->select_lex.context.resolve_in_table_list_only(table_list); + context->resolve_in_table_list_only(table_list); + value_count= values->elements; while ((values= its++)) { @@ -364,7 +407,14 @@ bool mysql_insert(THD *thd,TABLE_LIST *table_list, goto abort; } its.rewind (); - table_list->next_local= next_local; + + /* Restore the current context. */ + table_list->next_local= save_next_local; + context->first_name_resolution_table= save_first_name_resolution_table; + if (context->first_name_resolution_table) + context->first_name_resolution_table-> + next_name_resolution_table= save_next_name_resolution_table; + /* Fill in the given fields and dump it to the table file */ @@ -720,6 +770,7 @@ static bool mysql_prepare_insert_check_table(THD *thd, TABLE_LIST *table_list, DBUG_ENTER("mysql_prepare_insert_check_table"); if (setup_tables(thd, &thd->lex->select_lex.context, + &thd->lex->select_lex.top_join_list, table_list, where, &thd->lex->select_lex.leaf_tables, select_insert)) DBUG_RETURN(TRUE); @@ -774,10 +825,13 @@ bool mysql_prepare_insert(THD *thd, TABLE_LIST *table_list, COND **where, bool select_insert) { SELECT_LEX *select_lex= &thd->lex->select_lex; + Name_resolution_context *context= &select_lex->context; TABLE_LIST *save_table_list; TABLE_LIST *save_next_local; + TABLE_LIST *save_first_name_resolution_table; + TABLE_LIST *save_next_name_resolution_table; + bool save_resolve_in_select_list; bool insert_into_view= (table_list->view != 0); - bool save_resolve_in_select_list; bool res= 0; DBUG_ENTER("mysql_prepare_insert"); DBUG_PRINT("enter", ("table_list 0x%lx, table 0x%lx, view %d", @@ -815,35 +869,58 @@ bool mysql_prepare_insert(THD *thd, TABLE_LIST *table_list, select_insert)) DBUG_RETURN(TRUE); - save_table_list= select_lex->context.table_list; - save_resolve_in_select_list= select_lex->context.resolve_in_select_list; - save_next_local= table_list->next_local; + /* Save the state of the current name resolution context. */ + save_table_list= context->table_list; + /* Here first_name_resolution_table points to the first select table. */ + save_first_name_resolution_table= context->first_name_resolution_table; + save_next_name_resolution_table= (context->first_name_resolution_table) ? + context->first_name_resolution_table-> + next_name_resolution_table : + NULL; + save_resolve_in_select_list= context->resolve_in_select_list; + save_next_local= table_list->next_local; + /* + Perform name resolution only in the first table - 'table_list', + which is the table that is inserted into. + */ table_list->next_local= 0; - 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))) - res= TRUE; - else if (duplic == DUP_UPDATE) + context->resolve_in_table_list_only(table_list); + + /* Prepare the fields in the statement. */ + if (values && + !(res= check_insert_fields(thd, context->table_list, fields, *values, + !insert_into_view) || + setup_fields(thd, 0, *values, 0, 0, 0)) && + duplic == DUP_UPDATE) { select_lex->no_wrap_view_item= TRUE; - res= check_update_fields(thd, table_list, update_fields); + res= check_update_fields(thd, context->table_list, update_fields); select_lex->no_wrap_view_item= FALSE; + /* + When we are not using GROUP BY we can refer to other tables in the + ON DUPLICATE KEY part. + */ 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; + context->table_list->next_local= save_next_local; + /* first_name_resolution_table was set by resolve_in_table_list_only() */ + context->first_name_resolution_table-> + next_name_resolution_table= save_next_local; } if (!res) res= setup_fields(thd, 0, update_values, 1, 0, 0); } + + /* Restore the current context. */ table_list->next_local= save_next_local; - select_lex->context.table_list= save_table_list; - select_lex->context.resolve_in_select_list= save_resolve_in_select_list; + context->table_list= save_table_list; + context->first_name_resolution_table= save_first_name_resolution_table; + if (context->first_name_resolution_table) + context->first_name_resolution_table-> + next_name_resolution_table= save_next_name_resolution_table; + context->resolve_in_select_list= save_resolve_in_select_list; + if (res) DBUG_RETURN(res); @@ -2102,7 +2179,55 @@ select_insert::prepare(List<Item> &values, SELECT_LEX_UNIT *u) */ lex->current_select= &lex->select_lex; res= check_insert_fields(thd, table_list, *fields, values, - !insert_into_view); + !insert_into_view) || + setup_fields(thd, 0, values, 0, 0, 0); + + if (info.handle_duplicates == DUP_UPDATE) + { + /* Save the state of the current name resolution context. */ + Name_resolution_context *context= &lex->select_lex.context; + TABLE_LIST *save_table_list; + TABLE_LIST *save_next_local; + TABLE_LIST *save_first_name_resolution_table; + TABLE_LIST *save_next_name_resolution_table; + save_table_list= context->table_list; + save_first_name_resolution_table= context->first_name_resolution_table; + save_next_name_resolution_table= (context->first_name_resolution_table) ? + context->first_name_resolution_table-> + next_name_resolution_table : + NULL; + save_next_local= table_list->next_local; + + /* Perform name resolution only in the first table - 'table_list'. */ + table_list->next_local= 0; + context->resolve_in_table_list_only(table_list); + + lex->select_lex.no_wrap_view_item= TRUE; + res= res || check_update_fields(thd, context->table_list, + *info.update_fields); + lex->select_lex.no_wrap_view_item= FALSE; + /* + When we are not using GROUP BY we can refer to other tables in the + ON DUPLICATE KEY part + */ + if (lex->select_lex.group_list.elements == 0) + { + context->table_list->next_local= save_next_local; + /* first_name_resolution_table was set by resolve_in_table_list_only() */ + context->first_name_resolution_table-> + next_name_resolution_table= save_next_local; + } + res= res || setup_fields(thd, 0, *info.update_values, 1, 0, 0); + + /* Restore the current context. */ + table_list->next_local= save_next_local; + context->first_name_resolution_table= save_first_name_resolution_table; + if (context->first_name_resolution_table) + context->first_name_resolution_table-> + next_name_resolution_table= save_next_name_resolution_table; + + } + lex->current_select= lex_current_select_save; if (res) DBUG_RETURN(1); |