Commit 43b9ff1b authored by unknown's avatar unknown
Browse files

Merge gkodinov@bk-internal.mysql.com:/home/bk/mysql-5.0-opt

into  magare.gmz:/home/kgeorge/mysql/autopush/B26261-5.0-opt


sql/mysql_priv.h:
  Auto merged
sql/sql_insert.cc:
  Auto merged
sql/sql_prepare.cc:
  Auto merged
mysql-test/r/insert_update.result:
  SCCS merged
mysql-test/t/insert_update.test:
  SCCS merged
parents 1a259b88 2e8e78a4
Loading
Loading
Loading
Loading
+11 −0
Original line number Diff line number Diff line
@@ -236,6 +236,17 @@ INSERT INTO t2 VALUES (1), (3);
INSERT INTO t1 SELECT 1, COUNT(*) FROM t2 ON DUPLICATE KEY UPDATE j= a;
ERROR 42S22: Unknown column 'a' in 'field list'
DROP TABLE t1,t2;
SET SQL_MODE = 'TRADITIONAL';
CREATE TABLE t1 (a INT PRIMARY KEY, b INT NOT NULL);
INSERT INTO t1 (a) VALUES (1);
ERROR HY000: Field 'b' doesn't have a default value
INSERT INTO t1 (a) VALUES (1) ON DUPLICATE KEY UPDATE a = b;
ERROR HY000: Field 'b' doesn't have a default value
INSERT INTO t1 (a) VALUES (1) ON DUPLICATE KEY UPDATE b = b;
ERROR HY000: Field 'b' doesn't have a default value
SELECT * FROM t1;
a	b
DROP TABLE t1;
CREATE TABLE t1 (f1 INT AUTO_INCREMENT PRIMARY KEY,
f2 VARCHAR(5) NOT NULL UNIQUE);
INSERT t1 (f2) VALUES ('test') ON DUPLICATE KEY UPDATE f1 = LAST_INSERT_ID(f1);
+21 −0
Original line number Diff line number Diff line
@@ -163,6 +163,27 @@ INSERT INTO t2 VALUES (1), (3);
INSERT INTO t1 SELECT 1, COUNT(*) FROM t2 ON DUPLICATE KEY UPDATE j= a;
DROP TABLE t1,t2;

#
# Bug #26261: Missing default value isn't noticed in 
#   insert ... on duplicate key update
#
SET SQL_MODE = 'TRADITIONAL';

CREATE TABLE t1 (a INT PRIMARY KEY, b INT NOT NULL);

--error 1364
INSERT INTO t1 (a) VALUES (1);

--error 1364
INSERT INTO t1 (a) VALUES (1) ON DUPLICATE KEY UPDATE a = b;

--error 1364
INSERT INTO t1 (a) VALUES (1) ON DUPLICATE KEY UPDATE b = b;

SELECT * FROM t1;

DROP TABLE t1;

#
# Bug#27033: 0 as LAST_INSERT_ID() after INSERT .. ON DUPLICATE if rows were
#            touched but not actually changed.
+2 −1
Original line number Diff line number Diff line
@@ -835,7 +835,8 @@ bool mysql_prepare_insert(THD *thd, TABLE_LIST *table_list, TABLE *table,
                          List<Item> &fields, List_item *values,
                          List<Item> &update_fields,
                          List<Item> &update_values, enum_duplicates duplic,
                          COND **where, bool select_insert);
                          COND **where, bool select_insert,
                          bool check_fields, bool abort_on_warning);
bool mysql_insert(THD *thd,TABLE_LIST *table,List<Item> &fields,
                  List<List_item> &values, List<Item> &update_fields,
                  List<Item> &update_values, enum_duplicates flag,
+45 −23
Original line number Diff line number Diff line
@@ -473,10 +473,15 @@ bool mysql_insert(THD *thd,TABLE_LIST *table_list,
  thd->proc_info="init";
  thd->used_tables=0;
  values= its++;
  value_count= values->elements;

  if (mysql_prepare_insert(thd, table_list, table, fields, values,
			   update_fields, update_values, duplic, &unused_conds,
                           FALSE))
                           FALSE,
                           (fields.elements || !value_count),
                           !ignore && (thd->variables.sql_mode &
                                       (MODE_STRICT_TRANS_TABLES |
                                        MODE_STRICT_ALL_TABLES))))
    goto abort;

  /* mysql_prepare_insert set table_list->table if it was not set */
@@ -502,7 +507,6 @@ bool mysql_insert(THD *thd,TABLE_LIST *table_list,
  table_list->next_local= 0;
  context->resolve_in_table_list_only(table_list);

  value_count= values->elements;
  while ((values= its++))
  {
    counter++;
@@ -581,18 +585,10 @@ bool mysql_insert(THD *thd,TABLE_LIST *table_list,
    table->file->start_bulk_insert(values_list.elements);

  thd->no_trans_update= 0;
  thd->abort_on_warning= (!ignore &&
                          (thd->variables.sql_mode &
  thd->abort_on_warning= (!ignore && (thd->variables.sql_mode &
                                       (MODE_STRICT_TRANS_TABLES |
                                        MODE_STRICT_ALL_TABLES)));

  if ((fields.elements || !value_count) &&
      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;
  }

  mark_fields_used_by_triggers_for_insert_stmt(thd, table, duplic);

  if (table_list->prepare_where(thd, 0, TRUE) ||
@@ -963,6 +959,10 @@ static bool mysql_prepare_insert_check_table(THD *thd, TABLE_LIST *table_list,
			be taken from table_list->table)    
    where		Where clause (for insert ... select)
    select_insert	TRUE if INSERT ... SELECT statement
    check_fields        TRUE if need to check that all INSERT fields are 
                        given values.
    abort_on_warning    whether to report if some INSERT field is not 
                        assigned as an error (TRUE) or as a warning (FALSE).

  TODO (in far future)
    In cases of:
@@ -983,7 +983,8 @@ bool mysql_prepare_insert(THD *thd, TABLE_LIST *table_list,
                          TABLE *table, List<Item> &fields, List_item *values,
                          List<Item> &update_fields, List<Item> &update_values,
                          enum_duplicates duplic,
                          COND **where, bool select_insert)
                          COND **where, bool select_insert,
                          bool check_fields, bool abort_on_warning)
{
  SELECT_LEX *select_lex= &thd->lex->select_lex;
  Name_resolution_context *context= &select_lex->context;
@@ -1046,10 +1047,22 @@ bool mysql_prepare_insert(THD *thd, TABLE_LIST *table_list,
    table_list->next_local= 0;
    context->resolve_in_table_list_only(table_list);

    if (!(res= check_insert_fields(thd, context->table_list, fields, *values,
    res= check_insert_fields(thd, context->table_list, fields, *values,
                             !insert_into_view, &map) ||
          setup_fields(thd, 0, *values, 0, 0, 0)) 
        && duplic == DUP_UPDATE)
      setup_fields(thd, 0, *values, 0, 0, 0);

    if (!res && check_fields)
    {
      bool saved_abort_on_warning= thd->abort_on_warning;
      thd->abort_on_warning= abort_on_warning;
      res= check_that_all_fields_are_given_values(thd, 
                                                  table ? table : 
                                                  context->table_list->table,
                                                  context->table_list);
      thd->abort_on_warning= saved_abort_on_warning;
    }

    if (!res && duplic == DUP_UPDATE)
    {
      select_lex->no_wrap_view_item= TRUE;
      res= check_update_fields(thd, context->table_list, update_fields, &map);
@@ -2326,7 +2339,7 @@ bool mysql_insert_select_prepare(THD *thd)
                           lex->query_tables->table, lex->field_list, 0,
                           lex->update_list, lex->value_list,
                           lex->duplicates,
                           &select_lex->where, TRUE))
                           &select_lex->where, TRUE, FALSE, FALSE))
    DBUG_RETURN(TRUE);

  /*
@@ -2388,7 +2401,18 @@ select_insert::prepare(List<Item> &values, SELECT_LEX_UNIT *u)
                           !insert_into_view, &map) ||
       setup_fields(thd, 0, values, 0, 0, 0);

  if (info.handle_duplicates == DUP_UPDATE)
  if (!res && fields->elements)
  {
    bool saved_abort_on_warning= thd->abort_on_warning;
    thd->abort_on_warning= !info.ignore && (thd->variables.sql_mode &
                                            (MODE_STRICT_TRANS_TABLES |
                                             MODE_STRICT_ALL_TABLES));
    res= check_that_all_fields_are_given_values(thd, table_list->table, 
                                                table_list);
    thd->abort_on_warning= saved_abort_on_warning;
  }

  if (info.handle_duplicates == DUP_UPDATE && !res)
  {
    Name_resolution_context *context= &lex->select_lex.context;
    Name_resolution_context_state ctx_state;
@@ -2499,9 +2523,7 @@ select_insert::prepare(List<Item> &values, SELECT_LEX_UNIT *u)
                          (thd->variables.sql_mode &
                           (MODE_STRICT_TRANS_TABLES |
                            MODE_STRICT_ALL_TABLES)));
  res= ((fields->elements &&
         check_that_all_fields_are_given_values(thd, table, table_list)) ||
        table_list->prepare_where(thd, 0, TRUE) ||
  res= (table_list->prepare_where(thd, 0, TRUE) ||
        table_list->prepare_check_option(thd));

  if (!res)
+1 −1
Original line number Diff line number Diff line
@@ -1070,7 +1070,7 @@ static bool mysql_test_insert(Prepared_statement *stmt,

    if (mysql_prepare_insert(thd, table_list, table_list->table,
                             fields, values, update_fields, update_values,
                             duplic, &unused_conds, FALSE))
                             duplic, &unused_conds, FALSE, FALSE, FALSE))
      goto error;

    value_count= values->elements;