Commit c9a0e4ad authored by unknown's avatar unknown
Browse files

Merge bk-internal.mysql.com:/home/bk/mysql-4.1

into pcgem.rdg.cyberkinetica.com:/usr/home/acurtis/work/wl2274.2

parents c04900be 46364ddb
Loading
Loading
Loading
Loading
+62 −0
Original line number Diff line number Diff line
@@ -105,3 +105,65 @@ a b
8	28
9	29
drop table t1;
CREATE TABLE t1 (a INT, b INT, c INT, UNIQUE (A), UNIQUE(B));
INSERT t1 VALUES (1,2,10), (3,4,20);
INSERT t1 SELECT 5,6,30 FROM DUAL ON DUPLICATE KEY UPDATE c=c+100;
SELECT * FROM t1;
a	b	c
1	2	10
3	4	20
5	6	30
INSERT t1 SELECT 5,7,40 FROM DUAL ON DUPLICATE KEY UPDATE c=c+100;
SELECT * FROM t1;
a	b	c
1	2	10
3	4	20
5	6	130
INSERT t1 SELECT 8,4,50 FROM DUAL ON DUPLICATE KEY UPDATE c=c+1000;
SELECT * FROM t1;
a	b	c
1	2	10
3	4	1020
5	6	130
INSERT t1 SELECT 1,4,60 FROM DUAL ON DUPLICATE KEY UPDATE c=c+10000;
SELECT * FROM t1;
a	b	c
1	2	10010
3	4	1020
5	6	130
INSERT t1 SELECT 1,9,70 FROM DUAL ON DUPLICATE KEY UPDATE c=c+100000, b=4;
ERROR 23000: Duplicate entry '4' for key 2
SELECT * FROM t1;
a	b	c
1	2	10010
3	4	1020
5	6	130
TRUNCATE TABLE t1;
INSERT t1 VALUES (1,2,10), (3,4,20);
CREATE TABLE t2 (x INT, y INT, z INT, d INT);
INSERT t2 VALUES (5,6,30,1), (7,4,40,1), (8,9,60,1);
INSERT t2 VALUES (2,1,11,2), (7,4,40,2);
INSERT t1 SELECT x,y,z FROM t2 WHERE d=1 ON DUPLICATE KEY UPDATE c=c+100;
SELECT * FROM t1;
a	b	c
1	2	10
3	4	120
5	6	30
8	9	60
INSERT t1 SET a=5 ON DUPLICATE KEY UPDATE b=0;
SELECT * FROM t1;
a	b	c
1	2	10
3	4	120
5	0	30
8	9	60
INSERT t1 SELECT x,y,z FROM t2 WHERE d=2 ON DUPLICATE KEY UPDATE c=c+VALUES(a);
SELECT *, VALUES(a) FROM t1;
a	b	c	VALUES(a)
1	2	10	NULL
3	4	127	NULL
5	0	30	NULL
8	9	60	NULL
2	1	11	NULL
DROP TABLE t1;
DROP TABLE t2;
+31 −0
Original line number Diff line number Diff line
@@ -48,3 +48,34 @@ disable_info;

select * from t1;
drop table t1;

# WorkLog #2274 - enable INSERT .. SELECT .. UPDATE syntax
# Same tests as beginning of this test except that insert source
# is a result from a select statement
#
CREATE TABLE t1 (a INT, b INT, c INT, UNIQUE (A), UNIQUE(B));
INSERT t1 VALUES (1,2,10), (3,4,20);
INSERT t1 SELECT 5,6,30 FROM DUAL ON DUPLICATE KEY UPDATE c=c+100;
SELECT * FROM t1;
INSERT t1 SELECT 5,7,40 FROM DUAL ON DUPLICATE KEY UPDATE c=c+100;
SELECT * FROM t1;
INSERT t1 SELECT 8,4,50 FROM DUAL ON DUPLICATE KEY UPDATE c=c+1000;
SELECT * FROM t1;
INSERT t1 SELECT 1,4,60 FROM DUAL ON DUPLICATE KEY UPDATE c=c+10000;
SELECT * FROM t1;
-- error 1062
INSERT t1 SELECT 1,9,70 FROM DUAL ON DUPLICATE KEY UPDATE c=c+100000, b=4;
SELECT * FROM t1;
TRUNCATE TABLE t1;
INSERT t1 VALUES (1,2,10), (3,4,20);
CREATE TABLE t2 (x INT, y INT, z INT, d INT);
INSERT t2 VALUES (5,6,30,1), (7,4,40,1), (8,9,60,1);
INSERT t2 VALUES (2,1,11,2), (7,4,40,2);
INSERT t1 SELECT x,y,z FROM t2 WHERE d=1 ON DUPLICATE KEY UPDATE c=c+100;
SELECT * FROM t1;
INSERT t1 SET a=5 ON DUPLICATE KEY UPDATE b=0;
SELECT * FROM t1;
INSERT t1 SELECT x,y,z FROM t2 WHERE d=2 ON DUPLICATE KEY UPDATE c=c+VALUES(a);
SELECT *, VALUES(a) FROM t1;
DROP TABLE t1;
DROP TABLE t2;
+0 −1
Original line number Diff line number Diff line
@@ -362,7 +362,6 @@ bool check_merge_table_access(THD *thd, char *db,
			      TABLE_LIST *table_list);
int multi_update_precheck(THD *thd, TABLE_LIST *tables);
int multi_delete_precheck(THD *thd, TABLE_LIST *tables, uint *table_count);
int insert_select_precheck(THD *thd, TABLE_LIST *tables);
int update_precheck(THD *thd, TABLE_LIST *tables);
int delete_precheck(THD *thd, TABLE_LIST *tables);
int insert_precheck(THD *thd, TABLE_LIST *tables);
+10 −0
Original line number Diff line number Diff line
@@ -1238,6 +1238,16 @@ class select_insert :public select_result_interceptor {
    bzero((char*) &info,sizeof(info));
    info.handle_duplicates=duplic;
  }
  select_insert(TABLE *table_par, List<Item> *fields_par,
		List<Item> *update_fields, List<Item> *update_values,
		enum_duplicates duplic)
    :table(table_par), fields(fields_par), last_insert_id(0)
  {
    bzero((char*) &info,sizeof(info));
    info.handle_duplicates=duplic;
    info.update_fields= update_fields;
    info.update_values= update_values;
  }
  ~select_insert();
  int prepare(List<Item> &list, SELECT_LEX_UNIT *u);
  bool send_data(List<Item> &items);
+15 −12
Original line number Diff line number Diff line
@@ -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])))
Loading