/**
 * @file bug507.cpp regression case for bug 507 ( "rw-split router does not send last_insert_id() to master" )
 *
 * - "CREATE TABLE t2 (id INT(10) NOT NULL AUTO_INCREMENT, x int,  PRIMARY KEY (id));",
 * - do INSERT using RWsplit
 * - do "select last_insert_id(), @@server_id" using RWSplit and directly to Master, compare @@server_id
 *
 */

/*
Kolbe Kegel 2014-09-01 14:45:56 UTC
After inserting a row via the rw-split router, a call to last_insert_id() can go to a slave, producing bad results.

mariadb> select * from t1;
+----+
| id |
+----+
|  1 |
|  4 |
+----+
2 rows in set (0.00 sec)

mariadb> insert into t1 values ();
Query OK, 1 row affected (0.00 sec)

mariadb> select * from t1;
+----+
| id |
+----+
|  1 |
|  4 |
|  7 |
+----+
3 rows in set (0.00 sec)

mariadb> select last_insert_id();
+------------------+
| last_insert_id() |
+------------------+
|                0 |
+------------------+
1 row in set (0.00 sec)

mariadb> select @@wsrep_node_address, last_insert_id();
+----------------------+------------------+
| @@wsrep_node_address | last_insert_id() |
+----------------------+------------------+
| 192.168.30.31        |                7 |
+----------------------+------------------+
1 row in set (0.00 sec)
Comment 1 Vilho Raatikka 2014-09-01 17:51:45 UTC
last_inserted_id() belongs to UNKNOWN_FUNC class to which many read-only system functions belong too. Thus last_inserted_id() was routed to any slave.

Unfortunately I can't confirm wrong behavior since running the same sequence generates same output when connected directly to MariaDB backend. Perhaps there is something required for the table t1 which is not included here?
Comment 2 Vilho Raatikka 2014-09-01 20:01:35 UTC
An autoincrement attribute was missing.
*/


#include <iostream>
#include "testconnections.h"

const char * sel1 = "select last_insert_id(), @@server_id";

int main(int argc, char *argv[])
{
    TestConnections * Test = new TestConnections(argc, argv);
    Test->set_timeout(60);

    Test->repl->connect();
    Test->maxscales->connect_maxscale(0);

    if (Test->repl->N < 3)
    {
        Test->tprintf("There is not enoght nodes for test\n");
        delete Test;
        exit(1);
    }

    Test->tprintf("Creating table\n");
    fflush(stdout);
    Test->try_query(Test->maxscales->conn_rwsplit[0], (char *) "DROP TABLE IF EXISTS t2");
    Test->try_query(Test->maxscales->conn_rwsplit[0],
                    (char *) "CREATE TABLE t2 (id INT(10) NOT NULL AUTO_INCREMENT, x int,  PRIMARY KEY (id));");
    Test->tprintf("Doing INSERTs\n");
    fflush(stdout);
    Test->try_query(Test->maxscales->conn_rwsplit[0], (char *) "insert into t2 (x) values (1);");

    Test->stop_timeout();
    Test->repl->sync_slaves();

    Test->set_timeout(20);
    Test->tprintf("Trying \n");
    char last_insert_id1[1024];
    char last_insert_id2[1024];
    if ( (
                find_field(
                    Test->maxscales->conn_rwsplit[0], sel1,
                    "@@server_id", &last_insert_id1[0])
                != 0 ) || (
                find_field(
                    Test->repl->nodes[0], sel1,
                    "@@server_id", &last_insert_id2[0])
                != 0 ))
    {
        Test->tprintf("@@server_id fied not found!!\n");
        delete Test;
        exit(1);
    }
    else
    {
        Test->tprintf("'%s' to RWSplit gave @@server_id %s\n", sel1, last_insert_id1);
        Test->tprintf("'%s' directly to master gave @@server_id %s\n", sel1, last_insert_id2);
        Test->add_result(strcmp(last_insert_id1, last_insert_id2),
                         "last_insert_id() are different depending in which order terms are in SELECT\n");
    }

    Test->maxscales->close_maxscale_connections(0);
    Test->repl->close_connections();

    Test->check_maxscale_alive(0);

    int rval = Test->global_result;
    delete Test;
    return rval;
}
