diff options
author | unknown <acurtis@pcgem.rdg.cyberkinetica.com> | 2004-12-13 12:26:28 +0000 |
---|---|---|
committer | unknown <acurtis@pcgem.rdg.cyberkinetica.com> | 2004-12-13 12:26:28 +0000 |
commit | 46364ddb1978802ad9bf5418738b03d0cfe8bd61 (patch) | |
tree | 74dc7fe4fb76d0fd7e5bf58eca907c162b9d3b30 /sql/sql_insert.cc | |
parent | 0a3590f6d08342512deecfe15e91424eb01c0be4 (diff) | |
download | mariadb-git-46364ddb1978802ad9bf5418738b03d0cfe8bd61.tar.gz |
WL#2274 - INSERT..SELECT..UPDATE
UPDATE clause conflicts with SELECT for use of item_list field.
Alter UPDATE clause to use new lex field update_list
Tests included
mysql-test/r/insert_update.result:
WL#2274
New tests for INSERT..SELECT..UPDATE
mysql-test/t/insert_update.test:
WL#2274
New tests for INSERT..SELECT..UPDATE
sql/mysql_priv.h:
Remove function - insert_select_precheck()
sql/sql_class.h:
WL#2274
New constructor for class select_insert
sql/sql_insert.cc:
WL#2274
Move code into mysql_prepare_insert
Add checks as param values may be NULL
sql/sql_lex.cc:
WL#2274
initialize lex->update_list
sql/sql_lex.h:
WL#2274
New field in LEX: update_list
sql/sql_parse.cc:
WL#2274
INSERT..UPDATE clause now populates lex->update_list
Remove redundant function: insert_select_precheck()
sql/sql_prepare.cc:
WL#2274
invoke insert_precheck() instead of insert_select_precheck()
sql/sql_yacc.yy:
WL#2274
Enable INSERT..SELECT..UPDATE syntax
New rule - insert_update_list, to populate lex->update_list
Diffstat (limited to 'sql/sql_insert.cc')
-rw-r--r-- | sql/sql_insert.cc | 27 |
1 files changed, 15 insertions, 12 deletions
diff --git a/sql/sql_insert.cc b/sql/sql_insert.cc index 768acb0cf9e..ce64890523a 100644 --- a/sql/sql_insert.cc +++ b/sql/sql_insert.cc @@ -197,15 +197,6 @@ int mysql_insert(THD *thd,TABLE_LIST *table_list, thd->used_tables=0; values= its++; - if (duplic == DUP_UPDATE && !table->insert_values) - { - /* it should be allocated before Item::fix_fields() */ - table->insert_values= - (byte *)alloc_root(thd->mem_root, table->rec_buff_length); - if (!table->insert_values) - goto abort; - } - if (mysql_prepare_insert(thd, table_list, insert_table_list, table, fields, values, update_fields, update_values, duplic)) @@ -448,14 +439,24 @@ int mysql_prepare_insert(THD *thd, TABLE_LIST *table_list, enum_duplicates duplic) { DBUG_ENTER("mysql_prepare_insert"); - if (check_insert_fields(thd, table, fields, *values, 1) || + if (duplic == DUP_UPDATE && !table->insert_values) + { + /* it should be allocated before Item::fix_fields() */ + table->insert_values= + (byte *)alloc_root(thd->mem_root, table->rec_buff_length); + if (!table->insert_values) + DBUG_RETURN(-1); + } + if ((values && check_insert_fields(thd, table, fields, *values, 1)) || setup_tables(insert_table_list) || - setup_fields(thd, 0, insert_table_list, *values, 0, 0, 0) || + (values && setup_fields(thd, 0, insert_table_list, *values, 0, 0, 0)) || (duplic == DUP_UPDATE && (setup_fields(thd, 0, insert_table_list, update_fields, 1, 0, 0) || setup_fields(thd, 0, insert_table_list, update_values, 1, 0, 0)))) DBUG_RETURN(-1); - if (find_real_table_in_list(table_list->next, + if ((thd->lex->sql_command==SQLCOM_INSERT || + thd->lex->sql_command==SQLCOM_REPLACE) && + find_real_table_in_list(table_list->next, table_list->db, table_list->real_name)) { my_error(ER_UPDATE_TABLE_USED, MYF(0), table_list->real_name); @@ -550,8 +551,10 @@ int write_record(TABLE *table,COPY_INFO *info) that matches, is updated. If update causes a conflict again, an error is returned */ + DBUG_ASSERT(table->insert_values != NULL); store_record(table,insert_values); restore_record(table,record[1]); + DBUG_ASSERT(info->update_fields->elements==info->update_values->elements); if (fill_record(*info->update_fields, *info->update_values, 0)) goto err; if ((error=table->file->update_row(table->record[1],table->record[0]))) |