/**
 * @file bug565.cpp  regression case for bug 565 ( "Clients CLIENT_FOUND_ROWS setting is ignored by maxscale" ) MAX-311
 *
 * - open connection with CLIENT_FOUND_ROWS flag
 * - CREATE TABLE t1(id INT PRIMARY KEY, val INT, msg VARCHAR(100))
 * - INSERT INTO t1 VALUES (1, 1, 'foo'), (2, 1, 'bar'), (3, 2, 'baz'), (4, 2, 'abc')"
 * - check 'affected_rows' for folloing UPDATES:
 *   + UPDATE t1 SET msg='xyz' WHERE val=2" (expect 2)
 *   + UPDATE t1 SET msg='xyz' WHERE val=2 (expect 0)
 *   + UPDATE t1 SET msg='xyz' WHERE val=2 (expect 2)
 */

/*
Hartmut Holzgraefe 2014-10-02 14:27:18 UTC
Created attachment 155 [details]
test for mysql_affected_rows() with/without CLIENT_FOUND_ROWS connection flag

Even worse: connections via maxscale always behave as if CLIENT_FOUND_ROWS is set even though the default is NOT having it set.

When doing the same update two times in a row without CLIENT_FOUND_ROWS
mysql_affected_rows() should return the number of rows actually changed
by the last query, while with CLIENT_FOUND_ROWS connection flag set the
number of matching rows is returned, even if the UPDATE didn't change
any column values.

With a direct connection to mysqld this works as expected,
through readconnroute(master) I'm always getting the number of matching
rows (as if CLIENT_FOUND_ROWS was set), and not the number of actually
changed rows when CLIENT_FOUND_ROWS is not set (which is the default
behaviour when not setting connection options)

Attaching PHP mysqli test script, result with direct mysqld connection is

  update #1: 2
  update #2: 0
  update #3: 2

while through maxscale it is

  update #1: 2
  update #2: 2
  update #3: 2

I also verified this using the C API directly to rule out that this is
a PHP specific problem
Comment 1 Vilho Raatikka 2014-10-08 14:11:38 UTC
Client flags are not passed to backend server properly.
Comment 2 Vilho Raatikka 2014-10-08 19:35:58 UTC
Pushed initial fix to MAX-311. Waiting for validation for the fix.
*/


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

int main(int argc, char *argv[])
{
    TestConnections * Test = new TestConnections(argc, argv);
    Test->set_timeout(30);
    MYSQL * conn_found_rows;
    my_ulonglong rows;


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

    conn_found_rows = open_conn_db_flags(Test->maxscales->rwsplit_port[0], Test->maxscales->IP[0], (char *) "test",
                                         Test->maxscales->user_name, Test->maxscales->password, CLIENT_FOUND_ROWS, Test->ssl);

    Test->set_timeout(30);
    execute_query(Test->maxscales->conn_rwsplit[0], "DROP TABLE IF EXISTS t1");
    execute_query(Test->maxscales->conn_rwsplit[0], "CREATE TABLE t1(id INT PRIMARY KEY, val INT, msg VARCHAR(100))");
    execute_query(Test->maxscales->conn_rwsplit[0],
                  "INSERT INTO t1 VALUES (1, 1, 'foo'), (2, 1, 'bar'), (3, 2, 'baz'), (4, 2, 'abc')");

    Test->set_timeout(30);
    execute_query_affected_rows(Test->maxscales->conn_rwsplit[0], "UPDATE t1 SET msg='xyz' WHERE val=2", &rows);
    Test->tprintf("update #1: %ld (expeced value is 2)\n", (long) rows);
    if (rows != 2)
    {
        Test->add_result(1, "Affected rows is not 2\n");
    }

    Test->set_timeout(30);
    execute_query_affected_rows(Test->maxscales->conn_rwsplit[0], "UPDATE t1 SET msg='xyz' WHERE val=2", &rows);
    Test->tprintf("update #2: %ld  (expeced value is 0)\n", (long) rows);
    if (rows != 0)
    {
        Test->add_result(1, "Affected rows is not 0\n");
    }

    Test->set_timeout(30);
    execute_query_affected_rows(conn_found_rows, "UPDATE t1 SET msg='xyz' WHERE val=2", &rows);
    Test->tprintf("update #3: %ld  (expeced value is 2)\n", (long) rows);
    if (rows != 2)
    {
        Test->add_result(1, "Affected rows is not 2\n");
    }

    Test->maxscales->close_maxscale_connections(0);

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

}
