static void test_mysql_insert_id()
{
  my_ulonglong res;
  int rc;

  myheader("test_mysql_insert_id");

  rc= mysql_query(mysql, "drop table if exists t1");
  myquery(rc);
  /* table without auto_increment column */
  rc= mysql_query(mysql, "create table t1 (f1 int, f2 varchar(255), key(f1))");
  myquery(rc);
  rc= mysql_query(mysql, "insert into t1 values (1,'a')");
  myquery(rc);
  res= mysql_insert_id(mysql);
  DIE_UNLESS(res == 0);
  rc= mysql_query(mysql, "insert into t1 values (null,'b')");
  myquery(rc);
  res= mysql_insert_id(mysql);
  DIE_UNLESS(res == 0);
  rc= mysql_query(mysql, "insert into t1 select 5,'c'");
  myquery(rc);
  res= mysql_insert_id(mysql);
  DIE_UNLESS(res == 0);

  /*
    Test for bug #34889: mysql_client_test::test_mysql_insert_id test fails
    sporadically
  */
  rc= mysql_query(mysql, "create table t2 (f1 int not null primary key auto_increment, f2 varchar(255))");
  myquery(rc);
  rc= mysql_query(mysql, "insert into t2 values (null,'b')");
  myquery(rc);
  rc= mysql_query(mysql, "insert into t1 select 5,'c'");
  myquery(rc);
  res= mysql_insert_id(mysql);
  DIE_UNLESS(res == 0);
  rc= mysql_query(mysql, "drop table t2");
  myquery(rc);
  
  rc= mysql_query(mysql, "insert into t1 select null,'d'");
  myquery(rc);
  res= mysql_insert_id(mysql);
  DIE_UNLESS(res == 0);
  rc= mysql_query(mysql, "insert into t1 values (null,last_insert_id(300))");
  myquery(rc);
  res= mysql_insert_id(mysql);
  DIE_UNLESS(res == 300);
  rc= mysql_query(mysql, "insert into t1 select null,last_insert_id(400)");
  myquery(rc);
  res= mysql_insert_id(mysql);
  /*
    Behaviour change: old code used to return 0; but 400 is consistent
    with INSERT VALUES, and the manual's section of mysql_insert_id() does not
    say INSERT SELECT should be different.
  */
  DIE_UNLESS(res == 400);

  /* table with auto_increment column */
  rc= mysql_query(mysql, "create table t2 (f1 int not null primary key auto_increment, f2 varchar(255))");
  myquery(rc);
  rc= mysql_query(mysql, "insert into t2 values (1,'a')");
  myquery(rc);
  res= mysql_insert_id(mysql);
  DIE_UNLESS(res == 1);
  /* this should not influence next INSERT if it doesn't have auto_inc */
  rc= mysql_query(mysql, "insert into t1 values (10,'e')");
  myquery(rc);
  res= mysql_insert_id(mysql);
  DIE_UNLESS(res == 0);

  rc= mysql_query(mysql, "insert into t2 values (null,'b')");
  myquery(rc);
  res= mysql_insert_id(mysql);
  DIE_UNLESS(res == 2);
  rc= mysql_query(mysql, "insert into t2 select 5,'c'");
  myquery(rc);
  res= mysql_insert_id(mysql);
  /*
    Manual says that for multirow insert this should have been 5, but does not
    say for INSERT SELECT. This is a behaviour change: old code used to return
    0. We try to be consistent with INSERT VALUES.
  */
  DIE_UNLESS(res == 5);
  rc= mysql_query(mysql, "insert into t2 select null,'d'");
  myquery(rc);
  res= mysql_insert_id(mysql);
  DIE_UNLESS(res == 6);
  /* with more than one row */
  rc= mysql_query(mysql, "insert into t2 values (10,'a'),(11,'b')");
  myquery(rc);
  res= mysql_insert_id(mysql);
  DIE_UNLESS(res == 11);
  rc= mysql_query(mysql, "insert into t2 select 12,'a' union select 13,'b'");
  myquery(rc);
  res= mysql_insert_id(mysql);
  /*
    Manual says that for multirow insert this should have been 13, but does
    not say for INSERT SELECT. This is a behaviour change: old code used to
    return 0. We try to be consistent with INSERT VALUES.
  */
  DIE_UNLESS(res == 13);
  rc= mysql_query(mysql, "insert into t2 values (null,'a'),(null,'b')");
  myquery(rc);
  res= mysql_insert_id(mysql);
  DIE_UNLESS(res == 14);
  rc= mysql_query(mysql, "insert into t2 select null,'a' union select null,'b'");
  myquery(rc);
  res= mysql_insert_id(mysql);
  DIE_UNLESS(res == 16);
  rc= mysql_query(mysql, "insert into t2 select 12,'a' union select 13,'b'");
  myquery_r(rc);
  rc= mysql_query(mysql, "insert ignore into t2 select 12,'a' union select 13,'b'");
  myquery(rc);
  res= mysql_insert_id(mysql);
  DIE_UNLESS(res == 0);
  rc= mysql_query(mysql, "insert into t2 values (12,'a'),(13,'b')");
  myquery_r(rc);
  res= mysql_insert_id(mysql);
  DIE_UNLESS(res == 0);
  rc= mysql_query(mysql, "insert ignore into t2 values (12,'a'),(13,'b')");
  myquery(rc);
  res= mysql_insert_id(mysql);
  DIE_UNLESS(res == 0);
  /* mixing autogenerated and explicit values */
  rc= mysql_query(mysql, "insert into t2 values (null,'e'),(12,'a'),(13,'b')");
  myquery_r(rc);
  rc= mysql_query(mysql, "insert into t2 values (null,'e'),(12,'a'),(13,'b'),(25,'g')");
  myquery_r(rc);
  rc= mysql_query(mysql, "insert into t2 values (null,last_insert_id(300))");
  myquery(rc);
  res= mysql_insert_id(mysql);
  /*
    according to the manual, this might be 20 or 300, but it looks like
    auto_increment column takes priority over last_insert_id().
  */
  DIE_UNLESS(res == 20);
  /* If first autogenerated number fails and 2nd works: */
  rc= mysql_query(mysql, "drop table t2");
  myquery(rc);
  rc= mysql_query(mysql, "create table t2 (f1 int not null primary key "
                  "auto_increment, f2 varchar(255), unique (f2))");
  myquery(rc);
  rc= mysql_query(mysql, "insert into t2 values (null,'e')");
  res= mysql_insert_id(mysql);
  DIE_UNLESS(res == 1);
  rc= mysql_query(mysql, "insert ignore into t2 values (null,'e'),(null,'a'),(null,'e')");
  myquery(rc);
  res= mysql_insert_id(mysql);
  DIE_UNLESS(res == 2);
  /* If autogenerated fails and explicit works: */
  rc= mysql_query(mysql, "insert ignore into t2 values (null,'e'),(12,'c'),(null,'d')");
  myquery(rc);
  res= mysql_insert_id(mysql);
  /*
    Behaviour change: old code returned 3 (first autogenerated, even if it
    fails); we now return first successful autogenerated.
  */
  DIE_UNLESS(res == 13);
  /* UPDATE may update mysql_insert_id() if it uses LAST_INSERT_ID(#) */
  rc= mysql_query(mysql, "update t2 set f1=14 where f1=12");
  myquery(rc);
  res= mysql_insert_id(mysql);
  DIE_UNLESS(res == 0);
  rc= mysql_query(mysql, "update t2 set f1=0 where f1=14");
  myquery(rc);
  res= mysql_insert_id(mysql);
  DIE_UNLESS(res == 0);
  rc= mysql_query(mysql, "update t2 set f2=last_insert_id(372) where f1=0");
  myquery(rc);
  res= mysql_insert_id(mysql);
  DIE_UNLESS(res == 372);
  /* check that LAST_INSERT_ID() does not update mysql_insert_id(): */
  rc= mysql_query(mysql, "insert into t2 values (null,'g')");
  myquery(rc);
  res= mysql_insert_id(mysql);
  DIE_UNLESS(res == 15);
  rc= mysql_query(mysql, "update t2 set f2=(@li:=last_insert_id()) where f1=15");
  myquery(rc);
  res= mysql_insert_id(mysql);
  DIE_UNLESS(res == 0);
  /*
    Behaviour change: now if ON DUPLICATE KEY UPDATE updates a row,
    mysql_insert_id() returns the id of the row, instead of not being
    affected.
  */
  rc= mysql_query(mysql, "insert into t2 values (null,@li) on duplicate key "
                  "update f2=concat('we updated ',f2)");
  myquery(rc);
  res= mysql_insert_id(mysql);
  DIE_UNLESS(res == 15);

  rc= mysql_query(mysql, "drop table t1,t2");
  myquery(rc);
}