You've already forked mariadb-connector-c
mirror of
https://github.com/mariadb-corporation/mariadb-connector-c.git
synced 2025-08-08 14:02:17 +03:00
- Fix for mysql_stmt_next_result:
obtain number of fields from mysql structure added test case (ps_new.c) - Added additional parameter cipher for mysql_ssl_set - some cosmetics for test cases
This commit is contained in:
31
unittest/libmariadb/CMakeLists.txt
Normal file
31
unittest/libmariadb/CMakeLists.txt
Normal file
@@ -0,0 +1,31 @@
|
||||
# Copyright (C) 2008 Sun Microsystems, Inc.
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation; version 2 of the License.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program; if not, write to the Free Software
|
||||
# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
|
||||
ENABLE_TESTING()
|
||||
|
||||
|
||||
INCLUDE_DIRECTORIES(${CMAKE_SOURCE_DIR}/include
|
||||
${CMAKE_BINARY_DIR}/include
|
||||
${CMAKE_SOURCE_DIR}/unittest/mytap)
|
||||
|
||||
SET(API_TESTS "basic-t" "fetch" "charset" "logs" "cursor" "errors" "view" "ps" "ps_bugs"
|
||||
"sp" "result" "connection" "misc" "ssl" "ps_new")
|
||||
|
||||
FOREACH(API_TEST ${API_TESTS})
|
||||
ADD_EXECUTABLE(${API_TEST} ${API_TEST}.c)
|
||||
TARGET_LINK_LIBRARIES(${API_TEST} mytap mariadbclient)
|
||||
ADD_TEST(${API_TEST} ${EXECUTABLE_OUTPUT_PATH}/${API_TEST})
|
||||
SET_TESTS_PROPERTIES(${API_TEST} PROPERTIES TIMEOUT 120)
|
||||
ENDFOREACH(API_TEST)
|
451
unittest/libmariadb/basic-t.c
Normal file
451
unittest/libmariadb/basic-t.c
Normal file
@@ -0,0 +1,451 @@
|
||||
/*
|
||||
Copyright (c) 2009, 2010, Oracle and/or its affiliates. All rights reserved.
|
||||
|
||||
The MySQL Connector/C is licensed under the terms of the GPLv2
|
||||
<http://www.gnu.org/licenses/old-licenses/gpl-2.0.html>, like most
|
||||
MySQL Connectors. There are special exceptions to the terms and
|
||||
conditions of the GPLv2 as it is applied to this software, see the
|
||||
FLOSS License Exception
|
||||
<http://www.mysql.com/about/legal/licensing/foss-exception.html>.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published
|
||||
by the Free Software Foundation; version 2 of the License.
|
||||
|
||||
This program is distributed in the hope that it will be useful, but
|
||||
WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License along
|
||||
with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
Some basic tests of the client API.
|
||||
*/
|
||||
|
||||
#include "my_test.h"
|
||||
|
||||
static int basic_connect(MYSQL *mysql)
|
||||
{
|
||||
MYSQL_ROW row;
|
||||
MYSQL_RES *res;
|
||||
int rc;
|
||||
|
||||
MYSQL *my= mysql_init(NULL);
|
||||
FAIL_IF(!my, "mysql_init() failed");
|
||||
|
||||
FAIL_IF(!mysql_real_connect(my, hostname, username, password, schema,
|
||||
port, socketname, 0), mysql_error(my));
|
||||
|
||||
rc= mysql_query(my, "SELECT @@version");
|
||||
check_mysql_rc(rc, my);
|
||||
|
||||
res= mysql_store_result(my);
|
||||
FAIL_IF(!res, mysql_error(my));
|
||||
|
||||
while ((row= mysql_fetch_row(res)) != NULL)
|
||||
{
|
||||
FAIL_IF(mysql_num_fields(res) != 1, "Got the wrong number of fields");
|
||||
}
|
||||
FAIL_IF(mysql_errno(my), mysql_error(my));
|
||||
|
||||
mysql_free_result(res);
|
||||
mysql_close(my);
|
||||
|
||||
return OK;
|
||||
}
|
||||
|
||||
|
||||
static int use_utf8(MYSQL *my)
|
||||
{
|
||||
MYSQL_ROW row;
|
||||
MYSQL_RES *res;
|
||||
int rc;
|
||||
|
||||
/* Make sure that we actually ended up with utf8. */
|
||||
rc= mysql_query(my, "SELECT @@character_set_connection");
|
||||
check_mysql_rc(rc, my);
|
||||
|
||||
res= mysql_store_result(my);
|
||||
FAIL_IF(!res, mysql_error(my));
|
||||
|
||||
while ((row= mysql_fetch_row(res)) != NULL)
|
||||
{
|
||||
FAIL_IF(strcmp(row[0], "utf8"), "wrong character set");
|
||||
}
|
||||
FAIL_IF(mysql_errno(my), mysql_error(my));
|
||||
|
||||
|
||||
return OK;
|
||||
}
|
||||
|
||||
int client_query(MYSQL *mysql) {
|
||||
int rc;
|
||||
|
||||
rc= mysql_query(mysql, "DROP TABLE IF EXISTS t1");
|
||||
check_mysql_rc(rc, mysql);
|
||||
rc= mysql_query(mysql, "CREATE TABLE t1("
|
||||
"id int primary key auto_increment, "
|
||||
"name varchar(20))");
|
||||
check_mysql_rc(rc, mysql);
|
||||
rc= mysql_query(mysql, "CREATE TABLE t1(id int, name varchar(20))");
|
||||
FAIL_IF(!rc, "Error expected");
|
||||
rc= mysql_query(mysql, "INSERT INTO t1(name) VALUES('mysql')");
|
||||
check_mysql_rc(rc, mysql);
|
||||
rc= mysql_query(mysql, "INSERT INTO t1(name) VALUES('monty')");
|
||||
check_mysql_rc(rc, mysql);
|
||||
rc= mysql_query(mysql, "INSERT INTO t1(name) VALUES('venu')");
|
||||
check_mysql_rc(rc, mysql);
|
||||
rc= mysql_query(mysql, "INSERT INTO t1(name) VALUES('deleted')");
|
||||
check_mysql_rc(rc, mysql);
|
||||
rc= mysql_query(mysql, "INSERT INTO t1(name) VALUES('deleted')");
|
||||
check_mysql_rc(rc, mysql);
|
||||
rc= mysql_query(mysql, "UPDATE t1 SET name= 'updated' "
|
||||
"WHERE name= 'deleted'");
|
||||
check_mysql_rc(rc, mysql);
|
||||
rc= mysql_query(mysql, "UPDATE t1 SET id= 3 WHERE name= 'updated'");
|
||||
FAIL_IF(!rc, "Error expected");
|
||||
rc= mysql_query(mysql, "drop table t1");
|
||||
check_mysql_rc(rc, mysql);
|
||||
|
||||
return OK;
|
||||
}
|
||||
|
||||
static int test_bug12001(MYSQL *mysql)
|
||||
{
|
||||
MYSQL_RES *result;
|
||||
const char *query= "DROP TABLE IF EXISTS test_table;"
|
||||
"CREATE TABLE test_table(id INT);"
|
||||
"INSERT INTO test_table VALUES(10);"
|
||||
"UPDATE test_table SET id=20 WHERE id=10;"
|
||||
"SELECT * FROM test_table;"
|
||||
"INSERT INTO non_existent_table VALUES(11);";
|
||||
int rc, res;
|
||||
|
||||
|
||||
rc= mysql_query(mysql, query);
|
||||
check_mysql_rc(rc, mysql);
|
||||
|
||||
do
|
||||
{
|
||||
if (mysql_field_count(mysql) &&
|
||||
(result= mysql_use_result(mysql)))
|
||||
{
|
||||
mysql_free_result(result);
|
||||
}
|
||||
}
|
||||
while (!(res= mysql_next_result(mysql)));
|
||||
|
||||
rc= mysql_query(mysql, "DROP TABLE IF EXISTS test_table");
|
||||
check_mysql_rc(rc, mysql);
|
||||
|
||||
FAIL_UNLESS(res==1, "res != 1");
|
||||
|
||||
return OK;
|
||||
}
|
||||
|
||||
|
||||
/* connection options */
|
||||
struct my_option_st opt_utf8[] = {
|
||||
{MYSQL_SET_CHARSET_NAME, "utf8"},
|
||||
{0, NULL}
|
||||
};
|
||||
|
||||
static int test_bad_union(MYSQL *mysql)
|
||||
{
|
||||
MYSQL_STMT *stmt;
|
||||
int rc;
|
||||
const char *query= "SELECT 1, 2 union SELECT 1";
|
||||
|
||||
stmt= mysql_stmt_init(mysql);
|
||||
FAIL_IF(!stmt, mysql_error(mysql));
|
||||
rc= mysql_stmt_prepare(stmt, query, strlen(query));
|
||||
FAIL_UNLESS(rc && mysql_errno(mysql) == 1222, "Error expected");
|
||||
|
||||
mysql_stmt_close(stmt);
|
||||
return OK;
|
||||
}
|
||||
|
||||
/*
|
||||
Test that mysql_insert_id() behaves as documented in our manual
|
||||
*/
|
||||
static int test_mysql_insert_id(MYSQL *mysql)
|
||||
{
|
||||
my_ulonglong res;
|
||||
int rc;
|
||||
|
||||
if (mysql_get_server_version(mysql) < 50100) {
|
||||
diag("Test requires MySQL Server version 5.1 or above");
|
||||
return SKIP;
|
||||
}
|
||||
|
||||
rc= mysql_query(mysql, "drop table if exists t1");
|
||||
check_mysql_rc(rc, mysql);
|
||||
rc= mysql_query(mysql, "drop table if exists t2");
|
||||
check_mysql_rc(rc, mysql);
|
||||
/* table without auto_increment column */
|
||||
rc= mysql_query(mysql, "create table t1 (f1 int, f2 varchar(255), key(f1))");
|
||||
check_mysql_rc(rc, mysql);
|
||||
rc= mysql_query(mysql, "insert into t1 values (1,'a')");
|
||||
check_mysql_rc(rc, mysql);
|
||||
res= mysql_insert_id(mysql);
|
||||
FAIL_UNLESS(res == 0, "");
|
||||
rc= mysql_query(mysql, "insert into t1 values (null,'b')");
|
||||
check_mysql_rc(rc, mysql);
|
||||
res= mysql_insert_id(mysql);
|
||||
FAIL_UNLESS(res == 0, "");
|
||||
rc= mysql_query(mysql, "insert into t1 select 5,'c'");
|
||||
check_mysql_rc(rc, mysql);
|
||||
res= mysql_insert_id(mysql);
|
||||
FAIL_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))");
|
||||
check_mysql_rc(rc, mysql);
|
||||
rc= mysql_query(mysql, "insert into t2 values (null,'b')");
|
||||
check_mysql_rc(rc, mysql);
|
||||
rc= mysql_query(mysql, "insert into t1 select 5,'c'");
|
||||
check_mysql_rc(rc, mysql);
|
||||
res= mysql_insert_id(mysql);
|
||||
FAIL_UNLESS(res == 0, "");
|
||||
rc= mysql_query(mysql, "drop table t2");
|
||||
check_mysql_rc(rc, mysql);
|
||||
|
||||
rc= mysql_query(mysql, "insert into t1 select null,'d'");
|
||||
check_mysql_rc(rc, mysql);
|
||||
res= mysql_insert_id(mysql);
|
||||
FAIL_UNLESS(res == 0, "");
|
||||
rc= mysql_query(mysql, "insert into t1 values (null,last_insert_id(300))");
|
||||
check_mysql_rc(rc, mysql);
|
||||
res= mysql_insert_id(mysql);
|
||||
FAIL_UNLESS(res == 300, "");
|
||||
rc= mysql_query(mysql, "insert into t1 select null,last_insert_id(400)");
|
||||
check_mysql_rc(rc, mysql);
|
||||
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.
|
||||
*/
|
||||
FAIL_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))");
|
||||
check_mysql_rc(rc, mysql);
|
||||
rc= mysql_query(mysql, "insert into t2 values (1,'a')");
|
||||
check_mysql_rc(rc, mysql);
|
||||
res= mysql_insert_id(mysql);
|
||||
FAIL_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')");
|
||||
check_mysql_rc(rc, mysql);
|
||||
res= mysql_insert_id(mysql);
|
||||
FAIL_UNLESS(res == 0, "");
|
||||
|
||||
rc= mysql_query(mysql, "insert into t2 values (null,'b')");
|
||||
check_mysql_rc(rc, mysql);
|
||||
res= mysql_insert_id(mysql);
|
||||
FAIL_UNLESS(res == 2, "");
|
||||
rc= mysql_query(mysql, "insert into t2 select 5,'c'");
|
||||
check_mysql_rc(rc, mysql);
|
||||
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.
|
||||
*/
|
||||
FAIL_UNLESS(res == 5, "");
|
||||
rc= mysql_query(mysql, "insert into t2 select null,'d'");
|
||||
check_mysql_rc(rc, mysql);
|
||||
res= mysql_insert_id(mysql);
|
||||
FAIL_UNLESS(res == 6, "");
|
||||
/* with more than one row */
|
||||
rc= mysql_query(mysql, "insert into t2 values (10,'a'),(11,'b')");
|
||||
check_mysql_rc(rc, mysql);
|
||||
res= mysql_insert_id(mysql);
|
||||
FAIL_UNLESS(res == 11, "");
|
||||
rc= mysql_query(mysql, "insert into t2 select 12,'a' union select 13,'b'");
|
||||
check_mysql_rc(rc, mysql);
|
||||
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.
|
||||
*/
|
||||
FAIL_UNLESS(res == 13, "");
|
||||
rc= mysql_query(mysql, "insert into t2 values (null,'a'),(null,'b')");
|
||||
check_mysql_rc(rc, mysql);
|
||||
res= mysql_insert_id(mysql);
|
||||
FAIL_UNLESS(res == 14, "");
|
||||
rc= mysql_query(mysql, "insert into t2 select null,'a' union select null,'b'");
|
||||
check_mysql_rc(rc, mysql);
|
||||
res= mysql_insert_id(mysql);
|
||||
FAIL_UNLESS(res == 16, "");
|
||||
rc= mysql_query(mysql, "insert into t2 select 12,'a' union select 13,'b'");
|
||||
FAIL_IF(!rc, "Error expected");
|
||||
rc= mysql_query(mysql, "insert ignore into t2 select 12,'a' union select 13,'b'");
|
||||
check_mysql_rc(rc, mysql);
|
||||
res= mysql_insert_id(mysql);
|
||||
FAIL_UNLESS(res == 0, "");
|
||||
rc= mysql_query(mysql, "insert into t2 values (12,'a'),(13,'b')");
|
||||
FAIL_IF(!rc, "Error expected");
|
||||
res= mysql_insert_id(mysql);
|
||||
FAIL_UNLESS(res == 0, "");
|
||||
rc= mysql_query(mysql, "insert ignore into t2 values (12,'a'),(13,'b')");
|
||||
check_mysql_rc(rc, mysql);
|
||||
res= mysql_insert_id(mysql);
|
||||
FAIL_UNLESS(res == 0, "");
|
||||
/* mixing autogenerated and explicit values */
|
||||
rc= mysql_query(mysql, "insert into t2 values (null,'e'),(12,'a'),(13,'b')");
|
||||
FAIL_IF(!rc, "Error expected");
|
||||
rc= mysql_query(mysql, "insert into t2 values (null,'e'),(12,'a'),(13,'b'),(25,'g')");
|
||||
FAIL_IF(!rc, "Error expected");
|
||||
rc= mysql_query(mysql, "insert into t2 values (null,last_insert_id(300))");
|
||||
check_mysql_rc(rc, mysql);
|
||||
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().
|
||||
*/
|
||||
FAIL_UNLESS(res == 20, "");
|
||||
/* If first autogenerated number fails and 2nd works: */
|
||||
rc= mysql_query(mysql, "drop table t2");
|
||||
check_mysql_rc(rc, mysql);
|
||||
rc= mysql_query(mysql, "create table t2 (f1 int not null primary key "
|
||||
"auto_increment, f2 varchar(255), unique (f2))");
|
||||
check_mysql_rc(rc, mysql);
|
||||
rc= mysql_query(mysql, "insert into t2 values (null,'e')");
|
||||
res= mysql_insert_id(mysql);
|
||||
FAIL_UNLESS(res == 1, "");
|
||||
rc= mysql_query(mysql, "insert ignore into t2 values (null,'e'),(null,'a'),(null,'e')");
|
||||
check_mysql_rc(rc, mysql);
|
||||
res= mysql_insert_id(mysql);
|
||||
FAIL_UNLESS(res == 2, "");
|
||||
/* If autogenerated fails and explicit works: */
|
||||
rc= mysql_query(mysql, "insert ignore into t2 values (null,'e'),(12,'c'),(null,'d')");
|
||||
check_mysql_rc(rc, mysql);
|
||||
res= mysql_insert_id(mysql);
|
||||
/*
|
||||
Behaviour change: old code returned 3 (first autogenerated, even if it
|
||||
fails); we now return first successful autogenerated.
|
||||
*/
|
||||
FAIL_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");
|
||||
check_mysql_rc(rc, mysql);
|
||||
res= mysql_insert_id(mysql);
|
||||
FAIL_UNLESS(res == 0, "");
|
||||
rc= mysql_query(mysql, "update t2 set f1=0 where f1=14");
|
||||
check_mysql_rc(rc, mysql);
|
||||
res= mysql_insert_id(mysql);
|
||||
FAIL_UNLESS(res == 0, "");
|
||||
rc= mysql_query(mysql, "update t2 set f2=last_insert_id(372) where f1=0");
|
||||
check_mysql_rc(rc, mysql);
|
||||
res= mysql_insert_id(mysql);
|
||||
FAIL_UNLESS(res == 372, "");
|
||||
/* check that LAST_INSERT_ID() does not update mysql_insert_id(): */
|
||||
rc= mysql_query(mysql, "insert into t2 values (null,'g')");
|
||||
check_mysql_rc(rc, mysql);
|
||||
res= mysql_insert_id(mysql);
|
||||
FAIL_UNLESS(res == 15, "");
|
||||
rc= mysql_query(mysql, "update t2 set f2=(@li:=last_insert_id()) where f1=15");
|
||||
check_mysql_rc(rc, mysql);
|
||||
res= mysql_insert_id(mysql);
|
||||
FAIL_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)");
|
||||
check_mysql_rc(rc, mysql);
|
||||
res= mysql_insert_id(mysql);
|
||||
FAIL_UNLESS(res == 15, "");
|
||||
|
||||
rc= mysql_query(mysql, "drop table t1,t2");
|
||||
check_mysql_rc(rc, mysql);
|
||||
return OK;
|
||||
}
|
||||
|
||||
/* Test simple select to debug */
|
||||
|
||||
static int test_select_direct(MYSQL *mysql)
|
||||
{
|
||||
int rc;
|
||||
MYSQL_RES *result;
|
||||
|
||||
|
||||
rc= mysql_autocommit(mysql, TRUE);
|
||||
check_mysql_rc(rc, mysql);
|
||||
|
||||
rc= mysql_query(mysql, "DROP TABLE IF EXISTS test_select");
|
||||
check_mysql_rc(rc, mysql);
|
||||
|
||||
rc= mysql_query(mysql, "CREATE TABLE test_select(id int, id1 tinyint, "
|
||||
" id2 float, "
|
||||
" id3 double, "
|
||||
" name varchar(50))");
|
||||
check_mysql_rc(rc, mysql);
|
||||
|
||||
/* insert a row and commit the transaction */
|
||||
rc= mysql_query(mysql, "INSERT INTO test_select VALUES(10, 5, 2.3, 4.5, 'venu')");
|
||||
check_mysql_rc(rc, mysql);
|
||||
|
||||
rc= mysql_commit(mysql);
|
||||
check_mysql_rc(rc, mysql);
|
||||
|
||||
rc= mysql_query(mysql, "SELECT * FROM test_select");
|
||||
check_mysql_rc(rc, mysql);
|
||||
|
||||
/* get the result */
|
||||
result= mysql_store_result(mysql);
|
||||
FAIL_IF(!result, "Invalid result set");
|
||||
|
||||
mysql_free_result(result);
|
||||
return OK;
|
||||
}
|
||||
|
||||
/*
|
||||
Ensure we execute the status code while testing
|
||||
*/
|
||||
|
||||
static int test_status(MYSQL *mysql)
|
||||
{
|
||||
mysql_stat(mysql);
|
||||
check_mysql_rc(mysql_errno(mysql), mysql);
|
||||
return OK;
|
||||
}
|
||||
|
||||
struct my_tests_st my_tests[] = {
|
||||
{"basic_connect", basic_connect, TEST_CONNECTION_NONE, 0, NULL, NULL},
|
||||
{"use_utf8", use_utf8, TEST_CONNECTION_NEW, 0, opt_utf8, NULL},
|
||||
{"client_query", client_query, TEST_CONNECTION_DEFAULT, 0, NULL, NULL},
|
||||
{"test_bad_union", test_bad_union, TEST_CONNECTION_DEFAULT, 0, NULL, NULL},
|
||||
{"test_select_direct", test_select_direct, TEST_CONNECTION_DEFAULT, 0, NULL, NULL},
|
||||
{"test_mysql_insert_id", test_mysql_insert_id, TEST_CONNECTION_DEFAULT, 0, NULL, NULL},
|
||||
{"test_bug12001", test_bug12001, TEST_CONNECTION_NEW, CLIENT_MULTI_STATEMENTS, NULL, NULL},
|
||||
{"test_status", test_status, TEST_CONNECTION_NEW, CLIENT_MULTI_STATEMENTS, NULL, NULL},
|
||||
{NULL, NULL, 0, 0, NULL, NULL}
|
||||
};
|
||||
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
|
||||
if (argc > 1)
|
||||
get_options(argc, argv);
|
||||
|
||||
get_envvars();
|
||||
|
||||
run_tests(my_tests);
|
||||
|
||||
return(exit_status());
|
||||
}
|
38
unittest/libmariadb/ca.pem
Normal file
38
unittest/libmariadb/ca.pem
Normal file
@@ -0,0 +1,38 @@
|
||||
-----BEGIN CERTIFICATE-----
|
||||
MIIDGDCCAgACAQEwDQYJKoZIhvcNAQEFBQAwUjELMAkGA1UEBhMCREUxCzAJBgNV
|
||||
BAgMAkJXMRMwEQYDVQQHDApIZWlkZWxiZXJnMSEwHwYDVQQKDBhJbnRlcm5ldCBX
|
||||
aWRnaXRzIFB0eSBMdGQwHhcNMTIxMTIyMDcxMDM5WhcNMjIxMDAxMDcxMDM5WjBS
|
||||
MQswCQYDVQQGEwJERTELMAkGA1UECAwCQlcxEzARBgNVBAcMCkhlaWRlbGJlcmcx
|
||||
ITAfBgNVBAoMGEludGVybmV0IFdpZGdpdHMgUHR5IEx0ZDCCASIwDQYJKoZIhvcN
|
||||
AQEBBQADggEPADCCAQoCggEBAOKiAyhtJXHgjr0cLFx+gYqBZCzg+Bpevh3/+U0t
|
||||
A5trng5kht8dbI6m0Qjz8Mi09sFxaHmmL6WA+wxL8LqwMjOXpn3aAjNW3+QFu5Ei
|
||||
Iy+8KrwdJdZVzRHCCLt4HWpeMQBzn2y/MUgZzc8+RhcQSu2KVDBiKLVpa6Z9k3gl
|
||||
wsezI8ClJ6vWsJGnJX699H9BhMyS85ipVmeL69h5tWsdHQtmbK+XdHPQldi9r/88
|
||||
f2VfIOo7EFSm9ohJG70P8lhEIqByhQ8Hw0akGWLLsLg4cufPVrOdPZocJ/qJjQVG
|
||||
OkfSPkIgwKnpzGbXjFG5IMh5rXJCIRbO3ofTxGpSTzNQ0hcCAwEAATANBgkqhkiG
|
||||
9w0BAQUFAAOCAQEAb7bIszKyzpCvom4FjnNYT3buQCf0qnUGoPgVpXIpjc4Lsyr0
|
||||
nmIfgGNo/+5B1cj3iAtIuSojXOK96r8a84TueCaeX9ZDdG+ZZm9ng6mIiyQraZyR
|
||||
Gl+VsTH40O0QTjMcPB344Yz0ZSHU1E35LzarApHtqZi9TpCBFc0td1EhxX7rdEOD
|
||||
WzBRTKcMzV+Y0Fslqjy73JVYnaxJ/ZShW7TOowrdjE9DZ8VZ7dVSJOtdTLB5WNQE
|
||||
mxFInjbUig5vvHzmf4bEsBDz7RXy0W8fMQd2HEcgGBDwdQYq18kZl9H5plORDCgg
|
||||
S93U+OoInjEU2KEWyDyiBI7OwAZYIQytrxDBOw==
|
||||
-----END CERTIFICATE-----
|
||||
-----BEGIN CERTIFICATE-----
|
||||
MIIDGDCCAgACAQEwDQYJKoZIhvcNAQEFBQAwUjELMAkGA1UEBhMCREUxCzAJBgNV
|
||||
BAgMAkJXMRMwEQYDVQQHDApIZWlkZWxiZXJnMSEwHwYDVQQKDBhJbnRlcm5ldCBX
|
||||
aWRnaXRzIFB0eSBMdGQwHhcNMTIxMTIyMDcxMTI0WhcNMjIxMDAxMDcxMTI0WjBS
|
||||
MQswCQYDVQQGEwJERTELMAkGA1UECAwCQlcxEzARBgNVBAcMCkhlaWRlbGJlcmcx
|
||||
ITAfBgNVBAoMGEludGVybmV0IFdpZGdpdHMgUHR5IEx0ZDCCASIwDQYJKoZIhvcN
|
||||
AQEBBQADggEPADCCAQoCggEBANofs7wzZpUourQz03gALCHcTYXbuTJ16w/rbvql
|
||||
WUa1R/qUgaxN9k7SEj260Vr7PMEREAIdKIu54jCy/yCRzYb/03HorQjJgGXjYvtX
|
||||
nmwwUgLZSz3aLIX2p7jcw3ESiqN1/oZ3fB8+i6HT8igFcmbAOkPEN8TBM9Qenqj7
|
||||
NNx9iYAOp7r8xJXJXTEWBIy0kJ2eXZQacveLGPgFs6Qq0Hvn8FsXT9zQQH98BQhL
|
||||
o35vjxas/A8ThZiKd8cCmUbTtGxIlncR7FmJuqKAJVTSg/ZePFoYqW0s9GAtPJfC
|
||||
DVdaT94uGZIWtOCLPqQgiEyjdHWHdeF+WBdXex3xRI3Ii+UCAwEAATANBgkqhkiG
|
||||
9w0BAQUFAAOCAQEAKSXEbcpfgqZiWIJBpQX86kNMWhjA4m8GKwXoxhgxTtEZPju/
|
||||
VO/ehjsTo8AnRQdW4/sD+KgVqn6F4jw5WVwK6L0TTlat5umn+zKW9c72Cmsf7kiZ
|
||||
pc6bluyKv1uhS5pK1HLjQaL8vY4WExHkh8nGEuS4IIhAtHzBblE3G4/Kdq7V7IO7
|
||||
+YaSwO1nRiYaFbrZkF8u+GOIVJlcQ7C7m2332c0NFYBmYoeJ03rwb8kWe40UHaiP
|
||||
R3Pl/bzrRbcHiSqLawFpfYOG1+Sq9GkBwysv6ADU4wKcu9dYNvjgbRHhHuSLB3am
|
||||
Dnj09lCHMDxHUtk1PhLsxG65lMw4GaUEqjfUmg==
|
||||
-----END CERTIFICATE-----
|
683
unittest/libmariadb/charset.c
Normal file
683
unittest/libmariadb/charset.c
Normal file
@@ -0,0 +1,683 @@
|
||||
/*
|
||||
Copyright (c) 2009, 2010, Oracle and/or its affiliates. All rights reserved.
|
||||
|
||||
The MySQL Connector/C is licensed under the terms of the GPLv2
|
||||
<http://www.gnu.org/licenses/old-licenses/gpl-2.0.html>, like most
|
||||
MySQL Connectors. There are special exceptions to the terms and
|
||||
conditions of the GPLv2 as it is applied to this software, see the
|
||||
FLOSS License Exception
|
||||
<http://www.mysql.com/about/legal/licensing/foss-exception.html>.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published
|
||||
by the Free Software Foundation; version 2 of the License.
|
||||
|
||||
This program is distributed in the hope that it will be useful, but
|
||||
WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License along
|
||||
with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
#include "my_test.h"
|
||||
|
||||
/*
|
||||
test gbk charset escaping
|
||||
|
||||
The important part is that 0x27 (') is the second-byte in a invalid
|
||||
two-byte GBK character here. But 0xbf5c is a valid GBK character, so
|
||||
it needs to be escaped as 0x5cbf27
|
||||
|
||||
*/
|
||||
#define TEST_BUG8378_IN "\xef\xbb\xbf\x27\xbf\x10"
|
||||
#define TEST_BUG8378_OUT "\xef\xbb\x5c\xbf\x5c\x27\x5c\xbf\x10"
|
||||
|
||||
/* set connection options */
|
||||
struct my_option_st opt_bug8378[] = {
|
||||
{MYSQL_SET_CHARSET_NAME, "gbk"},
|
||||
{0, NULL}
|
||||
};
|
||||
|
||||
int bug_8378(MYSQL *mysql) {
|
||||
int rc, len;
|
||||
char out[9], buf[256];
|
||||
MYSQL_RES *res;
|
||||
MYSQL_ROW row;
|
||||
|
||||
len= mysql_real_escape_string(mysql, out, TEST_BUG8378_IN, 4);
|
||||
FAIL_IF(memcmp(out, TEST_BUG8378_OUT, len), "wrong result");
|
||||
|
||||
sprintf(buf, "SELECT '%s' FROM DUAL", TEST_BUG8378_OUT);
|
||||
|
||||
rc= mysql_query(mysql, buf);
|
||||
check_mysql_rc(rc, mysql);
|
||||
|
||||
if ((res= mysql_store_result(mysql))) {
|
||||
row= mysql_fetch_row(res);
|
||||
if (memcmp(row[0], TEST_BUG8378_IN, 4)) {
|
||||
mysql_free_result(res);
|
||||
return FAIL;
|
||||
}
|
||||
mysql_free_result(res);
|
||||
} else
|
||||
return FAIL;
|
||||
|
||||
return OK;
|
||||
}
|
||||
|
||||
int test_client_character_set(MYSQL *mysql)
|
||||
{
|
||||
MY_CHARSET_INFO cs;
|
||||
char *csname= (char*) "utf8";
|
||||
char *csdefault= (char*)mysql_character_set_name(mysql);
|
||||
|
||||
FAIL_IF(mysql_set_character_set(mysql, csname), mysql_error(mysql));
|
||||
|
||||
mysql_get_character_set_info(mysql, &cs);
|
||||
|
||||
FAIL_IF(strcmp(cs.csname, "utf8") || strcmp(cs.name, "utf8_general_ci"), "Character set != UTF8");
|
||||
FAIL_IF(mysql_set_character_set(mysql, csdefault), mysql_error(mysql));
|
||||
|
||||
return OK;
|
||||
}
|
||||
|
||||
/*
|
||||
* Regression test for bug #10214
|
||||
*
|
||||
* Test escaping with NO_BACKSLASH_ESCAPES
|
||||
*
|
||||
*/
|
||||
int bug_10214(MYSQL *mysql)
|
||||
{
|
||||
int len, rc;
|
||||
char out[8];
|
||||
|
||||
/* reset sql_mode */
|
||||
rc= mysql_query(mysql, "SET sql_mode=''");
|
||||
check_mysql_rc(rc, mysql);
|
||||
|
||||
len= mysql_real_escape_string(mysql, out, "a'b\\c", 5);
|
||||
FAIL_IF(memcmp(out, "a\\'b\\\\c", len), NULL);
|
||||
|
||||
rc= mysql_query(mysql, "set sql_mode='NO_BACKSLASH_ESCAPES'");
|
||||
check_mysql_rc(rc, mysql);
|
||||
FAIL_IF(!(mysql->server_status & SERVER_STATUS_NO_BACKSLASH_ESCAPES),
|
||||
"wrong server status: NO_BACKSLASH_ESCAPES not set");
|
||||
|
||||
len= mysql_real_escape_string(mysql, out, "a'b\\c", 5);
|
||||
FAIL_IF(memcmp(out, "a''b\\c", len), "wrong result");
|
||||
|
||||
return OK;
|
||||
}
|
||||
|
||||
/*
|
||||
* simple escaping of special chars
|
||||
*/
|
||||
int test_escaping(MYSQL *mysql)
|
||||
{
|
||||
int i= 0, rc, len;
|
||||
char out[20];
|
||||
char *escape_chars[] = {"'", "\x0", "\n", "\r", "\\", "\0", NULL};
|
||||
|
||||
/* reset sql_mode, mysql_change_user call doesn't reset it */
|
||||
rc= mysql_query(mysql, "SET sql_mode=''");
|
||||
check_mysql_rc(rc, mysql);
|
||||
|
||||
while (escape_chars[i]) {
|
||||
len= mysql_real_escape_string(mysql, out, escape_chars[i], 1);
|
||||
FAIL_IF(len < 2, "Len < 2");
|
||||
i++;
|
||||
}
|
||||
|
||||
return OK;
|
||||
}
|
||||
|
||||
/*
|
||||
* server doesn't reset sql_mode after COM_CHANGE_USER
|
||||
*/
|
||||
int bug_41785(MYSQL *mysql)
|
||||
{
|
||||
char out[10];
|
||||
int rc, len;
|
||||
|
||||
len= mysql_real_escape_string(mysql, out, "\\", 1);
|
||||
FAIL_IF(len != 2, "len != 2");
|
||||
|
||||
rc= mysql_query(mysql, "SET SQL_MODE=NO_BACKSLASH_ESCAPES");
|
||||
check_mysql_rc(rc, mysql);
|
||||
rc= mysql_query(mysql, "SET sql_mode=''");
|
||||
check_mysql_rc(rc, mysql);
|
||||
|
||||
mysql_change_user(mysql, "root", "", "test");
|
||||
|
||||
len= mysql_real_escape_string(mysql, out, "\\", 1);
|
||||
FAIL_IF(len != 2, "len != 2");
|
||||
|
||||
return OK;
|
||||
}
|
||||
|
||||
static int test_conversion(MYSQL *mysql)
|
||||
{
|
||||
MYSQL_STMT *stmt;
|
||||
const char *stmt_text;
|
||||
int rc;
|
||||
MYSQL_BIND my_bind[1];
|
||||
uchar buff[4];
|
||||
ulong length;
|
||||
|
||||
stmt_text= "DROP TABLE IF EXISTS t1";
|
||||
rc= mysql_real_query(mysql, stmt_text, strlen(stmt_text));
|
||||
check_mysql_rc(rc, mysql);
|
||||
stmt_text= "CREATE TABLE t1 (a TEXT) DEFAULT CHARSET latin1";
|
||||
rc= mysql_real_query(mysql, stmt_text, strlen(stmt_text));
|
||||
check_mysql_rc(rc, mysql);
|
||||
stmt_text= "SET character_set_connection=utf8, character_set_client=utf8, "
|
||||
" character_set_results=latin1";
|
||||
rc= mysql_real_query(mysql, stmt_text, strlen(stmt_text));
|
||||
check_mysql_rc(rc, mysql);
|
||||
|
||||
stmt= mysql_stmt_init(mysql);
|
||||
FAIL_IF(!stmt, mysql_error(mysql));
|
||||
stmt_text= "INSERT INTO t1 (a) VALUES (?)";
|
||||
rc= mysql_stmt_prepare(stmt, stmt_text, strlen(stmt_text));
|
||||
check_stmt_rc(rc, stmt);
|
||||
|
||||
memset(my_bind, '\0', sizeof(my_bind));
|
||||
my_bind[0].buffer= (char*) buff;
|
||||
my_bind[0].length= &length;
|
||||
my_bind[0].buffer_type= MYSQL_TYPE_STRING;
|
||||
|
||||
mysql_stmt_bind_param(stmt, my_bind);
|
||||
|
||||
buff[0]= (uchar) 0xC3;
|
||||
buff[1]= (uchar) 0xA0;
|
||||
length= 2;
|
||||
|
||||
rc= mysql_stmt_execute(stmt);
|
||||
check_stmt_rc(rc, stmt);
|
||||
|
||||
stmt_text= "SELECT a FROM t1";
|
||||
rc= mysql_stmt_prepare(stmt, stmt_text, strlen(stmt_text));
|
||||
check_stmt_rc(rc, stmt);
|
||||
rc= mysql_stmt_execute(stmt);
|
||||
check_stmt_rc(rc, stmt);
|
||||
|
||||
my_bind[0].buffer_length= sizeof(buff);
|
||||
mysql_stmt_bind_result(stmt, my_bind);
|
||||
|
||||
rc= mysql_stmt_fetch(stmt);
|
||||
check_stmt_rc(rc, stmt);
|
||||
FAIL_UNLESS(length == 1, "length != 1");
|
||||
FAIL_UNLESS(buff[0] == 0xE0, "buff[0] != 0xE0");
|
||||
rc= mysql_stmt_fetch(stmt);
|
||||
FAIL_UNLESS(rc == MYSQL_NO_DATA, "rc != MYSQL_NO_DATA");
|
||||
|
||||
mysql_stmt_close(stmt);
|
||||
stmt_text= "DROP TABLE t1";
|
||||
rc= mysql_real_query(mysql, stmt_text, strlen(stmt_text));
|
||||
check_mysql_rc(rc, mysql);
|
||||
stmt_text= "SET NAMES DEFAULT";
|
||||
rc= mysql_real_query(mysql, stmt_text, strlen(stmt_text));
|
||||
check_mysql_rc(rc, mysql);
|
||||
|
||||
return OK;
|
||||
}
|
||||
|
||||
static int test_bug27876(MYSQL *mysql)
|
||||
{
|
||||
int rc;
|
||||
MYSQL_RES *result;
|
||||
|
||||
uchar utf8_func[] =
|
||||
{
|
||||
0xd1, 0x84, 0xd1, 0x83, 0xd0, 0xbd, 0xd0, 0xba,
|
||||
0xd1, 0x86, 0xd0, 0xb8, 0xd0, 0xb9, 0xd0, 0xba,
|
||||
0xd0, 0xb0,
|
||||
0x00
|
||||
};
|
||||
|
||||
uchar utf8_param[] =
|
||||
{
|
||||
0xd0, 0xbf, 0xd0, 0xb0, 0xd1, 0x80, 0xd0, 0xb0,
|
||||
0xd0, 0xbc, 0xd0, 0xb5, 0xd1, 0x82, 0xd1, 0x8a,
|
||||
0xd1, 0x80, 0x5f, 0xd0, 0xb2, 0xd0, 0xb5, 0xd1,
|
||||
0x80, 0xd1, 0x81, 0xd0, 0xb8, 0xd1, 0x8f,
|
||||
0x00
|
||||
};
|
||||
|
||||
char query[500];
|
||||
|
||||
DBUG_ENTER("test_bug27876");
|
||||
|
||||
rc= mysql_query(mysql, "set names utf8");
|
||||
check_mysql_rc(rc, mysql);
|
||||
|
||||
rc= mysql_query(mysql, "select version()");
|
||||
check_mysql_rc(rc, mysql);
|
||||
result= mysql_store_result(mysql);
|
||||
FAIL_IF(!result, "Invalid result set");
|
||||
mysql_free_result(result);
|
||||
|
||||
sprintf(query, "DROP FUNCTION IF EXISTS %s", (char*) utf8_func);
|
||||
rc= mysql_query(mysql, query);
|
||||
check_mysql_rc(rc, mysql);
|
||||
|
||||
sprintf(query,
|
||||
"CREATE FUNCTION %s( %s VARCHAR(25))"
|
||||
" RETURNS VARCHAR(25) DETERMINISTIC RETURN %s",
|
||||
(char*) utf8_func, (char*) utf8_param, (char*) utf8_param);
|
||||
rc= mysql_query(mysql, query);
|
||||
check_mysql_rc(rc, mysql);
|
||||
sprintf(query, "SELECT %s(VERSION())", (char*) utf8_func);
|
||||
rc= mysql_query(mysql, query);
|
||||
check_mysql_rc(rc, mysql);
|
||||
result= mysql_store_result(mysql);
|
||||
FAIL_IF(!result, "Invalid result set");
|
||||
mysql_free_result(result);
|
||||
|
||||
sprintf(query, "DROP FUNCTION %s", (char*) utf8_func);
|
||||
rc= mysql_query(mysql, query);
|
||||
check_mysql_rc(rc, mysql);
|
||||
|
||||
rc= mysql_query(mysql, "set names default");
|
||||
check_mysql_rc(rc, mysql);
|
||||
return OK;
|
||||
}
|
||||
|
||||
static int test_ps_i18n(MYSQL *mysql)
|
||||
{
|
||||
MYSQL_STMT *stmt;
|
||||
int rc;
|
||||
const char *stmt_text;
|
||||
MYSQL_BIND bind_array[2];
|
||||
|
||||
/* Represented as numbers to keep UTF8 tools from clobbering them. */
|
||||
const char *koi8= "\xee\xd5\x2c\x20\xda\xc1\x20\xd2\xd9\xc2\xc1\xcc\xcb\xd5";
|
||||
const char *cp1251= "\xcd\xf3\x2c\x20\xe7\xe0\x20\xf0\xfb\xe1\xe0\xeb\xea\xf3";
|
||||
char buf1[16], buf2[16];
|
||||
ulong buf1_len, buf2_len;
|
||||
|
||||
stmt_text= "DROP TABLE IF EXISTS t1";
|
||||
rc= mysql_real_query(mysql, stmt_text, strlen(stmt_text));
|
||||
check_mysql_rc(rc, mysql);
|
||||
|
||||
/*
|
||||
Create table with binary columns, set session character set to cp1251,
|
||||
client character set to koi8, and make sure that there is conversion
|
||||
on insert and no conversion on select
|
||||
*/
|
||||
|
||||
stmt_text= "CREATE TABLE t1 (c1 VARBINARY(255), c2 VARBINARY(255))";
|
||||
rc= mysql_real_query(mysql, stmt_text, strlen(stmt_text));
|
||||
check_mysql_rc(rc, mysql);
|
||||
|
||||
stmt_text= "SET CHARACTER_SET_CLIENT=koi8r, "
|
||||
"CHARACTER_SET_CONNECTION=cp1251, "
|
||||
"CHARACTER_SET_RESULTS=koi8r";
|
||||
|
||||
rc= mysql_real_query(mysql, stmt_text, strlen(stmt_text));
|
||||
check_mysql_rc(rc, mysql);
|
||||
|
||||
memset(bind_array, '\0', sizeof(bind_array));
|
||||
bind_array[0].buffer_type= MYSQL_TYPE_STRING;
|
||||
bind_array[0].buffer= (void *) koi8;
|
||||
bind_array[0].buffer_length= strlen(koi8);
|
||||
|
||||
bind_array[1].buffer_type= MYSQL_TYPE_STRING;
|
||||
bind_array[1].buffer= (void *) koi8;
|
||||
bind_array[1].buffer_length= strlen(koi8);
|
||||
|
||||
stmt= mysql_stmt_init(mysql);
|
||||
check_stmt_rc(rc, stmt);
|
||||
|
||||
stmt_text= "INSERT INTO t1 (c1, c2) VALUES (?, ?)";
|
||||
|
||||
rc= mysql_stmt_prepare(stmt, stmt_text, strlen(stmt_text));
|
||||
check_stmt_rc(rc, stmt);
|
||||
mysql_stmt_bind_param(stmt, bind_array);
|
||||
check_stmt_rc(rc, stmt);
|
||||
|
||||
// mysql_stmt_send_long_data(stmt, 0, koi8, strlen(koi8));
|
||||
|
||||
rc= mysql_stmt_execute(stmt);
|
||||
check_stmt_rc(rc, stmt);
|
||||
stmt_text= "SELECT c1, c2 FROM t1";
|
||||
|
||||
/* c1 and c2 are binary so no conversion will be done on select */
|
||||
rc= mysql_stmt_prepare(stmt, stmt_text, strlen(stmt_text));
|
||||
check_stmt_rc(rc, stmt);
|
||||
rc= mysql_stmt_execute(stmt);
|
||||
check_stmt_rc(rc, stmt);
|
||||
bind_array[0].buffer= buf1;
|
||||
bind_array[0].buffer_length= sizeof(buf1);
|
||||
bind_array[0].length= &buf1_len;
|
||||
|
||||
bind_array[1].buffer= buf2;
|
||||
bind_array[1].buffer_length= sizeof(buf2);
|
||||
bind_array[1].length= &buf2_len;
|
||||
|
||||
mysql_stmt_bind_result(stmt, bind_array);
|
||||
|
||||
rc= mysql_stmt_fetch(stmt);
|
||||
check_stmt_rc(rc, stmt);
|
||||
FAIL_UNLESS(buf1_len == strlen(cp1251), "buf1_len != strlen(cp1251)");
|
||||
FAIL_UNLESS(buf2_len == strlen(cp1251), "buf2_len != strlen(cp1251)");
|
||||
FAIL_UNLESS(!memcmp(buf1, cp1251, buf1_len), "buf1 != cp1251");
|
||||
FAIL_UNLESS(!memcmp(buf2, cp1251, buf1_len), "buf2 != cp1251");
|
||||
|
||||
rc= mysql_stmt_fetch(stmt);
|
||||
FAIL_UNLESS(rc == MYSQL_NO_DATA, "rc != MYSQL_NO_DATA");
|
||||
|
||||
stmt_text= "DROP TABLE IF EXISTS t1";
|
||||
rc= mysql_real_query(mysql, stmt_text, strlen(stmt_text));
|
||||
check_mysql_rc(rc, mysql);
|
||||
|
||||
/*
|
||||
Now create table with two cp1251 columns, set client character
|
||||
set to koi8 and supply columns of one row as string and another as
|
||||
binary data. Binary data must not be converted on insert, and both
|
||||
columns must be converted to client character set on select.
|
||||
*/
|
||||
|
||||
stmt_text= "CREATE TABLE t1 (c1 VARCHAR(255) CHARACTER SET cp1251, "
|
||||
"c2 VARCHAR(255) CHARACTER SET cp1251)";
|
||||
|
||||
rc= mysql_real_query(mysql, stmt_text, strlen(stmt_text));
|
||||
check_mysql_rc(rc, mysql);
|
||||
|
||||
stmt_text= "INSERT INTO t1 (c1, c2) VALUES (?, ?)";
|
||||
|
||||
rc= mysql_stmt_prepare(stmt, stmt_text, strlen(stmt_text));
|
||||
check_stmt_rc(rc, stmt);
|
||||
/* this data must be converted */
|
||||
bind_array[0].buffer_type= MYSQL_TYPE_STRING;
|
||||
bind_array[0].buffer= (void *) koi8;
|
||||
bind_array[0].buffer_length= strlen(koi8);
|
||||
|
||||
bind_array[1].buffer_type= MYSQL_TYPE_STRING;
|
||||
bind_array[1].buffer= (void *) koi8;
|
||||
bind_array[1].buffer_length= strlen(koi8);
|
||||
|
||||
mysql_stmt_bind_param(stmt, bind_array);
|
||||
|
||||
// mysql_stmt_send_long_data(stmt, 0, koi8, strlen(koi8));
|
||||
|
||||
rc= mysql_stmt_execute(stmt);
|
||||
check_stmt_rc(rc, stmt);
|
||||
/* this data must not be converted */
|
||||
bind_array[0].buffer_type= MYSQL_TYPE_BLOB;
|
||||
bind_array[0].buffer= (void *) cp1251;
|
||||
bind_array[0].buffer_length= strlen(cp1251);
|
||||
|
||||
bind_array[1].buffer_type= MYSQL_TYPE_BLOB;
|
||||
bind_array[1].buffer= (void *) cp1251;
|
||||
bind_array[1].buffer_length= strlen(cp1251);
|
||||
|
||||
mysql_stmt_bind_param(stmt, bind_array);
|
||||
|
||||
// mysql_stmt_send_long_data(stmt, 0, cp1251, strlen(cp1251));
|
||||
|
||||
rc= mysql_stmt_execute(stmt);
|
||||
check_stmt_rc(rc, stmt);
|
||||
/* Fetch data and verify that rows are in koi8 */
|
||||
|
||||
stmt_text= "SELECT c1, c2 FROM t1";
|
||||
|
||||
/* c1 and c2 are binary so no conversion will be done on select */
|
||||
rc= mysql_stmt_prepare(stmt, stmt_text, strlen(stmt_text));
|
||||
check_stmt_rc(rc, stmt);
|
||||
rc= mysql_stmt_execute(stmt);
|
||||
check_stmt_rc(rc, stmt);
|
||||
bind_array[0].buffer= buf1;
|
||||
bind_array[0].buffer_length= sizeof(buf1);
|
||||
bind_array[0].length= &buf1_len;
|
||||
|
||||
bind_array[1].buffer= buf2;
|
||||
bind_array[1].buffer_length= sizeof(buf2);
|
||||
bind_array[1].length= &buf2_len;
|
||||
|
||||
mysql_stmt_bind_result(stmt, bind_array);
|
||||
|
||||
while ((rc= mysql_stmt_fetch(stmt)) == 0)
|
||||
{
|
||||
FAIL_UNLESS(buf1_len == strlen(koi8), "buf1_len != strlen(koi8)");
|
||||
FAIL_UNLESS(buf2_len == strlen(koi8), "buf2_len != strlen(koi8)");
|
||||
FAIL_UNLESS(!memcmp(buf1, koi8, buf1_len), "buf1 != koi8");
|
||||
FAIL_UNLESS(!memcmp(buf2, koi8, buf1_len), "buf2 != koi8");
|
||||
}
|
||||
FAIL_UNLESS(rc == MYSQL_NO_DATA, "rc != MYSQL_NO_DATA");
|
||||
mysql_stmt_close(stmt);
|
||||
|
||||
stmt_text= "DROP TABLE t1";
|
||||
rc= mysql_real_query(mysql, stmt_text, strlen(stmt_text));
|
||||
check_mysql_rc(rc, mysql);
|
||||
stmt_text= "SET NAMES DEFAULT";
|
||||
rc= mysql_real_query(mysql, stmt_text, strlen(stmt_text));
|
||||
check_mysql_rc(rc, mysql);
|
||||
return OK;
|
||||
}
|
||||
|
||||
/*
|
||||
Bug#30472: libmysql doesn't reset charset, insert_id after succ.
|
||||
mysql_change_user() call row insertions.
|
||||
*/
|
||||
|
||||
static int bug30472_retrieve_charset_info(MYSQL *con,
|
||||
char *character_set_name,
|
||||
char *character_set_client,
|
||||
char *character_set_results,
|
||||
char *collation_connection)
|
||||
{
|
||||
MYSQL_RES *rs;
|
||||
MYSQL_ROW row;
|
||||
int rc;
|
||||
|
||||
/* Get the cached client character set name. */
|
||||
|
||||
strcpy(character_set_name, mysql_character_set_name(con));
|
||||
|
||||
/* Retrieve server character set information. */
|
||||
|
||||
rc= mysql_query(con, "SHOW VARIABLES LIKE 'character_set_client'");
|
||||
check_mysql_rc(rc, con);
|
||||
|
||||
rs= mysql_store_result(con);
|
||||
FAIL_IF(!rs, "Invalid result set");
|
||||
row= mysql_fetch_row(rs);
|
||||
FAIL_IF(!row, "Couldn't fetch row");
|
||||
strcpy(character_set_client, row[1]);
|
||||
mysql_free_result(rs);
|
||||
|
||||
rc= mysql_query(con, "SHOW VARIABLES LIKE 'character_set_results'");
|
||||
check_mysql_rc(rc, con);
|
||||
rs= mysql_store_result(con);
|
||||
FAIL_IF(!rs, "Invalid result set");
|
||||
row= mysql_fetch_row(rs);
|
||||
FAIL_IF(!row, "Couldn't fetch row");
|
||||
strcpy(character_set_results, row[1]);
|
||||
mysql_free_result(rs);
|
||||
|
||||
rc= mysql_query(con, "SHOW VARIABLES LIKE 'collation_connection'");
|
||||
check_mysql_rc(rc, con);
|
||||
rs= mysql_store_result(con);
|
||||
FAIL_IF(!rs, "Invalid result set");
|
||||
row= mysql_fetch_row(rs);
|
||||
FAIL_IF(!row, "Couldn't fetch row");
|
||||
strcpy(collation_connection, row[1]);
|
||||
mysql_free_result(rs);
|
||||
return OK;
|
||||
}
|
||||
|
||||
#define MY_CS_NAME_SIZE 32
|
||||
|
||||
static int test_bug30472(MYSQL *mysql)
|
||||
{
|
||||
int rc;
|
||||
|
||||
char character_set_name_1[MY_CS_NAME_SIZE];
|
||||
char character_set_client_1[MY_CS_NAME_SIZE];
|
||||
char character_set_results_1[MY_CS_NAME_SIZE];
|
||||
char collation_connnection_1[MY_CS_NAME_SIZE];
|
||||
|
||||
char character_set_name_2[MY_CS_NAME_SIZE];
|
||||
char character_set_client_2[MY_CS_NAME_SIZE];
|
||||
char character_set_results_2[MY_CS_NAME_SIZE];
|
||||
char collation_connnection_2[MY_CS_NAME_SIZE];
|
||||
|
||||
char character_set_name_3[MY_CS_NAME_SIZE];
|
||||
char character_set_client_3[MY_CS_NAME_SIZE];
|
||||
char character_set_results_3[MY_CS_NAME_SIZE];
|
||||
char collation_connnection_3[MY_CS_NAME_SIZE];
|
||||
|
||||
char character_set_name_4[MY_CS_NAME_SIZE];
|
||||
char character_set_client_4[MY_CS_NAME_SIZE];
|
||||
char character_set_results_4[MY_CS_NAME_SIZE];
|
||||
char collation_connnection_4[MY_CS_NAME_SIZE];
|
||||
|
||||
if (mysql_get_server_version(mysql) < 50100) {
|
||||
diag("Test requires MySQL Server version 5.1 or above");
|
||||
return SKIP;
|
||||
}
|
||||
/* Retrieve character set information. */
|
||||
|
||||
bug30472_retrieve_charset_info(mysql,
|
||||
character_set_name_1,
|
||||
character_set_client_1,
|
||||
character_set_results_1,
|
||||
collation_connnection_1);
|
||||
|
||||
/* Switch client character set. */
|
||||
|
||||
FAIL_IF(mysql_set_character_set(mysql, "utf8"), "Setting cs to utf8 failed");
|
||||
|
||||
/* Retrieve character set information. */
|
||||
|
||||
bug30472_retrieve_charset_info(mysql,
|
||||
character_set_name_2,
|
||||
character_set_client_2,
|
||||
character_set_results_2,
|
||||
collation_connnection_2);
|
||||
|
||||
/*
|
||||
Check that
|
||||
1) character set has been switched and
|
||||
2) new character set is different from the original one.
|
||||
*/
|
||||
|
||||
FAIL_UNLESS(strcmp(character_set_name_2, "utf8") == 0, "cs_name != utf8");
|
||||
FAIL_UNLESS(strcmp(character_set_client_2, "utf8") == 0, "cs_client != utf8");
|
||||
FAIL_UNLESS(strcmp(character_set_results_2, "utf8") == 0, "cs_result != ut8");
|
||||
FAIL_UNLESS(strcmp(collation_connnection_2, "utf8_general_ci") == 0, "collation != utf8_general_ci");
|
||||
|
||||
FAIL_UNLESS(strcmp(character_set_name_1, character_set_name_2) != 0, "cs_name1 = cs_name2");
|
||||
FAIL_UNLESS(strcmp(character_set_client_1, character_set_client_2) != 0, "cs_client1 = cs_client2");
|
||||
FAIL_UNLESS(strcmp(character_set_results_1, character_set_results_2) != 0, "cs_result1 = cs_result2");
|
||||
FAIL_UNLESS(strcmp(collation_connnection_1, collation_connnection_2) != 0, "collation1 = collation2");
|
||||
|
||||
/* Call mysql_change_user() with the same username, password, database. */
|
||||
|
||||
rc= mysql_change_user(mysql, username, password, (schema) ? schema : "test");
|
||||
check_mysql_rc(rc, mysql);
|
||||
|
||||
/* Retrieve character set information. */
|
||||
|
||||
bug30472_retrieve_charset_info(mysql,
|
||||
character_set_name_3,
|
||||
character_set_client_3,
|
||||
character_set_results_3,
|
||||
collation_connnection_3);
|
||||
|
||||
/* Check that character set information has been reset. */
|
||||
|
||||
FAIL_UNLESS(strcmp(character_set_name_1, character_set_name_3) == 0, "cs_name1 != cs_name3");
|
||||
FAIL_UNLESS(strcmp(character_set_client_1, character_set_client_3) == 0, "cs_client1 != cs_client3");
|
||||
FAIL_UNLESS(strcmp(character_set_results_1, character_set_results_3) == 0, "cs_result1 != cs_result3");
|
||||
FAIL_UNLESS(strcmp(collation_connnection_1, collation_connnection_3) == 0, "collation1 != collation3");
|
||||
|
||||
/* Change connection-default character set in the client. */
|
||||
|
||||
mysql_options(mysql, MYSQL_SET_CHARSET_NAME, "utf8");
|
||||
|
||||
/*
|
||||
Call mysql_change_user() in order to check that new connection will
|
||||
have UTF8 character set on the client and on the server.
|
||||
*/
|
||||
|
||||
rc= mysql_change_user(mysql, username, password, (schema) ? schema : "test");
|
||||
check_mysql_rc(rc, mysql);
|
||||
|
||||
/* Retrieve character set information. */
|
||||
|
||||
bug30472_retrieve_charset_info(mysql,
|
||||
character_set_name_4,
|
||||
character_set_client_4,
|
||||
character_set_results_4,
|
||||
collation_connnection_4);
|
||||
|
||||
/* Check that we have UTF8 on the server and on the client. */
|
||||
|
||||
FAIL_UNLESS(strcmp(character_set_name_4, "utf8") == 0, "cs_name != utf8");
|
||||
FAIL_UNLESS(strcmp(character_set_client_4, "utf8") == 0, "cs_client != utf8");
|
||||
FAIL_UNLESS(strcmp(character_set_results_4, "utf8") == 0, "cs_result != utf8");
|
||||
FAIL_UNLESS(strcmp(collation_connnection_4, "utf8_general_ci") == 0, "collation_connection != utf8_general_ci");
|
||||
|
||||
/* That's it. Cleanup. */
|
||||
|
||||
return OK;
|
||||
}
|
||||
|
||||
static int test_bug_54100(MYSQL *mysql)
|
||||
{
|
||||
MYSQL_RES *result;
|
||||
MYSQL_ROW row;
|
||||
int rc;
|
||||
|
||||
rc= mysql_query(mysql, "SHOW CHARACTER SET");
|
||||
check_mysql_rc(rc, mysql);
|
||||
|
||||
result= mysql_store_result(mysql);
|
||||
|
||||
while ((row= mysql_fetch_row(result)))
|
||||
{
|
||||
/* ignore ucs2 */
|
||||
if (strcmp(row[0], "ucs2") && strcmp(row[0], "utf16le") && strcmp(row[0], "utf8mb4") &&
|
||||
strcmp(row[0], "utf16") && strcmp(row[0], "utf32")) {
|
||||
rc= mysql_set_character_set(mysql, row[0]);
|
||||
check_mysql_rc(rc, mysql);
|
||||
}
|
||||
}
|
||||
mysql_free_result(result);
|
||||
|
||||
return OK;
|
||||
}
|
||||
|
||||
|
||||
struct my_tests_st my_tests[] = {
|
||||
{"bug_8378: mysql_real_escape with gbk", bug_8378, TEST_CONNECTION_NEW, 0, opt_bug8378, NULL},
|
||||
{"test_client_character_set", test_client_character_set, TEST_CONNECTION_DEFAULT, 0, NULL, NULL},
|
||||
{"bug_10214: mysql_real_escape with NO_BACKSLASH_ESCAPES", bug_10214, TEST_CONNECTION_DEFAULT, 0, NULL, NULL},
|
||||
{"test_escaping", test_escaping, TEST_CONNECTION_DEFAULT, 0, NULL, NULL},
|
||||
{"test_conversion", test_conversion, TEST_CONNECTION_DEFAULT, 0, NULL, NULL},
|
||||
{"bug_41785", bug_41785, TEST_CONNECTION_DEFAULT, 0, NULL, "not fixed yet"},
|
||||
{"test_bug27876", test_bug27876, TEST_CONNECTION_DEFAULT, 0, NULL, NULL},
|
||||
{"test_bug30472", test_bug30472, TEST_CONNECTION_NEW, 0, NULL, NULL},
|
||||
{"test_ps_i18n", test_ps_i18n, TEST_CONNECTION_DEFAULT, 0, NULL, NULL},
|
||||
{"test_bug_54100", test_bug_54100, TEST_CONNECTION_NEW, 0, NULL, NULL},
|
||||
{NULL, NULL, 0, 0, NULL, 0}
|
||||
};
|
||||
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
if (argc > 1)
|
||||
get_options(argc, argv);
|
||||
|
||||
get_envvars();
|
||||
|
||||
run_tests(my_tests);
|
||||
|
||||
return(exit_status());
|
||||
}
|
512
unittest/libmariadb/connection.c
Normal file
512
unittest/libmariadb/connection.c
Normal file
@@ -0,0 +1,512 @@
|
||||
/*
|
||||
Copyright (c) 2009, 2010, Oracle and/or its affiliates. All rights reserved.
|
||||
|
||||
The MySQL Connector/C is licensed under the terms of the GPLv2
|
||||
<http://www.gnu.org/licenses/old-licenses/gpl-2.0.html>, like most
|
||||
MySQL Connectors. There are special exceptions to the terms and
|
||||
conditions of the GPLv2 as it is applied to this software, see the
|
||||
FLOSS License Exception
|
||||
<http://www.mysql.com/about/legal/licensing/foss-exception.html>.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published
|
||||
by the Free Software Foundation; version 2 of the License.
|
||||
|
||||
This program is distributed in the hope that it will be useful, but
|
||||
WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License along
|
||||
with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
/**
|
||||
Some basic tests of the client API.
|
||||
*/
|
||||
|
||||
#include "my_test.h"
|
||||
|
||||
static int test_bug20023(MYSQL *mysql)
|
||||
{
|
||||
int sql_big_selects_orig;
|
||||
int max_join_size_orig;
|
||||
|
||||
int sql_big_selects_2;
|
||||
int sql_big_selects_3;
|
||||
int sql_big_selects_4;
|
||||
int sql_big_selects_5;
|
||||
int rc;
|
||||
|
||||
if (mysql_get_server_version(mysql) < 50100) {
|
||||
diag("Test requires MySQL Server version 5.1 or above");
|
||||
return SKIP;
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
Remember original SQL_BIG_SELECTS, MAX_JOIN_SIZE values.
|
||||
***********************************************************************/
|
||||
|
||||
query_int_variable(mysql,
|
||||
"@@session.sql_big_selects",
|
||||
&sql_big_selects_orig);
|
||||
|
||||
query_int_variable(mysql,
|
||||
"@@global.max_join_size",
|
||||
&max_join_size_orig);
|
||||
|
||||
/***********************************************************************
|
||||
Test that COM_CHANGE_USER resets the SQL_BIG_SELECTS to the initial value.
|
||||
***********************************************************************/
|
||||
|
||||
/* Issue COM_CHANGE_USER. */
|
||||
rc= mysql_change_user(mysql, username, password, schema);
|
||||
check_mysql_rc(rc, mysql);
|
||||
|
||||
/* Query SQL_BIG_SELECTS. */
|
||||
|
||||
query_int_variable(mysql,
|
||||
"@@session.sql_big_selects",
|
||||
&sql_big_selects_2);
|
||||
|
||||
/* Check that SQL_BIG_SELECTS is reset properly. */
|
||||
|
||||
FAIL_UNLESS(sql_big_selects_orig == sql_big_selects_2, "Different value for sql_big_select");
|
||||
|
||||
/***********************************************************************
|
||||
Test that if MAX_JOIN_SIZE set to non-default value,
|
||||
SQL_BIG_SELECTS will be 0.
|
||||
***********************************************************************/
|
||||
|
||||
/* Set MAX_JOIN_SIZE to some non-default value. */
|
||||
|
||||
rc= mysql_query(mysql, "SET @@global.max_join_size = 10000");
|
||||
check_mysql_rc(rc, mysql);
|
||||
rc= mysql_query(mysql, "SET @@session.max_join_size = default");
|
||||
check_mysql_rc(rc, mysql);
|
||||
|
||||
/* Issue COM_CHANGE_USER. */
|
||||
|
||||
rc= mysql_change_user(mysql, username, password, schema);
|
||||
check_mysql_rc(rc, mysql);
|
||||
|
||||
/* Query SQL_BIG_SELECTS. */
|
||||
|
||||
query_int_variable(mysql,
|
||||
"@@session.sql_big_selects",
|
||||
&sql_big_selects_3);
|
||||
|
||||
/* Check that SQL_BIG_SELECTS is 0. */
|
||||
|
||||
FAIL_UNLESS(sql_big_selects_3 == 0, "big_selects != 0");
|
||||
|
||||
/***********************************************************************
|
||||
Test that if MAX_JOIN_SIZE set to default value,
|
||||
SQL_BIG_SELECTS will be 1.
|
||||
***********************************************************************/
|
||||
|
||||
/* Set MAX_JOIN_SIZE to the default value (-1). */
|
||||
|
||||
rc= mysql_query(mysql, "SET @@global.max_join_size = cast(-1 as unsigned int)");
|
||||
rc= mysql_query(mysql, "SET @@session.max_join_size = default");
|
||||
|
||||
/* Issue COM_CHANGE_USER. */
|
||||
|
||||
rc= mysql_change_user(mysql, username, password, schema);
|
||||
check_mysql_rc(rc, mysql);
|
||||
|
||||
/* Query SQL_BIG_SELECTS. */
|
||||
|
||||
query_int_variable(mysql,
|
||||
"@@session.sql_big_selects",
|
||||
&sql_big_selects_4);
|
||||
|
||||
/* Check that SQL_BIG_SELECTS is 1. */
|
||||
|
||||
FAIL_UNLESS(sql_big_selects_4 == 1, "sql_big_select != 1");
|
||||
|
||||
/***********************************************************************
|
||||
Restore MAX_JOIN_SIZE.
|
||||
Check that SQL_BIG_SELECTS will be the original one.
|
||||
***********************************************************************/
|
||||
|
||||
rc= mysql_query(mysql, "SET @@global.max_join_size = cast(-1 as unsigned int)");
|
||||
check_mysql_rc(rc, mysql);
|
||||
|
||||
rc= mysql_query(mysql, "SET @@session.max_join_size = default");
|
||||
check_mysql_rc(rc, mysql);
|
||||
|
||||
/* Issue COM_CHANGE_USER. */
|
||||
|
||||
rc= mysql_change_user(mysql, username, password, schema);
|
||||
check_mysql_rc(rc, mysql);
|
||||
|
||||
/* Query SQL_BIG_SELECTS. */
|
||||
|
||||
query_int_variable(mysql,
|
||||
"@@session.sql_big_selects",
|
||||
&sql_big_selects_5);
|
||||
|
||||
/* Check that SQL_BIG_SELECTS is 1. */
|
||||
|
||||
FAIL_UNLESS(sql_big_selects_5 == sql_big_selects_orig, "big_select != 1");
|
||||
|
||||
/***********************************************************************
|
||||
That's it. Cleanup.
|
||||
***********************************************************************/
|
||||
|
||||
return OK;
|
||||
}
|
||||
|
||||
static int test_change_user(MYSQL *mysql)
|
||||
{
|
||||
char buff[256];
|
||||
const char *user_pw= "mysqltest_pw";
|
||||
const char *user_no_pw= "mysqltest_no_pw";
|
||||
const char *pw= "password";
|
||||
const char *db= "mysqltest_user_test_database";
|
||||
int rc;
|
||||
|
||||
DBUG_ENTER("test_change_user");
|
||||
|
||||
/* Prepare environment */
|
||||
sprintf(buff, "drop database if exists %s", db);
|
||||
rc= mysql_query(mysql, buff);
|
||||
check_mysql_rc(rc, mysql)
|
||||
|
||||
sprintf(buff, "create database %s", db);
|
||||
rc= mysql_query(mysql, buff);
|
||||
check_mysql_rc(rc, mysql)
|
||||
|
||||
sprintf(buff,
|
||||
"grant select on %s.* to %s@'%%' identified by '%s'",
|
||||
db,
|
||||
user_pw,
|
||||
pw);
|
||||
rc= mysql_query(mysql, buff);
|
||||
check_mysql_rc(rc, mysql)
|
||||
|
||||
sprintf(buff,
|
||||
"grant select on %s.* to %s@'%%'",
|
||||
db,
|
||||
user_no_pw);
|
||||
rc= mysql_query(mysql, buff);
|
||||
check_mysql_rc(rc, mysql)
|
||||
|
||||
|
||||
/* Try some combinations */
|
||||
rc= mysql_change_user(mysql, NULL, NULL, NULL);
|
||||
FAIL_UNLESS(rc, "Error expected");
|
||||
|
||||
|
||||
rc= mysql_change_user(mysql, "", NULL, NULL);
|
||||
FAIL_UNLESS(rc, "Error expected");
|
||||
|
||||
rc= mysql_change_user(mysql, "", "", NULL);
|
||||
FAIL_UNLESS(rc, "Error expected");
|
||||
|
||||
rc= mysql_change_user(mysql, "", "", "");
|
||||
FAIL_UNLESS(rc, "Error expected");
|
||||
|
||||
rc= mysql_change_user(mysql, NULL, "", "");
|
||||
FAIL_UNLESS(rc, "Error expected");
|
||||
|
||||
|
||||
rc= mysql_change_user(mysql, NULL, NULL, "");
|
||||
FAIL_UNLESS(rc, "Error expected");
|
||||
|
||||
rc= mysql_change_user(mysql, "", NULL, "");
|
||||
FAIL_UNLESS(rc, "Error expected");
|
||||
|
||||
rc= mysql_change_user(mysql, user_pw, NULL, "");
|
||||
FAIL_UNLESS(rc, "Error expected");
|
||||
|
||||
rc= mysql_change_user(mysql, user_pw, "", "");
|
||||
FAIL_UNLESS(rc, "Error expected");
|
||||
|
||||
rc= mysql_change_user(mysql, user_pw, "", NULL);
|
||||
FAIL_UNLESS(rc, "Error expected");
|
||||
|
||||
rc= mysql_change_user(mysql, user_pw, NULL, NULL);
|
||||
FAIL_UNLESS(rc, "Error expected");
|
||||
|
||||
rc= mysql_change_user(mysql, user_pw, "", db);
|
||||
FAIL_UNLESS(rc, "Error expected");
|
||||
|
||||
rc= mysql_change_user(mysql, user_pw, NULL, db);
|
||||
FAIL_UNLESS(rc, "Error expected");
|
||||
|
||||
rc= mysql_change_user(mysql, user_pw, pw, db);
|
||||
check_mysql_rc(rc, mysql)
|
||||
|
||||
rc= mysql_change_user(mysql, user_pw, pw, NULL);
|
||||
check_mysql_rc(rc, mysql)
|
||||
|
||||
rc= mysql_change_user(mysql, user_pw, pw, "");
|
||||
check_mysql_rc(rc, mysql)
|
||||
|
||||
rc= mysql_change_user(mysql, user_no_pw, pw, db);
|
||||
FAIL_UNLESS(rc, "Error expected");
|
||||
|
||||
rc= mysql_change_user(mysql, user_no_pw, pw, "");
|
||||
FAIL_UNLESS(rc, "Error expected");
|
||||
|
||||
rc= mysql_change_user(mysql, user_no_pw, pw, NULL);
|
||||
FAIL_UNLESS(rc, "Error expected");
|
||||
|
||||
rc= mysql_change_user(mysql, user_no_pw, "", NULL);
|
||||
check_mysql_rc(rc, mysql)
|
||||
|
||||
rc= mysql_change_user(mysql, user_no_pw, "", "");
|
||||
check_mysql_rc(rc, mysql)
|
||||
|
||||
rc= mysql_change_user(mysql, user_no_pw, "", db);
|
||||
check_mysql_rc(rc, mysql)
|
||||
|
||||
rc= mysql_change_user(mysql, user_no_pw, NULL, db);
|
||||
check_mysql_rc(rc, mysql)
|
||||
|
||||
rc= mysql_change_user(mysql, "", pw, db);
|
||||
FAIL_UNLESS(rc, "Error expected");
|
||||
|
||||
rc= mysql_change_user(mysql, "", pw, "");
|
||||
FAIL_UNLESS(rc, "Error expected");
|
||||
|
||||
rc= mysql_change_user(mysql, "", pw, NULL);
|
||||
FAIL_UNLESS(rc, "Error expected");
|
||||
|
||||
rc= mysql_change_user(mysql, NULL, pw, NULL);
|
||||
FAIL_UNLESS(rc, "Error expected");
|
||||
|
||||
rc= mysql_change_user(mysql, NULL, NULL, db);
|
||||
FAIL_UNLESS(rc, "Error expected");
|
||||
|
||||
rc= mysql_change_user(mysql, NULL, "", db);
|
||||
FAIL_UNLESS(rc, "Error expected");
|
||||
|
||||
rc= mysql_change_user(mysql, "", "", db);
|
||||
FAIL_UNLESS(rc, "Error expected");
|
||||
|
||||
/* Cleanup the environment */
|
||||
|
||||
rc= mysql_change_user(mysql, username, password, schema);
|
||||
check_mysql_rc(rc, mysql);
|
||||
|
||||
sprintf(buff, "drop database %s", db);
|
||||
rc= mysql_query(mysql, buff);
|
||||
check_mysql_rc(rc, mysql)
|
||||
|
||||
sprintf(buff, "drop user %s@'%%'", user_pw);
|
||||
rc= mysql_query(mysql, buff);
|
||||
check_mysql_rc(rc, mysql)
|
||||
|
||||
sprintf(buff, "drop user %s@'%%'", user_no_pw);
|
||||
rc= mysql_query(mysql, buff);
|
||||
check_mysql_rc(rc, mysql)
|
||||
|
||||
return OK;
|
||||
}
|
||||
|
||||
/**
|
||||
Bug#31669 Buffer overflow in mysql_change_user()
|
||||
*/
|
||||
|
||||
#define LARGE_BUFFER_SIZE 2048
|
||||
|
||||
static int test_bug31669(MYSQL *mysql)
|
||||
{
|
||||
int rc;
|
||||
static char buff[LARGE_BUFFER_SIZE+1];
|
||||
static char user[USERNAME_CHAR_LENGTH+1];
|
||||
static char db[NAME_CHAR_LEN+1];
|
||||
static char query[LARGE_BUFFER_SIZE*2];
|
||||
|
||||
rc= mysql_change_user(mysql, NULL, NULL, NULL);
|
||||
FAIL_UNLESS(rc, "Error expected");
|
||||
|
||||
rc= mysql_change_user(mysql, "", "", "");
|
||||
FAIL_UNLESS(rc, "Error expected");
|
||||
|
||||
memset(buff, 'a', sizeof(buff));
|
||||
|
||||
rc= mysql_change_user(mysql, buff, buff, buff);
|
||||
FAIL_UNLESS(rc, "Error epected");
|
||||
|
||||
rc = mysql_change_user(mysql, username, password, schema);
|
||||
check_mysql_rc(rc, mysql);
|
||||
|
||||
memset(db, 'a', sizeof(db));
|
||||
db[NAME_CHAR_LEN]= 0;
|
||||
sprintf(query, "CREATE DATABASE IF NOT EXISTS %s", db);
|
||||
rc= mysql_query(mysql, query);
|
||||
check_mysql_rc(rc, mysql);
|
||||
|
||||
memset(user, 'b', sizeof(user));
|
||||
user[USERNAME_CHAR_LENGTH]= 0;
|
||||
memset(buff, 'c', sizeof(buff));
|
||||
buff[LARGE_BUFFER_SIZE]= 0;
|
||||
sprintf(query, "GRANT ALL PRIVILEGES ON *.* TO '%s'@'%%' IDENTIFIED BY '%s' WITH GRANT OPTION", user, buff);
|
||||
rc= mysql_query(mysql, query);
|
||||
check_mysql_rc(rc, mysql);
|
||||
|
||||
rc= mysql_query(mysql, "FLUSH PRIVILEGES");
|
||||
check_mysql_rc(rc, mysql);
|
||||
|
||||
rc= mysql_change_user(mysql, user, buff, db);
|
||||
check_mysql_rc(rc, mysql);
|
||||
|
||||
user[USERNAME_CHAR_LENGTH-1]= 'a';
|
||||
rc= mysql_change_user(mysql, user, buff, db);
|
||||
FAIL_UNLESS(rc, "Error expected");
|
||||
|
||||
user[USERNAME_CHAR_LENGTH-1]= 'b';
|
||||
buff[LARGE_BUFFER_SIZE-1]= 'd';
|
||||
rc= mysql_change_user(mysql, user, buff, db);
|
||||
FAIL_UNLESS(rc, "Error expected");
|
||||
|
||||
buff[LARGE_BUFFER_SIZE-1]= 'c';
|
||||
db[NAME_CHAR_LEN-1]= 'e';
|
||||
rc= mysql_change_user(mysql, user, buff, db);
|
||||
FAIL_UNLESS(rc, "Error expected");
|
||||
|
||||
db[NAME_CHAR_LEN-1]= 'a';
|
||||
rc= mysql_change_user(mysql, user, buff, db);
|
||||
FAIL_UNLESS(!rc, "Error expected");
|
||||
|
||||
rc= mysql_change_user(mysql, user + 1, buff + 1, db + 1);
|
||||
FAIL_UNLESS(rc, "Error expected");
|
||||
|
||||
rc = mysql_change_user(mysql, username, password, schema);
|
||||
check_mysql_rc(rc, mysql);
|
||||
|
||||
sprintf(query, "DROP DATABASE %s", db);
|
||||
rc= mysql_query(mysql, query);
|
||||
check_mysql_rc(rc, mysql);
|
||||
|
||||
sprintf(query, "DELETE FROM mysql.user WHERE User='%s'", user);
|
||||
rc= mysql_query(mysql, query);
|
||||
check_mysql_rc(rc, mysql);
|
||||
FAIL_UNLESS(mysql_affected_rows(mysql) == 1, "");
|
||||
|
||||
return OK;
|
||||
}
|
||||
|
||||
/**
|
||||
Bug# 33831 mysql_real_connect() should fail if
|
||||
given an already connected MYSQL handle.
|
||||
*/
|
||||
|
||||
static int test_bug33831(MYSQL *mysql)
|
||||
{
|
||||
FAIL_IF(mysql_real_connect(mysql, hostname, username,
|
||||
password, schema, port, socketname, 0),
|
||||
"Error expected");
|
||||
|
||||
return OK;
|
||||
}
|
||||
|
||||
/* Test MYSQL_OPT_RECONNECT, Bug#15719 */
|
||||
|
||||
static int test_opt_reconnect(MYSQL *mysql)
|
||||
{
|
||||
my_bool my_true= TRUE;
|
||||
int rc;
|
||||
|
||||
mysql= mysql_init(NULL);
|
||||
FAIL_IF(!mysql, "not enough memory");
|
||||
|
||||
FAIL_UNLESS(mysql->reconnect == 0, "reconnect != 0");
|
||||
|
||||
rc= mysql_options(mysql, MYSQL_OPT_RECONNECT, &my_true);
|
||||
check_mysql_rc(rc, mysql);
|
||||
|
||||
FAIL_UNLESS(mysql->reconnect == 1, "reconnect != 1");
|
||||
|
||||
if (!(mysql_real_connect(mysql, hostname, username,
|
||||
password, schema, port,
|
||||
socketname, 0)))
|
||||
{
|
||||
diag("connection failed");
|
||||
mysql_close(mysql);
|
||||
return FAIL;
|
||||
}
|
||||
|
||||
FAIL_UNLESS(mysql->reconnect == 1, "reconnect != 1");
|
||||
|
||||
mysql_close(mysql);
|
||||
|
||||
mysql= mysql_init(NULL);
|
||||
FAIL_IF(!mysql, "not enough memory");
|
||||
|
||||
FAIL_UNLESS(mysql->reconnect == 0, "reconnect != 0");
|
||||
|
||||
if (!(mysql_real_connect(mysql, hostname, username,
|
||||
password, schema, port,
|
||||
socketname, 0)))
|
||||
{
|
||||
diag("connection failed");
|
||||
mysql_close(mysql);
|
||||
return FAIL;
|
||||
}
|
||||
|
||||
FAIL_UNLESS(mysql->reconnect == 0, "reconnect != 0");
|
||||
|
||||
mysql_close(mysql);
|
||||
return OK;
|
||||
}
|
||||
|
||||
static int test_compress(MYSQL *mysql)
|
||||
{
|
||||
MYSQL_RES *res;
|
||||
MYSQL_ROW row;
|
||||
int rc;
|
||||
|
||||
mysql= mysql_init(NULL);
|
||||
FAIL_IF(!mysql, "not enough memory");
|
||||
|
||||
/* use compressed protocol */
|
||||
rc= mysql_options(mysql, MYSQL_OPT_COMPRESS, NULL);
|
||||
|
||||
|
||||
|
||||
if (!(mysql_real_connect(mysql, hostname, username,
|
||||
password, schema, port,
|
||||
socketname, 0)))
|
||||
{
|
||||
diag("connection failed");
|
||||
return FAIL;
|
||||
}
|
||||
|
||||
rc= mysql_query(mysql, "SHOW STATUS LIKE 'compression'");
|
||||
check_mysql_rc(rc, mysql);
|
||||
res= mysql_store_result(mysql);
|
||||
row= mysql_fetch_row(res);
|
||||
FAIL_UNLESS(strcmp(row[1], "ON") == 0, "Compression off");
|
||||
mysql_free_result(res);
|
||||
|
||||
mysql_close(mysql);
|
||||
return OK;
|
||||
}
|
||||
|
||||
struct my_tests_st my_tests[] = {
|
||||
{"test_bug20023", test_bug20023, TEST_CONNECTION_NEW, 0, NULL, NULL},
|
||||
{"test_bug31669", test_bug31669, TEST_CONNECTION_NEW, 0, NULL, NULL},
|
||||
{"test_bug33831", test_bug33831, TEST_CONNECTION_NEW, 0, NULL, NULL},
|
||||
{"test_change_user", test_change_user, TEST_CONNECTION_NEW, 0, NULL, NULL},
|
||||
{"test_opt_reconnect", test_opt_reconnect, TEST_CONNECTION_NONE, 0, NULL, NULL},
|
||||
{"test_compress", test_compress, TEST_CONNECTION_NONE, 0, NULL, NULL},
|
||||
{NULL, NULL, 0, 0, NULL, NULL}
|
||||
};
|
||||
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
if (argc > 1)
|
||||
get_options(argc, argv);
|
||||
|
||||
get_envvars();
|
||||
|
||||
run_tests(my_tests);
|
||||
|
||||
return(exit_status());
|
||||
}
|
1846
unittest/libmariadb/cursor.c
Normal file
1846
unittest/libmariadb/cursor.c
Normal file
File diff suppressed because it is too large
Load Diff
100
unittest/libmariadb/data.csv
Normal file
100
unittest/libmariadb/data.csv
Normal file
@@ -0,0 +1,100 @@
|
||||
00000100,1,60000.000000
|
||||
00000101,2,60000.000000
|
||||
00000102,3,60000.000000
|
||||
00000103,1,60000.000000
|
||||
00000104,2,60000.000000
|
||||
00000105,3,60000.000000
|
||||
00000106,1,60000.000000
|
||||
00000107,2,60000.000000
|
||||
00000108,3,60000.000000
|
||||
00000109,1,60000.000000
|
||||
00000110,2,60000.000000
|
||||
00000111,3,60000.000000
|
||||
00000112,1,60000.000000
|
||||
00000113,2,60000.000000
|
||||
00000114,3,60000.000000
|
||||
00000115,1,60000.000000
|
||||
00000116,2,60000.000000
|
||||
00000117,3,60000.000000
|
||||
00000118,1,60000.000000
|
||||
00000119,2,60000.000000
|
||||
00000120,3,60000.000000
|
||||
00000121,1,60000.000000
|
||||
00000122,2,60000.000000
|
||||
00000123,3,60000.000000
|
||||
00000124,1,60000.000000
|
||||
00000125,2,60000.000000
|
||||
00000126,3,60000.000000
|
||||
00000127,1,60000.000000
|
||||
00000128,2,60000.000000
|
||||
00000129,3,60000.000000
|
||||
00000130,1,60000.000000
|
||||
00000131,2,60000.000000
|
||||
00000132,3,60000.000000
|
||||
00000133,1,60000.000000
|
||||
00000134,2,60000.000000
|
||||
00000135,3,60000.000000
|
||||
00000136,1,60000.000000
|
||||
00000137,2,60000.000000
|
||||
00000138,3,60000.000000
|
||||
00000139,1,60000.000000
|
||||
00000140,2,60000.000000
|
||||
00000141,3,60000.000000
|
||||
00000142,1,60000.000000
|
||||
00000143,2,60000.000000
|
||||
00000144,3,60000.000000
|
||||
00000145,1,60000.000000
|
||||
00000146,2,60000.000000
|
||||
00000147,3,60000.000000
|
||||
00000148,1,60000.000000
|
||||
00000149,2,60000.000000
|
||||
00000150,3,60000.000000
|
||||
00000151,1,60000.000000
|
||||
00000152,2,60000.000000
|
||||
00000153,3,60000.000000
|
||||
00000154,1,60000.000000
|
||||
00000155,2,60000.000000
|
||||
00000156,3,60000.000000
|
||||
00000157,1,60000.000000
|
||||
00000158,2,60000.000000
|
||||
00000159,3,60000.000000
|
||||
00000160,1,60000.000000
|
||||
00000161,2,60000.000000
|
||||
00000162,3,60000.000000
|
||||
00000163,1,60000.000000
|
||||
00000164,2,60000.000000
|
||||
00000165,3,60000.000000
|
||||
00000166,1,60000.000000
|
||||
00000167,2,60000.000000
|
||||
00000168,3,60000.000000
|
||||
00000169,1,60000.000000
|
||||
00000170,2,60000.000000
|
||||
00000171,3,60000.000000
|
||||
00000172,1,60000.000000
|
||||
00000173,2,60000.000000
|
||||
00000174,3,60000.000000
|
||||
00000175,1,60000.000000
|
||||
00000176,2,60000.000000
|
||||
00000177,3,60000.000000
|
||||
00000178,1,60000.000000
|
||||
00000179,2,60000.000000
|
||||
00000180,3,60000.000000
|
||||
00000181,1,60000.000000
|
||||
00000182,2,60000.000000
|
||||
00000183,3,60000.000000
|
||||
00000184,1,60000.000000
|
||||
00000185,2,60000.000000
|
||||
00000186,3,60000.000000
|
||||
00000187,1,60000.000000
|
||||
00000188,2,60000.000000
|
||||
00000189,3,60000.000000
|
||||
00000190,1,60000.000000
|
||||
00000191,2,60000.000000
|
||||
00000192,3,60000.000000
|
||||
00000193,1,60000.000000
|
||||
00000194,2,60000.000000
|
||||
00000195,3,60000.000000
|
||||
00000196,1,60000.000000
|
||||
00000197,2,60000.000000
|
||||
00000198,3,60000.000000
|
||||
00000199,1,60000.000000
|
|
282
unittest/libmariadb/errors.c
Normal file
282
unittest/libmariadb/errors.c
Normal file
@@ -0,0 +1,282 @@
|
||||
/*
|
||||
Copyright (c) 2009, 2010, Oracle and/or its affiliates. All rights reserved.
|
||||
|
||||
The MySQL Connector/C is licensed under the terms of the GPLv2
|
||||
<http://www.gnu.org/licenses/old-licenses/gpl-2.0.html>, like most
|
||||
MySQL Connectors. There are special exceptions to the terms and
|
||||
conditions of the GPLv2 as it is applied to this software, see the
|
||||
FLOSS License Exception
|
||||
<http://www.mysql.com/about/legal/licensing/foss-exception.html>.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published
|
||||
by the Free Software Foundation; version 2 of the License.
|
||||
|
||||
This program is distributed in the hope that it will be useful, but
|
||||
WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License along
|
||||
with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
#include "my_test.h"
|
||||
|
||||
/* Test warnings */
|
||||
|
||||
static int test_client_warnings(MYSQL *mysql)
|
||||
{
|
||||
int rc;
|
||||
|
||||
rc= mysql_query(mysql, "DROP TABLE if exists test_non_exists");
|
||||
check_mysql_rc(rc, mysql);
|
||||
rc= mysql_query(mysql, "DROP TABLE if exists test_non_exists");
|
||||
check_mysql_rc(rc, mysql);
|
||||
|
||||
FAIL_IF(!mysql_warning_count(mysql), "Warning expected");
|
||||
|
||||
return OK;
|
||||
}
|
||||
|
||||
|
||||
static int test_ps_client_warnings(MYSQL *mysql)
|
||||
{
|
||||
int rc;
|
||||
MYSQL_STMT *stmt;
|
||||
char *query= "DROP TABLE IF EXISTS test_non_exists";
|
||||
|
||||
rc= mysql_query(mysql, "DROP TABLE if exists test_non_exists");
|
||||
check_mysql_rc(rc, mysql);
|
||||
|
||||
stmt= mysql_stmt_init(mysql);
|
||||
rc= mysql_stmt_prepare(stmt, query, strlen(query));
|
||||
FAIL_IF(rc, mysql_stmt_error(stmt));
|
||||
|
||||
rc= mysql_stmt_execute(stmt);
|
||||
FAIL_IF(rc, mysql_stmt_error(stmt));
|
||||
|
||||
FAIL_IF(!mysql_warning_count(mysql), "Warning expected");
|
||||
|
||||
mysql_stmt_close(stmt);
|
||||
|
||||
return OK;
|
||||
}
|
||||
|
||||
static int test_server_warnings(MYSQL *mysql)
|
||||
{
|
||||
int rc;
|
||||
MYSQL_RES *result;
|
||||
|
||||
rc= mysql_query(mysql, "DROP TABLE if exists test_non_exists");
|
||||
check_mysql_rc(rc, mysql);
|
||||
rc= mysql_query(mysql, "DROP TABLE if exists test_non_exists");
|
||||
check_mysql_rc(rc, mysql);
|
||||
|
||||
rc= mysql_query(mysql, "SHOW WARNINGS");
|
||||
check_mysql_rc(rc, mysql);
|
||||
|
||||
result= mysql_store_result(mysql);
|
||||
FAIL_IF(!result, mysql_error(mysql));
|
||||
FAIL_IF(!mysql_num_rows(result), "Empty resultset");
|
||||
|
||||
mysql_free_result(result);
|
||||
|
||||
return OK;
|
||||
}
|
||||
|
||||
|
||||
/* Test errors */
|
||||
|
||||
static int test_client_errors(MYSQL *mysql)
|
||||
{
|
||||
int rc;
|
||||
|
||||
rc= mysql_query(mysql, "DROP TABLE if exists test_non_exists");
|
||||
check_mysql_rc(rc, mysql);
|
||||
|
||||
rc= mysql_query(mysql, "DROP TABLE test_non_exists");
|
||||
FAIL_IF(!rc, "Error expected");
|
||||
|
||||
FAIL_IF(!mysql_errno(mysql), "Error expected");
|
||||
FAIL_IF(!strlen(mysql_error(mysql)), "Empty errormsg");
|
||||
FAIL_IF(strcmp(mysql_sqlstate(mysql), "00000") == 0, "Invalid SQLstate");
|
||||
|
||||
return OK;
|
||||
}
|
||||
|
||||
static int test_ps_client_errors(MYSQL *mysql)
|
||||
{
|
||||
int rc;
|
||||
MYSQL_STMT *stmt;
|
||||
char *query= "DROP TABLE test_non_exists";
|
||||
|
||||
rc= mysql_query(mysql, "DROP TABLE if exists test_non_exists");
|
||||
check_mysql_rc(rc, mysql);
|
||||
|
||||
stmt= mysql_stmt_init(mysql);
|
||||
rc= mysql_stmt_prepare(stmt, query, strlen(query));
|
||||
FAIL_IF(rc, mysql_stmt_error(stmt));
|
||||
|
||||
rc= mysql_stmt_execute(stmt);
|
||||
FAIL_IF(!rc, mysql_stmt_error(stmt));
|
||||
|
||||
FAIL_IF(!mysql_stmt_errno(stmt), "Error expected");
|
||||
FAIL_IF(!strlen(mysql_stmt_error(stmt)), "Empty errormsg");
|
||||
FAIL_IF(strcmp(mysql_stmt_sqlstate(stmt), "00000") == 0, "Invalid SQLstate");
|
||||
|
||||
mysql_stmt_close(stmt);
|
||||
|
||||
return OK;
|
||||
}
|
||||
|
||||
static int test_server_errors(MYSQL *mysql)
|
||||
{
|
||||
int rc;
|
||||
MYSQL_RES *result;
|
||||
|
||||
rc= mysql_query(mysql, "DROP TABLE if exists test_non_exists");
|
||||
check_mysql_rc(rc, mysql);
|
||||
|
||||
rc= mysql_query(mysql, "DROP TABLE test_non_exists");
|
||||
check_mysql_rc(rc, mysql);
|
||||
|
||||
rc= mysql_query(mysql, "SHOW ERRORS");
|
||||
check_mysql_rc(rc, mysql);
|
||||
|
||||
result= mysql_store_result(mysql);
|
||||
FAIL_IF(!result, mysql_error(mysql));
|
||||
FAIL_IF(!mysql_num_rows(result), "Empty resultset");
|
||||
mysql_free_result(result);
|
||||
|
||||
return OK;
|
||||
}
|
||||
|
||||
/* Bug #16143: mysql_stmt_sqlstate returns an empty string instead of '00000' */
|
||||
|
||||
static int test_bug16143(MYSQL *mysql)
|
||||
{
|
||||
MYSQL_STMT *stmt;
|
||||
|
||||
stmt= mysql_stmt_init(mysql);
|
||||
FAIL_IF(!stmt, mysql_error(mysql));
|
||||
|
||||
/* Check mysql_stmt_sqlstate return "no error" */
|
||||
FAIL_UNLESS(strcmp(mysql_stmt_sqlstate(stmt), "00000") == 0, "Expected SQLstate 000000");
|
||||
|
||||
mysql_stmt_close(stmt);
|
||||
|
||||
return OK;
|
||||
}
|
||||
|
||||
/* Test warnings for cuted rows */
|
||||
|
||||
static int test_cuted_rows(MYSQL *mysql)
|
||||
{
|
||||
int rc, count;
|
||||
MYSQL_RES *result;
|
||||
|
||||
|
||||
mysql_query(mysql, "DROP TABLE if exists t1");
|
||||
mysql_query(mysql, "DROP TABLE if exists t2");
|
||||
|
||||
rc= mysql_query(mysql, "CREATE TABLE t1(c1 tinyint)");
|
||||
check_mysql_rc(rc, mysql);
|
||||
|
||||
rc= mysql_query(mysql, "CREATE TABLE t2(c1 int not null)");
|
||||
check_mysql_rc(rc, mysql);
|
||||
|
||||
rc= mysql_query(mysql, "INSERT INTO t1 values(10), (NULL), (NULL)");
|
||||
check_mysql_rc(rc, mysql);
|
||||
|
||||
count= mysql_warning_count(mysql);
|
||||
FAIL_UNLESS(count == 0, "warnings != 0");
|
||||
|
||||
rc= mysql_query(mysql, "INSERT INTO t2 SELECT * FROM t1");
|
||||
check_mysql_rc(rc, mysql);
|
||||
|
||||
count= mysql_warning_count(mysql);
|
||||
FAIL_UNLESS(count == 2, "warnings != 2");
|
||||
|
||||
rc= mysql_query(mysql, "SHOW WARNINGS");
|
||||
check_mysql_rc(rc, mysql);
|
||||
|
||||
result= mysql_store_result(mysql);
|
||||
FAIL_IF(!result, "Invalid result set");
|
||||
|
||||
rc= 0;
|
||||
while (mysql_fetch_row(result))
|
||||
rc++;
|
||||
FAIL_UNLESS(rc == 2, "rowcount != 2");
|
||||
mysql_free_result(result);
|
||||
|
||||
rc= mysql_query(mysql, "INSERT INTO t1 VALUES('junk'), (876789)");
|
||||
check_mysql_rc(rc, mysql);
|
||||
|
||||
count= mysql_warning_count(mysql);
|
||||
FAIL_UNLESS(count == 2, "warnings != 2");
|
||||
|
||||
rc= mysql_query(mysql, "SHOW WARNINGS");
|
||||
check_mysql_rc(rc, mysql);
|
||||
|
||||
result= mysql_store_result(mysql);
|
||||
FAIL_IF(!result, "Invalid result set");
|
||||
|
||||
rc= 0;
|
||||
while (mysql_fetch_row(result))
|
||||
rc++;
|
||||
FAIL_UNLESS(rc == 2, "rowcount != 2");
|
||||
mysql_free_result(result);
|
||||
return OK;
|
||||
}
|
||||
|
||||
static int test_parse_error_and_bad_length(MYSQL *mysql)
|
||||
{
|
||||
MYSQL_STMT *stmt;
|
||||
int rc;
|
||||
|
||||
/* check that we get 4 syntax errors over the 4 calls */
|
||||
|
||||
rc= mysql_query(mysql, "SHOW DATABAAAA");
|
||||
FAIL_UNLESS(rc, "Error expected");
|
||||
rc= mysql_real_query(mysql, "SHOW DATABASES", 100);
|
||||
FAIL_UNLESS(rc, "Error expected");
|
||||
|
||||
stmt= mysql_stmt_init(mysql);
|
||||
FAIL_IF(!stmt, mysql_error(mysql));
|
||||
rc= mysql_stmt_prepare(stmt, "SHOW DATABAAAA", strlen("SHOW DATABAAAA"));
|
||||
FAIL_IF(!rc, "Error expected");
|
||||
mysql_stmt_close(stmt);
|
||||
stmt= mysql_stmt_init(mysql);
|
||||
FAIL_UNLESS(stmt, "");
|
||||
rc= mysql_stmt_prepare(stmt, "SHOW DATABASES", 100);
|
||||
FAIL_IF(!rc, "Error expected");
|
||||
mysql_stmt_close(stmt);
|
||||
return OK;
|
||||
}
|
||||
|
||||
|
||||
struct my_tests_st my_tests[] = {
|
||||
{"test_client_warnings", test_client_warnings, TEST_CONNECTION_DEFAULT, 0, NULL , NULL},
|
||||
{"test_ps_client_warnings", test_ps_client_warnings, TEST_CONNECTION_DEFAULT, 0, NULL , NULL},
|
||||
{"test_server_warnings", test_server_warnings, TEST_CONNECTION_DEFAULT, 0, NULL , NULL},
|
||||
{"test_client_errors", test_client_errors, TEST_CONNECTION_DEFAULT, 0, NULL , NULL},
|
||||
{"test_ps_client_errors", test_ps_client_errors, TEST_CONNECTION_DEFAULT, 0, NULL , NULL},
|
||||
{"test_server_errors", test_server_errors, TEST_CONNECTION_DEFAULT, 0, NULL , "Open bug: #42364"},
|
||||
{"test_bug16143", test_bug16143, TEST_CONNECTION_DEFAULT, 0, NULL , NULL},
|
||||
{"test_cuted_rows", test_cuted_rows, TEST_CONNECTION_DEFAULT, 0, NULL , NULL},
|
||||
{"test_parse_error_and_bad_length", test_parse_error_and_bad_length, TEST_CONNECTION_DEFAULT, 0, NULL , NULL},
|
||||
{NULL, NULL, 0, 0, NULL, NULL}
|
||||
};
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
if (argc > 1)
|
||||
get_options(argc, argv);
|
||||
|
||||
get_envvars();
|
||||
|
||||
run_tests(my_tests);
|
||||
|
||||
return(exit_status());
|
||||
}
|
904
unittest/libmariadb/fetch.c
Normal file
904
unittest/libmariadb/fetch.c
Normal file
@@ -0,0 +1,904 @@
|
||||
/*
|
||||
Copyright (c) 2009, 2010, Oracle and/or its affiliates. All rights reserved.
|
||||
|
||||
The MySQL Connector/C is licensed under the terms of the GPLv2
|
||||
<http://www.gnu.org/licenses/old-licenses/gpl-2.0.html>, like most
|
||||
MySQL Connectors. There are special exceptions to the terms and
|
||||
conditions of the GPLv2 as it is applied to this software, see the
|
||||
FLOSS License Exception
|
||||
<http://www.mysql.com/about/legal/licensing/foss-exception.html>.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published
|
||||
by the Free Software Foundation; version 2 of the License.
|
||||
|
||||
This program is distributed in the hope that it will be useful, but
|
||||
WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License along
|
||||
with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
#include "my_test.h"
|
||||
|
||||
/* Generalized fetch conversion routine for all basic types */
|
||||
|
||||
static int bind_fetch(MYSQL *mysql, int row_count)
|
||||
{
|
||||
MYSQL_STMT *stmt;
|
||||
int rc, i, count= row_count;
|
||||
int32 data[10];
|
||||
int8 i8_data;
|
||||
int16 i16_data;
|
||||
long i32_data;
|
||||
longlong i64_data;
|
||||
float f_data;
|
||||
double d_data;
|
||||
char s_data[10];
|
||||
ulong length[10];
|
||||
MYSQL_BIND my_bind[7];
|
||||
my_bool is_null[7];
|
||||
char query[MAX_TEST_QUERY_LENGTH];
|
||||
|
||||
stmt= mysql_stmt_init(mysql);
|
||||
FAIL_IF(!stmt, mysql_error(mysql));
|
||||
|
||||
strcpy(query, "INSERT INTO test_bind_fetch VALUES (?, ?, ?, ?, ?, ?, ?)");
|
||||
rc= mysql_stmt_prepare(stmt, query, strlen(query));
|
||||
check_stmt_rc(rc,stmt);
|
||||
|
||||
FAIL_UNLESS(mysql_stmt_param_count(stmt) == 7, "ParamCount != 7");
|
||||
|
||||
memset(my_bind, '\0', sizeof(my_bind));
|
||||
|
||||
for (i= 0; i < (int) array_elements(my_bind); i++)
|
||||
{
|
||||
my_bind[i].buffer_type= MYSQL_TYPE_LONG;
|
||||
my_bind[i].buffer= (void *) &data[i];
|
||||
}
|
||||
rc= mysql_stmt_bind_param(stmt, my_bind);
|
||||
check_stmt_rc(rc,stmt);
|
||||
|
||||
while (count--)
|
||||
{
|
||||
rc= 10+count;
|
||||
for (i= 0; i < (int) array_elements(my_bind); i++)
|
||||
{
|
||||
data[i]= rc+i;
|
||||
rc+= 12;
|
||||
}
|
||||
rc= mysql_stmt_execute(stmt);
|
||||
check_stmt_rc(rc,stmt);
|
||||
}
|
||||
|
||||
rc= mysql_commit(mysql);
|
||||
check_stmt_rc(rc,stmt);
|
||||
|
||||
mysql_stmt_close(stmt);
|
||||
|
||||
rc= my_stmt_result(mysql, "SELECT * FROM test_bind_fetch");
|
||||
FAIL_UNLESS(row_count == rc, "Wrong number of rows");
|
||||
|
||||
stmt= mysql_stmt_init(mysql);
|
||||
FAIL_IF(!stmt, mysql_error(mysql));
|
||||
|
||||
strcpy(query, "SELECT * FROM test_bind_fetch");
|
||||
rc= mysql_stmt_prepare(stmt, query, strlen(query));
|
||||
check_stmt_rc(rc,stmt);
|
||||
|
||||
for (i= 0; i < (int) array_elements(my_bind); i++)
|
||||
{
|
||||
my_bind[i].buffer= (void *) &data[i];
|
||||
my_bind[i].length= &length[i];
|
||||
my_bind[i].is_null= &is_null[i];
|
||||
}
|
||||
|
||||
my_bind[0].buffer_type= MYSQL_TYPE_TINY;
|
||||
my_bind[0].buffer= (void *)&i8_data;
|
||||
|
||||
my_bind[1].buffer_type= MYSQL_TYPE_SHORT;
|
||||
my_bind[1].buffer= (void *)&i16_data;
|
||||
|
||||
my_bind[2].buffer_type= MYSQL_TYPE_LONG;
|
||||
my_bind[2].buffer= (void *)&i32_data;
|
||||
|
||||
my_bind[3].buffer_type= MYSQL_TYPE_LONGLONG;
|
||||
my_bind[3].buffer= (void *)&i64_data;
|
||||
|
||||
my_bind[4].buffer_type= MYSQL_TYPE_FLOAT;
|
||||
my_bind[4].buffer= (void *)&f_data;
|
||||
|
||||
my_bind[5].buffer_type= MYSQL_TYPE_DOUBLE;
|
||||
my_bind[5].buffer= (void *)&d_data;
|
||||
|
||||
my_bind[6].buffer_type= MYSQL_TYPE_STRING;
|
||||
my_bind[6].buffer= (void *)&s_data;
|
||||
my_bind[6].buffer_length= sizeof(s_data);
|
||||
|
||||
rc= mysql_stmt_bind_result(stmt, my_bind);
|
||||
check_stmt_rc(rc,stmt);
|
||||
|
||||
rc= mysql_stmt_execute(stmt);
|
||||
check_stmt_rc(rc,stmt);
|
||||
|
||||
rc= mysql_stmt_store_result(stmt);
|
||||
check_stmt_rc(rc,stmt);
|
||||
|
||||
while (row_count--)
|
||||
{
|
||||
rc= mysql_stmt_fetch(stmt);
|
||||
check_stmt_rc(rc,stmt);
|
||||
|
||||
rc= 10+row_count;
|
||||
|
||||
/* TINY */
|
||||
FAIL_UNLESS((int) i8_data == rc, "Invalid value for i8_data");
|
||||
FAIL_UNLESS(length[0] == 1, "Invalid length");
|
||||
rc+= 13;
|
||||
|
||||
/* SHORT */
|
||||
FAIL_UNLESS((int) i16_data == rc, "Invalid value for i16_data");
|
||||
FAIL_UNLESS(length[1] == 2, "Invalid length");
|
||||
rc+= 13;
|
||||
|
||||
/* LONG */
|
||||
FAIL_UNLESS((int) i32_data == rc, "Invalid value for i32_data");
|
||||
FAIL_UNLESS(length[2] == 4, "Invalid length");
|
||||
rc+= 13;
|
||||
|
||||
/* LONGLONG */
|
||||
FAIL_UNLESS((int) i64_data == rc, "Invalid value for i64_data");
|
||||
FAIL_UNLESS(length[3] == 8, "Invalid length");
|
||||
rc+= 13;
|
||||
|
||||
/* FLOAT */
|
||||
FAIL_UNLESS((int)f_data == rc, "Invalid value for f_data");
|
||||
FAIL_UNLESS(length[4] == 4, "Invalid length");
|
||||
rc+= 13;
|
||||
|
||||
/* DOUBLE */
|
||||
FAIL_UNLESS((int)d_data == rc, "Invalid value for d_data");
|
||||
FAIL_UNLESS(length[5] == 8, "Invalid length");
|
||||
rc+= 13;
|
||||
|
||||
/* CHAR */
|
||||
{
|
||||
char buff[20];
|
||||
long len= sprintf(buff, "%d", rc);
|
||||
FAIL_UNLESS(strcmp(s_data, buff) == 0, "Invalid value for s_data");
|
||||
FAIL_UNLESS(length[6] == (ulong) len, "Invalid length");
|
||||
}
|
||||
}
|
||||
rc= mysql_stmt_fetch(stmt);
|
||||
FAIL_UNLESS(rc == MYSQL_NO_DATA, "Expected MYSQL_NO_DATA");
|
||||
|
||||
mysql_stmt_close(stmt);
|
||||
return OK;
|
||||
}
|
||||
|
||||
|
||||
static int test_fetch_seek(MYSQL *mysql)
|
||||
{
|
||||
MYSQL_STMT *stmt;
|
||||
MYSQL_BIND my_bind[3];
|
||||
MYSQL_ROW_OFFSET row;
|
||||
int rc;
|
||||
int32 c1;
|
||||
char c2[11], c3[20];
|
||||
char *query = "SELECT * FROM t1";
|
||||
|
||||
rc= mysql_query(mysql, "drop table if exists t1");
|
||||
check_mysql_rc(rc, mysql);
|
||||
rc= mysql_query(mysql, "create table t1(c1 int primary key auto_increment, c2 char(10), c3 timestamp)");
|
||||
check_mysql_rc(rc, mysql);
|
||||
rc= mysql_query(mysql, "insert into t1(c2) values('venu'), ('mysql'), ('open'), ('source')");
|
||||
check_mysql_rc(rc, mysql);
|
||||
|
||||
stmt= mysql_stmt_init(mysql);
|
||||
FAIL_IF(!stmt, mysql_error(mysql));
|
||||
|
||||
rc= mysql_stmt_prepare(stmt, query, strlen(query));
|
||||
check_stmt_rc(rc,stmt);
|
||||
|
||||
memset(my_bind, '\0', sizeof(my_bind));
|
||||
my_bind[0].buffer_type= MYSQL_TYPE_LONG;
|
||||
my_bind[0].buffer= (void *)&c1;
|
||||
|
||||
my_bind[1].buffer_type= MYSQL_TYPE_STRING;
|
||||
my_bind[1].buffer= (void *)c2;
|
||||
my_bind[1].buffer_length= sizeof(c2);
|
||||
|
||||
my_bind[2]= my_bind[1];
|
||||
my_bind[2].buffer= (void *)c3;
|
||||
my_bind[2].buffer_length= sizeof(c3);
|
||||
|
||||
rc= mysql_stmt_execute(stmt);
|
||||
check_stmt_rc(rc,stmt);
|
||||
|
||||
rc= mysql_stmt_bind_result(stmt, my_bind);
|
||||
check_stmt_rc(rc,stmt);
|
||||
|
||||
rc= mysql_stmt_store_result(stmt);
|
||||
check_stmt_rc(rc,stmt);
|
||||
|
||||
|
||||
rc= mysql_stmt_fetch(stmt);
|
||||
check_stmt_rc(rc,stmt);
|
||||
|
||||
row= mysql_stmt_row_tell(stmt);
|
||||
|
||||
row= mysql_stmt_row_seek(stmt, row);
|
||||
|
||||
rc= mysql_stmt_fetch(stmt);
|
||||
check_stmt_rc(rc,stmt);
|
||||
|
||||
row= mysql_stmt_row_seek(stmt, row);
|
||||
|
||||
rc= mysql_stmt_fetch(stmt);
|
||||
check_stmt_rc(rc,stmt);
|
||||
|
||||
mysql_stmt_data_seek(stmt, 0);
|
||||
|
||||
rc= mysql_stmt_fetch(stmt);
|
||||
check_stmt_rc(rc,stmt);
|
||||
|
||||
rc= mysql_stmt_fetch(stmt);
|
||||
check_stmt_rc(rc,stmt);
|
||||
|
||||
rc= mysql_stmt_fetch(stmt);
|
||||
check_stmt_rc(rc,stmt);
|
||||
|
||||
rc= mysql_stmt_fetch(stmt);
|
||||
check_stmt_rc(rc,stmt);
|
||||
|
||||
rc= mysql_stmt_fetch(stmt);
|
||||
FAIL_IF(rc != MYSQL_NO_DATA, "Expected MYSQL_NO_DATA");
|
||||
|
||||
mysql_stmt_close(stmt);
|
||||
rc= mysql_query(mysql, "drop table t1");
|
||||
check_mysql_rc(rc, mysql);
|
||||
|
||||
return OK;
|
||||
}
|
||||
|
||||
/* Test mysql_stmt_fetch_column() with offset */
|
||||
|
||||
static int test_fetch_offset(MYSQL *mysql)
|
||||
{
|
||||
MYSQL_STMT *stmt;
|
||||
MYSQL_BIND my_bind[1];
|
||||
char data[11];
|
||||
ulong length;
|
||||
int rc;
|
||||
my_bool is_null;
|
||||
char *query = "SELECT * FROM t1";
|
||||
|
||||
|
||||
rc= mysql_query(mysql, "drop table if exists t1");
|
||||
check_mysql_rc(rc, mysql);
|
||||
rc= mysql_query(mysql, "create table t1(a char(10))");
|
||||
check_mysql_rc(rc, mysql);
|
||||
rc= mysql_query(mysql, "insert into t1 values('abcdefghij'), (null)");
|
||||
check_mysql_rc(rc, mysql);
|
||||
|
||||
stmt= mysql_stmt_init(mysql);
|
||||
FAIL_IF(!stmt, mysql_error(mysql));
|
||||
|
||||
rc= mysql_stmt_prepare(stmt, query, strlen(query));
|
||||
check_stmt_rc(rc,stmt);
|
||||
|
||||
memset(my_bind, '\0', sizeof(my_bind));
|
||||
my_bind[0].buffer_type= MYSQL_TYPE_STRING;
|
||||
my_bind[0].buffer= (void *)data;
|
||||
my_bind[0].buffer_length= 11;
|
||||
my_bind[0].is_null= &is_null;
|
||||
my_bind[0].length= &length;
|
||||
|
||||
rc= mysql_stmt_execute(stmt);
|
||||
check_stmt_rc(rc,stmt);
|
||||
|
||||
rc= mysql_stmt_fetch_column(stmt, my_bind, 0, 0);
|
||||
FAIL_IF(!rc, "Error expected");
|
||||
|
||||
rc= mysql_stmt_execute(stmt);
|
||||
check_stmt_rc(rc,stmt);
|
||||
|
||||
rc= mysql_stmt_bind_result(stmt, my_bind);
|
||||
check_stmt_rc(rc,stmt);
|
||||
|
||||
rc= mysql_stmt_store_result(stmt);
|
||||
check_stmt_rc(rc,stmt);
|
||||
|
||||
rc= mysql_stmt_fetch(stmt);
|
||||
check_stmt_rc(rc,stmt);
|
||||
|
||||
data[0]= '\0';
|
||||
rc= mysql_stmt_fetch_column(stmt, my_bind, 0, 0);
|
||||
check_stmt_rc(rc,stmt);
|
||||
|
||||
|
||||
FAIL_IF(!(strncmp(data, "abcd", 4) == 0 && length == 10), "Wrong value");
|
||||
|
||||
rc= mysql_stmt_fetch_column(stmt, my_bind, 0, 5);
|
||||
check_stmt_rc(rc,stmt);
|
||||
FAIL_IF(!(strncmp(data, "fg", 2) == 0 && length == 10), "Wrong value");
|
||||
|
||||
rc= mysql_stmt_fetch_column(stmt, my_bind, 0, 9);
|
||||
check_stmt_rc(rc,stmt);
|
||||
FAIL_IF(!(strncmp(data, "j", 1) == 0 && length == 10), "Wrong value");
|
||||
|
||||
rc= mysql_stmt_fetch(stmt);
|
||||
check_stmt_rc(rc,stmt);
|
||||
|
||||
is_null= 0;
|
||||
|
||||
rc= mysql_stmt_fetch_column(stmt, my_bind, 0, 0);
|
||||
check_stmt_rc(rc,stmt);
|
||||
|
||||
FAIL_IF(is_null != 1, "Null flag not set");
|
||||
|
||||
rc= mysql_stmt_fetch(stmt);
|
||||
FAIL_IF(rc != MYSQL_NO_DATA, "Expected MYSQL_NO_DATA");
|
||||
|
||||
rc= mysql_stmt_fetch_column(stmt, my_bind, 1, 0);
|
||||
FAIL_IF(!rc, "Error expected");
|
||||
|
||||
mysql_stmt_close(stmt);
|
||||
|
||||
rc= mysql_query(mysql, "drop table t1");
|
||||
check_mysql_rc(rc, mysql);
|
||||
|
||||
return OK;
|
||||
}
|
||||
|
||||
/* Test mysql_stmt_fetch_column() */
|
||||
|
||||
static int test_fetch_column(MYSQL *mysql)
|
||||
{
|
||||
MYSQL_STMT *stmt;
|
||||
MYSQL_BIND my_bind[2];
|
||||
char c2[20], bc2[20];
|
||||
ulong l1, l2, bl1, bl2;
|
||||
int rc, c1, bc1;
|
||||
char *query= "SELECT * FROM t1 ORDER BY c2 DESC";
|
||||
|
||||
rc= mysql_query(mysql, "drop table if exists t1");
|
||||
check_mysql_rc(rc, mysql);
|
||||
rc= mysql_query(mysql, "create table t1(c1 int primary key auto_increment, c2 char(10))");
|
||||
check_mysql_rc(rc, mysql);
|
||||
rc= mysql_query(mysql, "insert into t1(c2) values('venu'), ('mysql')");
|
||||
check_mysql_rc(rc, mysql);
|
||||
|
||||
stmt= mysql_stmt_init(mysql);
|
||||
FAIL_IF(!stmt, mysql_error(mysql));
|
||||
|
||||
rc= mysql_stmt_prepare(stmt, query, strlen(query));
|
||||
check_stmt_rc(rc,stmt);
|
||||
|
||||
memset(my_bind, '\0', sizeof(my_bind));
|
||||
my_bind[0].buffer_type= MYSQL_TYPE_LONG;
|
||||
my_bind[0].buffer= (void *)&bc1;
|
||||
my_bind[0].buffer_length= 0;
|
||||
my_bind[0].is_null= 0;
|
||||
my_bind[0].length= &bl1;
|
||||
my_bind[1].buffer_type= MYSQL_TYPE_STRING;
|
||||
my_bind[1].buffer= (void *)bc2;
|
||||
my_bind[1].buffer_length= 7;
|
||||
my_bind[1].is_null= 0;
|
||||
my_bind[1].length= &bl2;
|
||||
|
||||
rc= mysql_stmt_execute(stmt);
|
||||
check_stmt_rc(rc,stmt);
|
||||
|
||||
rc= mysql_stmt_bind_result(stmt, my_bind);
|
||||
check_stmt_rc(rc,stmt);
|
||||
|
||||
rc= mysql_stmt_store_result(stmt);
|
||||
check_stmt_rc(rc,stmt);
|
||||
|
||||
rc= mysql_stmt_fetch_column(stmt, my_bind, 1, 0); /* No-op at this point */
|
||||
FAIL_IF(!rc, "Error expected");
|
||||
|
||||
rc= mysql_stmt_fetch(stmt);
|
||||
check_stmt_rc(rc,stmt);
|
||||
|
||||
c2[0]= '\0'; l2= 0;
|
||||
my_bind[0].buffer_type= MYSQL_TYPE_STRING;
|
||||
my_bind[0].buffer= (void *)c2;
|
||||
my_bind[0].buffer_length= 7;
|
||||
my_bind[0].is_null= 0;
|
||||
my_bind[0].length= &l2;
|
||||
|
||||
rc= mysql_stmt_fetch_column(stmt, my_bind, 1, 0);
|
||||
check_stmt_rc(rc,stmt);
|
||||
FAIL_IF(!(strncmp(c2, "venu", 4) == 0 && l2 == 4), "Expected c2='venu'");
|
||||
|
||||
c2[0]= '\0'; l2= 0;
|
||||
rc= mysql_stmt_fetch_column(stmt, my_bind, 1, 0);
|
||||
check_stmt_rc(rc,stmt);
|
||||
FAIL_IF(!(strcmp(c2, "venu") == 0 && l2 == 4), "Expected c2='venu'");
|
||||
|
||||
c1= 0;
|
||||
my_bind[0].buffer_type= MYSQL_TYPE_LONG;
|
||||
my_bind[0].buffer= (void *)&c1;
|
||||
my_bind[0].buffer_length= 0;
|
||||
my_bind[0].is_null= 0;
|
||||
my_bind[0].length= &l1;
|
||||
|
||||
rc= mysql_stmt_fetch_column(stmt, my_bind, 0, 0);
|
||||
check_stmt_rc(rc,stmt);
|
||||
FAIL_IF(!(c1 == 1 && l1 == 4), "Expected c1=1");
|
||||
|
||||
rc= mysql_stmt_fetch(stmt);
|
||||
check_stmt_rc(rc,stmt);
|
||||
|
||||
c2[0]= '\0'; l2= 0;
|
||||
my_bind[0].buffer_type= MYSQL_TYPE_STRING;
|
||||
my_bind[0].buffer= (void *)c2;
|
||||
my_bind[0].buffer_length= 7;
|
||||
my_bind[0].is_null= 0;
|
||||
my_bind[0].length= &l2;
|
||||
|
||||
rc= mysql_stmt_fetch_column(stmt, my_bind, 1, 0);
|
||||
check_stmt_rc(rc,stmt);
|
||||
FAIL_IF(!(strncmp(c2, "mysq", 4) == 0 && l2 == 5), "Expected c2='mysql'");
|
||||
|
||||
c2[0]= '\0'; l2= 0;
|
||||
rc= mysql_stmt_fetch_column(stmt, my_bind, 1, 0);
|
||||
check_stmt_rc(rc,stmt);
|
||||
FAIL_IF(!(strcmp(c2, "mysql") == 0 && l2 == 5), "Expected c2='mysql'");
|
||||
|
||||
c1= 0;
|
||||
my_bind[0].buffer_type= MYSQL_TYPE_LONG;
|
||||
my_bind[0].buffer= (void *)&c1;
|
||||
my_bind[0].buffer_length= 0;
|
||||
my_bind[0].is_null= 0;
|
||||
my_bind[0].length= &l1;
|
||||
|
||||
rc= mysql_stmt_fetch_column(stmt, my_bind, 0, 0);
|
||||
check_stmt_rc(rc,stmt);
|
||||
FAIL_IF(!(c1 == 2 && l1 == 4), "Expected c2=2");
|
||||
|
||||
rc= mysql_stmt_fetch(stmt);
|
||||
FAIL_IF(rc!=MYSQL_NO_DATA, "Expected MYSQL_NO_DATA");
|
||||
|
||||
rc= mysql_stmt_fetch_column(stmt, my_bind, 1, 0);
|
||||
FAIL_IF(!rc, "Error expected");
|
||||
|
||||
mysql_stmt_close(stmt);
|
||||
rc= mysql_query(mysql, "drop table t1");
|
||||
check_mysql_rc(rc, mysql);
|
||||
|
||||
return OK;
|
||||
}
|
||||
|
||||
/* Test fetch without prior bound buffers */
|
||||
|
||||
static int test_fetch_nobuffs(MYSQL *mysql)
|
||||
{
|
||||
MYSQL_STMT *stmt;
|
||||
MYSQL_BIND my_bind[4];
|
||||
char str[4][50];
|
||||
int rc;
|
||||
char *query = "SELECT DATABASE(), CURRENT_USER(), \
|
||||
CURRENT_DATE(), CURRENT_TIME()";
|
||||
|
||||
stmt = mysql_stmt_init(mysql);
|
||||
FAIL_IF(!stmt, mysql_error(mysql));
|
||||
rc= mysql_stmt_prepare(stmt, query, strlen(query));
|
||||
check_stmt_rc(rc, stmt);
|
||||
|
||||
rc= mysql_stmt_execute(stmt);
|
||||
check_stmt_rc(rc, stmt);
|
||||
|
||||
rc= 0;
|
||||
while (mysql_stmt_fetch(stmt) != MYSQL_NO_DATA)
|
||||
rc++;
|
||||
|
||||
FAIL_IF(rc != 1, "Expected 1 row");
|
||||
|
||||
memset(my_bind, '\0', sizeof(my_bind));
|
||||
my_bind[0].buffer_type= MYSQL_TYPE_STRING;
|
||||
my_bind[0].buffer= (void *)str[0];
|
||||
my_bind[0].buffer_length= sizeof(str[0]);
|
||||
my_bind[1]= my_bind[2]= my_bind[3]= my_bind[0];
|
||||
my_bind[1].buffer= (void *)str[1];
|
||||
my_bind[2].buffer= (void *)str[2];
|
||||
my_bind[3].buffer= (void *)str[3];
|
||||
|
||||
rc= mysql_stmt_bind_result(stmt, my_bind);
|
||||
check_stmt_rc(rc, stmt);
|
||||
|
||||
rc= mysql_stmt_execute(stmt);
|
||||
check_stmt_rc(rc, stmt);
|
||||
|
||||
rc= 0;
|
||||
while (mysql_stmt_fetch(stmt) != MYSQL_NO_DATA)
|
||||
{
|
||||
rc++;
|
||||
}
|
||||
FAIL_IF(rc != 1, "Expected 1 row");
|
||||
|
||||
mysql_stmt_close(stmt);
|
||||
|
||||
return OK;
|
||||
}
|
||||
|
||||
/* Test fetch null */
|
||||
|
||||
static int test_fetch_null(MYSQL *mysql)
|
||||
{
|
||||
MYSQL_STMT *stmt;
|
||||
int rc;
|
||||
int i;
|
||||
long nData;
|
||||
MYSQL_BIND my_bind[11];
|
||||
ulong length[11];
|
||||
my_bool is_null[11];
|
||||
char query[MAX_TEST_QUERY_LENGTH];
|
||||
|
||||
|
||||
rc= mysql_query(mysql, "DROP TABLE IF EXISTS test_fetch_null");
|
||||
check_mysql_rc(rc, mysql);
|
||||
|
||||
rc= mysql_query(mysql, "CREATE TABLE test_fetch_null("
|
||||
" col1 tinyint, col2 smallint, "
|
||||
" col3 int, col4 bigint, "
|
||||
" col5 float, col6 double, "
|
||||
" col7 date, col8 time, "
|
||||
" col9 varbinary(10), "
|
||||
" col10 varchar(50), "
|
||||
" col11 char(20))");
|
||||
check_mysql_rc(rc, mysql);
|
||||
|
||||
rc= mysql_query(mysql, "INSERT INTO test_fetch_null (col11) "
|
||||
"VALUES (1000), (88), (389789)");
|
||||
check_mysql_rc(rc, mysql);
|
||||
|
||||
rc= mysql_commit(mysql);
|
||||
FAIL_IF(rc, mysql_error(mysql));
|
||||
|
||||
/* fetch */
|
||||
memset(my_bind, '\0', sizeof(my_bind));
|
||||
for (i= 0; i < (int) array_elements(my_bind); i++)
|
||||
{
|
||||
my_bind[i].buffer_type= MYSQL_TYPE_LONG;
|
||||
my_bind[i].is_null= &is_null[i];
|
||||
my_bind[i].length= &length[i];
|
||||
}
|
||||
my_bind[i-1].buffer= (void *)&nData; /* Last column is not null */
|
||||
|
||||
strcpy((char *)query , "SELECT * FROM test_fetch_null");
|
||||
|
||||
rc= my_stmt_result(mysql, query);
|
||||
FAIL_UNLESS(rc == 3, "Exoected 3 rows");
|
||||
|
||||
stmt = mysql_stmt_init(mysql);
|
||||
FAIL_IF(!stmt, mysql_error(mysql));
|
||||
|
||||
rc= mysql_stmt_prepare(stmt, query, strlen(query));
|
||||
check_stmt_rc(rc, stmt);
|
||||
|
||||
rc= mysql_stmt_bind_result(stmt, my_bind);
|
||||
check_stmt_rc(rc, stmt);
|
||||
|
||||
rc= mysql_stmt_execute(stmt);
|
||||
check_stmt_rc(rc, stmt);
|
||||
|
||||
rc= 0;
|
||||
while (mysql_stmt_fetch(stmt) != MYSQL_NO_DATA)
|
||||
{
|
||||
rc++;
|
||||
for (i= 0; i < 10; i++)
|
||||
{
|
||||
FAIL_IF(!is_null[i], "Expected is_null");
|
||||
}
|
||||
FAIL_UNLESS(nData == 1000 || nData == 88 || nData == 389789, "Wrong value for nData");
|
||||
FAIL_UNLESS(is_null[i] == 0, "Exoected !is_null");
|
||||
FAIL_UNLESS(length[i] == 4, "Expected length=4");
|
||||
}
|
||||
FAIL_UNLESS(rc == 3, "Expected 3 rows");
|
||||
mysql_stmt_close(stmt);
|
||||
|
||||
return OK;
|
||||
}
|
||||
|
||||
/* Test fetching of date, time and ts */
|
||||
|
||||
static int test_fetch_date(MYSQL *mysql)
|
||||
{
|
||||
MYSQL_STMT *stmt;
|
||||
uint i;
|
||||
int rc;
|
||||
long year;
|
||||
char date[25], my_time[25], ts[25], ts_4[25], ts_6[20], dt[20];
|
||||
ulong d_length, t_length, ts_length, ts4_length, ts6_length,
|
||||
dt_length, y_length;
|
||||
MYSQL_BIND my_bind[8];
|
||||
my_bool is_null[8];
|
||||
ulong length[8];
|
||||
char *query= "SELECT * FROM test_bind_result";
|
||||
|
||||
rc= mysql_query(mysql, "DROP TABLE IF EXISTS test_bind_result");
|
||||
check_mysql_rc(rc, mysql);
|
||||
|
||||
rc= mysql_query(mysql, "CREATE TABLE test_bind_result(c1 date, c2 time, \
|
||||
c3 timestamp, \
|
||||
c4 year, \
|
||||
c5 datetime, \
|
||||
c6 timestamp, \
|
||||
c7 timestamp)");
|
||||
check_mysql_rc(rc, mysql);
|
||||
|
||||
rc= mysql_query(mysql, "SET SQL_MODE=''");
|
||||
check_mysql_rc(rc, mysql);
|
||||
rc= mysql_query(mysql, "INSERT INTO test_bind_result VALUES('2002-01-02', \
|
||||
'12:49:00', \
|
||||
'2002-01-02 17:46:59', \
|
||||
2010, \
|
||||
'2010-07-10', \
|
||||
'2020', '1999-12-29')");
|
||||
check_mysql_rc(rc, mysql);
|
||||
|
||||
rc= mysql_commit(mysql);
|
||||
FAIL_IF(rc, mysql_error(mysql));
|
||||
|
||||
memset(my_bind, '\0', sizeof(my_bind));
|
||||
for (i= 0; i < array_elements(my_bind); i++)
|
||||
{
|
||||
my_bind[i].is_null= &is_null[i];
|
||||
my_bind[i].length= &length[i];
|
||||
}
|
||||
|
||||
my_bind[0].buffer_type= MYSQL_TYPE_STRING;
|
||||
my_bind[1]= my_bind[2]= my_bind[0];
|
||||
|
||||
my_bind[0].buffer= (void *)&date;
|
||||
my_bind[0].buffer_length= sizeof(date);
|
||||
my_bind[0].length= &d_length;
|
||||
|
||||
my_bind[1].buffer= (void *)&my_time;
|
||||
my_bind[1].buffer_length= sizeof(my_time);
|
||||
my_bind[1].length= &t_length;
|
||||
|
||||
my_bind[2].buffer= (void *)&ts;
|
||||
my_bind[2].buffer_length= sizeof(ts);
|
||||
my_bind[2].length= &ts_length;
|
||||
|
||||
my_bind[3].buffer_type= MYSQL_TYPE_LONG;
|
||||
my_bind[3].buffer= (void *)&year;
|
||||
my_bind[3].length= &y_length;
|
||||
|
||||
my_bind[4].buffer_type= MYSQL_TYPE_STRING;
|
||||
my_bind[4].buffer= (void *)&dt;
|
||||
my_bind[4].buffer_length= sizeof(dt);
|
||||
my_bind[4].length= &dt_length;
|
||||
|
||||
my_bind[5].buffer_type= MYSQL_TYPE_STRING;
|
||||
my_bind[5].buffer= (void *)&ts_4;
|
||||
my_bind[5].buffer_length= sizeof(ts_4);
|
||||
my_bind[5].length= &ts4_length;
|
||||
|
||||
my_bind[6].buffer_type= MYSQL_TYPE_STRING;
|
||||
my_bind[6].buffer= (void *)&ts_6;
|
||||
my_bind[6].buffer_length= sizeof(ts_6);
|
||||
my_bind[6].length= &ts6_length;
|
||||
|
||||
rc= my_stmt_result(mysql, "SELECT * FROM test_bind_result");
|
||||
FAIL_UNLESS(rc == 1, "Expected 1 row");
|
||||
|
||||
stmt= mysql_stmt_init(mysql);
|
||||
FAIL_IF(!stmt, mysql_error(mysql));
|
||||
rc= mysql_stmt_prepare(stmt, query, strlen(query));
|
||||
check_stmt_rc(rc, stmt);
|
||||
|
||||
rc= mysql_stmt_bind_result(stmt, my_bind);
|
||||
check_stmt_rc(rc, stmt);
|
||||
|
||||
rc= mysql_stmt_execute(stmt);
|
||||
check_stmt_rc(rc, stmt);
|
||||
|
||||
ts_4[0]= '\0';
|
||||
rc= mysql_stmt_fetch(stmt);
|
||||
check_stmt_rc(rc, stmt);
|
||||
|
||||
FAIL_UNLESS(strcmp(date, "2002-01-02") == 0, "date != '2002-01-02'");
|
||||
FAIL_UNLESS(d_length == 10, "d_length != 10");
|
||||
|
||||
FAIL_UNLESS(strcmp(my_time, "12:49:00") == 0, "mytime != '12:49:00'");
|
||||
FAIL_UNLESS(t_length == 8, "t_length != 8");
|
||||
|
||||
FAIL_UNLESS(strcmp(ts, "2002-01-02 17:46:59") == 0, "ts != '2002-01-02 17:46:59'");
|
||||
FAIL_UNLESS(ts_length == 19, "ts_length != 19");
|
||||
|
||||
FAIL_UNLESS(year == 2010, "year != 2010");
|
||||
FAIL_UNLESS(y_length == 4, "y_length != 4");
|
||||
|
||||
FAIL_UNLESS(strcmp(dt, "2010-07-10 00:00:00") == 0, "dt != 2010-07-10 00:00:00");
|
||||
FAIL_UNLESS(dt_length == 19, "dt_length != 19");
|
||||
|
||||
FAIL_UNLESS(strcmp(ts_4, "0000-00-00 00:00:00") == 0, "ts4 != '0000-00-00 00:00:00'");
|
||||
FAIL_UNLESS(ts4_length == strlen("0000-00-00 00:00:00"), "ts4_length != 19");
|
||||
|
||||
FAIL_UNLESS(strcmp(ts_6, "1999-12-29 00:00:00") == 0, "ts_6 != '1999-12-29 00:00:00'");
|
||||
FAIL_UNLESS(ts6_length == 19, "ts6_length != 19");
|
||||
|
||||
rc= mysql_stmt_fetch(stmt);
|
||||
FAIL_UNLESS(rc == MYSQL_NO_DATA, "rc != MYSQL_NO_DATA");
|
||||
|
||||
mysql_stmt_close(stmt);
|
||||
|
||||
return OK;
|
||||
}
|
||||
|
||||
/* Test fetching of str to all types */
|
||||
|
||||
static int test_fetch_str(MYSQL *mysql)
|
||||
{
|
||||
int rc;
|
||||
|
||||
rc= mysql_query(mysql, "DROP TABLE IF EXISTS test_bind_fetch");
|
||||
check_mysql_rc(rc, mysql);
|
||||
|
||||
rc= mysql_query(mysql, "CREATE TABLE test_bind_fetch(c1 char(10), \
|
||||
c2 char(10), \
|
||||
c3 char(20), \
|
||||
c4 char(20), \
|
||||
c5 char(30), \
|
||||
c6 char(40), \
|
||||
c7 char(20))");
|
||||
check_mysql_rc(rc, mysql);
|
||||
|
||||
return bind_fetch(mysql, 3);
|
||||
}
|
||||
|
||||
/* Test fetching of long to all types */
|
||||
|
||||
static int test_fetch_long(MYSQL *mysql)
|
||||
{
|
||||
int rc;
|
||||
|
||||
rc= mysql_query(mysql, "DROP TABLE IF EXISTS test_bind_fetch");
|
||||
check_mysql_rc(rc, mysql);
|
||||
rc= mysql_query(mysql, "CREATE TABLE test_bind_fetch(c1 int unsigned, \
|
||||
c2 int unsigned, \
|
||||
c3 int, \
|
||||
c4 int, \
|
||||
c5 int, \
|
||||
c6 int unsigned, \
|
||||
c7 int)");
|
||||
check_mysql_rc(rc, mysql);
|
||||
return bind_fetch(mysql, 4);
|
||||
}
|
||||
|
||||
|
||||
/* Test fetching of short to all types */
|
||||
|
||||
static int test_fetch_short(MYSQL *mysql)
|
||||
{
|
||||
int rc;
|
||||
|
||||
rc= mysql_query(mysql, "DROP TABLE IF EXISTS test_bind_fetch");
|
||||
check_mysql_rc(rc, mysql);
|
||||
rc= mysql_query(mysql, "CREATE TABLE test_bind_fetch(c1 smallint unsigned, \
|
||||
c2 smallint, \
|
||||
c3 smallint unsigned, \
|
||||
c4 smallint, \
|
||||
c5 smallint, \
|
||||
c6 smallint, \
|
||||
c7 smallint unsigned)");
|
||||
check_mysql_rc(rc, mysql);
|
||||
return bind_fetch(mysql, 5);
|
||||
}
|
||||
|
||||
|
||||
/* Test fetching of tiny to all types */
|
||||
|
||||
static int test_fetch_tiny(MYSQL *mysql)
|
||||
{
|
||||
int rc;
|
||||
|
||||
rc= mysql_query(mysql, "DROP TABLE IF EXISTS test_bind_fetch");
|
||||
check_mysql_rc(rc, mysql);
|
||||
|
||||
rc= mysql_query(mysql, "CREATE TABLE test_bind_fetch(c1 tinyint unsigned, \
|
||||
c2 tinyint, \
|
||||
c3 tinyint unsigned, \
|
||||
c4 tinyint, \
|
||||
c5 tinyint, \
|
||||
c6 tinyint, \
|
||||
c7 tinyint unsigned)");
|
||||
check_mysql_rc(rc, mysql);
|
||||
return bind_fetch(mysql, 3);
|
||||
}
|
||||
|
||||
|
||||
/* Test fetching of longlong to all types */
|
||||
|
||||
static int test_fetch_bigint(MYSQL *mysql)
|
||||
{
|
||||
int rc;
|
||||
|
||||
rc= mysql_query(mysql, "DROP TABLE IF EXISTS test_bind_fetch");
|
||||
check_mysql_rc(rc, mysql);
|
||||
|
||||
rc= mysql_query(mysql, "CREATE TABLE test_bind_fetch(c1 bigint, \
|
||||
c2 bigint, \
|
||||
c3 bigint unsigned, \
|
||||
c4 bigint unsigned, \
|
||||
c5 bigint unsigned, \
|
||||
c6 bigint unsigned, \
|
||||
c7 bigint unsigned)");
|
||||
check_mysql_rc(rc, mysql);
|
||||
return bind_fetch(mysql, 2);
|
||||
}
|
||||
|
||||
|
||||
/* Test fetching of float to all types */
|
||||
|
||||
static int test_fetch_float(MYSQL *mysql)
|
||||
{
|
||||
int rc;
|
||||
|
||||
rc= mysql_query(mysql, "DROP TABLE IF EXISTS test_bind_fetch");
|
||||
check_mysql_rc(rc, mysql);
|
||||
|
||||
rc= mysql_query(mysql, "CREATE TABLE test_bind_fetch(c1 float(3), \
|
||||
c2 float, \
|
||||
c3 float unsigned, \
|
||||
c4 float, \
|
||||
c5 float, \
|
||||
c6 float, \
|
||||
c7 float(10) unsigned)");
|
||||
check_mysql_rc(rc, mysql);
|
||||
|
||||
return bind_fetch(mysql, 2);
|
||||
}
|
||||
|
||||
|
||||
/* Test fetching of double to all types */
|
||||
|
||||
static int test_fetch_double(MYSQL *mysql)
|
||||
{
|
||||
int rc;
|
||||
|
||||
rc= mysql_query(mysql, "DROP TABLE IF EXISTS test_bind_fetch");
|
||||
check_mysql_rc(rc, mysql);
|
||||
rc= mysql_query(mysql, "CREATE TABLE test_bind_fetch(c1 double(5, 2), "
|
||||
"c2 double unsigned, c3 double unsigned, "
|
||||
"c4 double unsigned, c5 double unsigned, "
|
||||
"c6 double unsigned, c7 double unsigned)");
|
||||
check_mysql_rc(rc, mysql);
|
||||
return bind_fetch(mysql, 3);
|
||||
}
|
||||
|
||||
struct my_tests_st my_tests[] = {
|
||||
{"test_fetch_seek", test_fetch_seek, 1, 0, NULL , NULL},
|
||||
{"test_fetch_offset", test_fetch_offset, 1, 0, NULL , NULL},
|
||||
{"test_fetch_column", test_fetch_column, 1, 0, NULL , NULL},
|
||||
{"test_fetch_nobuffs", test_fetch_nobuffs, 1, 0, NULL , NULL},
|
||||
{"test_fetch_null", test_fetch_null, 1, 0, NULL , NULL},
|
||||
{"test_fetch_date", test_fetch_date, 1, 0, NULL , NULL},
|
||||
{"test_fetch_str", test_fetch_str, 1, 0, NULL , NULL},
|
||||
{"test_fetch_long", test_fetch_long, 1, 0, NULL , NULL},
|
||||
{"test_fetch_short", test_fetch_short, 1, 0, NULL , NULL},
|
||||
{"test_fetch_tiny", test_fetch_tiny, 1, 0, NULL , NULL},
|
||||
{"test_fetch_bigint", test_fetch_bigint, 1, 0, NULL , NULL},
|
||||
{"test_fetch_float", test_fetch_float, 1, 0, NULL , NULL},
|
||||
{"test_fetch_double", test_fetch_double, 1, 0, NULL , NULL},
|
||||
{NULL, NULL, 0, 0, NULL, NULL}
|
||||
};
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
if (argc > 1)
|
||||
get_options(argc, argv);
|
||||
|
||||
get_envvars();
|
||||
|
||||
run_tests(my_tests);
|
||||
|
||||
return(exit_status());
|
||||
}
|
213
unittest/libmariadb/logs.c
Normal file
213
unittest/libmariadb/logs.c
Normal file
@@ -0,0 +1,213 @@
|
||||
/*
|
||||
Copyright (c) 2009, 2010, Oracle and/or its affiliates. All rights reserved.
|
||||
|
||||
The MySQL Connector/C is licensed under the terms of the GPLv2
|
||||
<http://www.gnu.org/licenses/old-licenses/gpl-2.0.html>, like most
|
||||
MySQL Connectors. There are special exceptions to the terms and
|
||||
conditions of the GPLv2 as it is applied to this software, see the
|
||||
FLOSS License Exception
|
||||
<http://www.mysql.com/about/legal/licensing/foss-exception.html>.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published
|
||||
by the Free Software Foundation; version 2 of the License.
|
||||
|
||||
This program is distributed in the hope that it will be useful, but
|
||||
WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License along
|
||||
with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
#include "my_test.h"
|
||||
|
||||
static int enable_general_log(MYSQL *mysql, int truncate)
|
||||
{
|
||||
int rc;
|
||||
|
||||
rc= mysql_query(mysql, "set @save_global_general_log=@@global.general_log");
|
||||
check_mysql_rc(rc, mysql);
|
||||
|
||||
rc= mysql_query(mysql, "set @@global.general_log=on");
|
||||
check_mysql_rc(rc, mysql);
|
||||
|
||||
if (truncate)
|
||||
{
|
||||
rc= mysql_query(mysql, "truncate mysql.general_log");
|
||||
check_mysql_rc(rc, mysql);
|
||||
}
|
||||
|
||||
return OK;
|
||||
}
|
||||
|
||||
|
||||
static int restore_general_log(MYSQL *mysql)
|
||||
{
|
||||
int rc;
|
||||
rc= mysql_query(mysql, "set @@global.general_log=@save_global_general_log");
|
||||
check_mysql_rc(rc, mysql);
|
||||
|
||||
return OK;
|
||||
}
|
||||
|
||||
|
||||
/* Test update/binary logs */
|
||||
|
||||
static int test_logs(MYSQL *mysql)
|
||||
{
|
||||
MYSQL_STMT *stmt;
|
||||
MYSQL_BIND my_bind[2];
|
||||
char data[255];
|
||||
ulong length;
|
||||
int rc;
|
||||
short id;
|
||||
|
||||
rc= mysql_query(mysql, "DROP TABLE IF EXISTS test_logs");
|
||||
check_mysql_rc(rc, mysql);
|
||||
|
||||
rc= mysql_query(mysql, "CREATE TABLE test_logs(id smallint, name varchar(20))");
|
||||
check_mysql_rc(rc, mysql);
|
||||
|
||||
strcpy((char *)data, "INSERT INTO test_logs VALUES(?, ?)");
|
||||
stmt= mysql_stmt_init(mysql);
|
||||
FAIL_IF(!stmt, mysql_error(mysql));
|
||||
|
||||
rc= mysql_stmt_prepare(stmt, data, strlen(data));
|
||||
check_stmt_rc(rc, stmt);
|
||||
|
||||
memset(my_bind, '\0', sizeof(my_bind));
|
||||
|
||||
my_bind[0].buffer_type= MYSQL_TYPE_SHORT;
|
||||
my_bind[0].buffer= (void *)&id;
|
||||
|
||||
my_bind[1].buffer_type= MYSQL_TYPE_STRING;
|
||||
my_bind[1].buffer= (void *)&data;
|
||||
my_bind[1].buffer_length= 255;
|
||||
my_bind[1].length= &length;
|
||||
|
||||
id= 9876;
|
||||
strcpy((char *)data, "MySQL - Open Source Database");
|
||||
length= strlen(data);
|
||||
|
||||
rc= mysql_stmt_bind_param(stmt, my_bind);
|
||||
check_stmt_rc(rc, stmt);
|
||||
|
||||
rc= mysql_stmt_execute(stmt);
|
||||
check_stmt_rc(rc, stmt);
|
||||
|
||||
strcpy((char *)data, "'");
|
||||
length= 1;
|
||||
|
||||
rc= mysql_stmt_execute(stmt);
|
||||
check_stmt_rc(rc, stmt);
|
||||
|
||||
strcpy((char *)data, "\"");
|
||||
length= 1;
|
||||
|
||||
rc= mysql_stmt_execute(stmt);
|
||||
check_stmt_rc(rc, stmt);
|
||||
|
||||
strcpy((char *)data, "my\'sql\'");
|
||||
length= strlen(data);
|
||||
rc= mysql_stmt_execute(stmt);
|
||||
check_stmt_rc(rc, stmt);
|
||||
|
||||
strcpy((char *)data, "my\"sql\"");
|
||||
length= strlen(data);
|
||||
rc= mysql_stmt_execute(stmt);
|
||||
check_stmt_rc(rc, stmt);
|
||||
|
||||
mysql_stmt_close(stmt);
|
||||
|
||||
strcpy((char *)data, "INSERT INTO test_logs VALUES(20, 'mysql')");
|
||||
stmt= mysql_stmt_init(mysql);
|
||||
FAIL_IF(!stmt, mysql_error(mysql));
|
||||
|
||||
rc= mysql_stmt_prepare(stmt, data, strlen(data));
|
||||
check_stmt_rc(rc, stmt);
|
||||
|
||||
rc= mysql_stmt_execute(stmt);
|
||||
check_stmt_rc(rc, stmt);
|
||||
|
||||
rc= mysql_stmt_execute(stmt);
|
||||
check_stmt_rc(rc, stmt);
|
||||
|
||||
mysql_stmt_close(stmt);
|
||||
|
||||
strcpy((char *)data, "SELECT * FROM test_logs WHERE id=?");
|
||||
stmt= mysql_stmt_init(mysql);
|
||||
FAIL_IF(!stmt, mysql_error(mysql));
|
||||
|
||||
rc= mysql_stmt_prepare(stmt, data, strlen(data));
|
||||
check_stmt_rc(rc, stmt);
|
||||
|
||||
rc= mysql_stmt_bind_param(stmt, my_bind);
|
||||
check_stmt_rc(rc, stmt);
|
||||
|
||||
rc= mysql_stmt_execute(stmt);
|
||||
check_stmt_rc(rc, stmt);
|
||||
|
||||
my_bind[1].buffer_length= 255;
|
||||
rc= mysql_stmt_bind_result(stmt, my_bind);
|
||||
check_stmt_rc(rc, stmt);
|
||||
|
||||
rc= mysql_stmt_fetch(stmt);
|
||||
check_stmt_rc(rc, stmt);
|
||||
|
||||
FAIL_UNLESS(id == 9876, "id != 9876");
|
||||
FAIL_UNLESS(length == 19 || length == 20, "Invalid Length"); /* Due to VARCHAR(20) */
|
||||
FAIL_UNLESS(strncmp(data, "MySQL - Open Source", 19) == 0, "data != 'MySQL - Open Source'");
|
||||
|
||||
rc= mysql_stmt_fetch(stmt);
|
||||
check_stmt_rc(rc, stmt);
|
||||
|
||||
FAIL_UNLESS(length == 1, "length != 1");
|
||||
FAIL_UNLESS(strcmp(data, "'") == 0, "data != '''");
|
||||
|
||||
rc= mysql_stmt_fetch(stmt);
|
||||
check_stmt_rc(rc, stmt);
|
||||
|
||||
FAIL_UNLESS(length == 1, "length != 1");
|
||||
FAIL_UNLESS(strcmp(data, "\"") == 0, "data != '\"'");
|
||||
|
||||
rc= mysql_stmt_fetch(stmt);
|
||||
check_stmt_rc(rc, stmt);
|
||||
|
||||
FAIL_UNLESS(length == 7, "length != 7");
|
||||
FAIL_UNLESS(strcmp(data, "my\'sql\'") == 0, "data != my'sql'");
|
||||
|
||||
rc= mysql_stmt_fetch(stmt);
|
||||
check_stmt_rc(rc, stmt);
|
||||
|
||||
FAIL_UNLESS(length == 7, "length != 7");
|
||||
|
||||
rc= mysql_stmt_fetch(stmt);
|
||||
FAIL_UNLESS(rc == MYSQL_NO_DATA, "rc != MYSQL_NO_DATA");
|
||||
|
||||
mysql_stmt_close(stmt);
|
||||
|
||||
rc= mysql_query(mysql, "DROP TABLE test_logs");
|
||||
check_mysql_rc(rc, mysql);
|
||||
|
||||
return OK;
|
||||
}
|
||||
|
||||
|
||||
struct my_tests_st my_tests[] = {
|
||||
{"test_logs", test_logs, TEST_CONNECTION_DEFAULT, 0, NULL , NULL},
|
||||
{NULL, NULL, 0, 0, NULL, NULL}
|
||||
};
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
if (argc > 1)
|
||||
get_options(argc, argv);
|
||||
|
||||
get_envvars();
|
||||
|
||||
run_tests(my_tests);
|
||||
|
||||
return(exit_status());
|
||||
}
|
839
unittest/libmariadb/misc.c
Normal file
839
unittest/libmariadb/misc.c
Normal file
@@ -0,0 +1,839 @@
|
||||
/*
|
||||
Copyright (c) 2009, 2010, Oracle and/or its affiliates. All rights reserved.
|
||||
|
||||
The MySQL Connector/C is licensed under the terms of the GPLv2
|
||||
<http://www.gnu.org/licenses/old-licenses/gpl-2.0.html>, like most
|
||||
MySQL Connectors. There are special exceptions to the terms and
|
||||
conditions of the GPLv2 as it is applied to this software, see the
|
||||
FLOSS License Exception
|
||||
<http://www.mysql.com/about/legal/licensing/foss-exception.html>.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published
|
||||
by the Free Software Foundation; version 2 of the License.
|
||||
|
||||
This program is distributed in the hope that it will be useful, but
|
||||
WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License along
|
||||
with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
#include "my_test.h"
|
||||
|
||||
/*
|
||||
Bug#28075 "COM_DEBUG crashes mysqld"
|
||||
*/
|
||||
|
||||
static int test_bug28075(MYSQL *mysql)
|
||||
{
|
||||
int rc;
|
||||
|
||||
rc= mysql_dump_debug_info(mysql);
|
||||
check_mysql_rc(rc, mysql);
|
||||
|
||||
rc= mysql_ping(mysql);
|
||||
check_mysql_rc(rc, mysql);
|
||||
|
||||
return OK;
|
||||
}
|
||||
|
||||
/*
|
||||
Bug#28505: mysql_affected_rows() returns wrong value if CLIENT_FOUND_ROWS
|
||||
flag is set.
|
||||
*/
|
||||
|
||||
static int test_bug28505(MYSQL *mysql)
|
||||
{
|
||||
my_ulonglong res;
|
||||
int rc;
|
||||
|
||||
rc= mysql_query(mysql, "drop table if exists t1");
|
||||
rc= mysql_query(mysql, "create table t1(f1 int primary key)");
|
||||
rc= mysql_query(mysql, "insert into t1 values(1)");
|
||||
rc= mysql_query(mysql, "insert into t1 values(1) on duplicate key update f1=1");
|
||||
res= mysql_affected_rows(mysql);
|
||||
FAIL_UNLESS(!res, "res != 0");
|
||||
rc= mysql_query(mysql, "drop table t1");
|
||||
return OK;
|
||||
}
|
||||
|
||||
/*
|
||||
Bug #29692 Single row inserts can incorrectly report a huge number of
|
||||
row insertions
|
||||
*/
|
||||
|
||||
static int test_bug29692(MYSQL *mysql)
|
||||
{
|
||||
int rc;
|
||||
rc= mysql_query(mysql, "drop table if exists t1");
|
||||
check_mysql_rc(rc, mysql);
|
||||
rc= mysql_query(mysql, "create table t1(f1 int)");
|
||||
check_mysql_rc(rc, mysql);
|
||||
rc= mysql_query(mysql, "insert into t1 values(1)");
|
||||
check_mysql_rc(rc, mysql);
|
||||
FAIL_UNLESS(1 == mysql_affected_rows(mysql), "affected_rows != 1");
|
||||
rc= mysql_query(mysql, "drop table t1");
|
||||
check_mysql_rc(rc, mysql);
|
||||
return OK;
|
||||
}
|
||||
|
||||
static int bug31418_impl()
|
||||
{
|
||||
my_bool is_null;
|
||||
MYSQL *mysql;
|
||||
int rc;
|
||||
|
||||
/* Create a new connection. */
|
||||
|
||||
mysql= test_connect(NULL);
|
||||
if (!mysql)
|
||||
return FAIL;
|
||||
|
||||
/***********************************************************************
|
||||
Check that lock is free:
|
||||
- IS_FREE_LOCK() should return 1;
|
||||
- IS_USED_LOCK() should return NULL;
|
||||
***********************************************************************/
|
||||
|
||||
is_null= query_int_variable(mysql,
|
||||
"IS_FREE_LOCK('bug31418')",
|
||||
&rc);
|
||||
FAIL_UNLESS(!is_null && rc, "rc = 0");
|
||||
|
||||
is_null= query_int_variable(mysql,
|
||||
"IS_USED_LOCK('bug31418')",
|
||||
&rc);
|
||||
FAIL_UNLESS(is_null, "rc = 0");
|
||||
|
||||
/***********************************************************************
|
||||
Acquire lock and check the lock status (the lock must be in use):
|
||||
- IS_FREE_LOCK() should return 0;
|
||||
- IS_USED_LOCK() should return non-zero thread id;
|
||||
***********************************************************************/
|
||||
|
||||
query_int_variable(mysql, "GET_LOCK('bug31418', 1)", &rc);
|
||||
FAIL_UNLESS(rc, "rc = 0");
|
||||
|
||||
is_null= query_int_variable(mysql,
|
||||
"IS_FREE_LOCK('bug31418')",
|
||||
&rc);
|
||||
FAIL_UNLESS(!is_null && !rc, "rc = 0");
|
||||
|
||||
is_null= query_int_variable(mysql,
|
||||
"IS_USED_LOCK('bug31418')",
|
||||
&rc);
|
||||
FAIL_UNLESS(!is_null && rc, "rc = 0");
|
||||
|
||||
/***********************************************************************
|
||||
Issue COM_CHANGE_USER command and check the lock status
|
||||
(the lock must be free):
|
||||
- IS_FREE_LOCK() should return 1;
|
||||
- IS_USED_LOCK() should return NULL;
|
||||
**********************************************************************/
|
||||
|
||||
rc= mysql_change_user(mysql, username, password, schema ? schema : "test");
|
||||
check_mysql_rc(rc, mysql);
|
||||
|
||||
is_null= query_int_variable(mysql,
|
||||
"IS_FREE_LOCK('bug31418')",
|
||||
&rc);
|
||||
FAIL_UNLESS(!is_null && rc, "rc = 0");
|
||||
|
||||
is_null= query_int_variable(mysql,
|
||||
"IS_USED_LOCK('bug31418')",
|
||||
&rc);
|
||||
FAIL_UNLESS(is_null, "rc = 0");
|
||||
|
||||
/***********************************************************************
|
||||
That's it. Cleanup.
|
||||
***********************************************************************/
|
||||
|
||||
mysql_close(mysql);
|
||||
return OK;
|
||||
}
|
||||
|
||||
static int test_bug31418(MYSQL *mysql)
|
||||
{
|
||||
int i;
|
||||
/* Run test case for BUG#31418 for three different connections. */
|
||||
|
||||
for (i=0; i < 3; i++)
|
||||
if (bug31418_impl())
|
||||
return FAIL;
|
||||
|
||||
return OK;
|
||||
}
|
||||
|
||||
/*
|
||||
Altough mysql_create_db(), mysql_rm_db() are deprecated since 4.0 they
|
||||
should not crash server and should not hang in case of errors.
|
||||
|
||||
Since those functions can't be seen in modern API (unless client library
|
||||
was compiled with USE_OLD_FUNCTIONS define) we use simple_command() macro.
|
||||
*/
|
||||
static int test_bug6081(MYSQL *mysql)
|
||||
{
|
||||
int rc;
|
||||
|
||||
if (mysql_get_server_version(mysql) < 50100) {
|
||||
diag("Test requires MySQL Server version 5.1 or above");
|
||||
return SKIP;
|
||||
}
|
||||
|
||||
rc= simple_command(mysql, MYSQL_COM_DROP_DB, (char*) schema,
|
||||
(ulong)strlen(schema), 0U);
|
||||
FAIL_IF(!rc, "Error expected");
|
||||
|
||||
rc= simple_command(mysql, MYSQL_COM_CREATE_DB, (char*) schema,
|
||||
(ulong)strlen(schema), 0U);
|
||||
FAIL_IF(!rc, "Error expected");
|
||||
|
||||
rc= mysql_select_db(mysql, schema);
|
||||
check_mysql_rc(rc, mysql);
|
||||
return OK;
|
||||
}
|
||||
|
||||
/* Query processing */
|
||||
|
||||
static int test_debug_example(MYSQL *mysql)
|
||||
{
|
||||
int rc;
|
||||
MYSQL_RES *result;
|
||||
|
||||
|
||||
rc= mysql_query(mysql, "DROP TABLE IF EXISTS test_debug_example");
|
||||
check_mysql_rc(rc, mysql);
|
||||
|
||||
rc= mysql_query(mysql, "CREATE TABLE test_debug_example("
|
||||
"id INT PRIMARY KEY AUTO_INCREMENT, "
|
||||
"name VARCHAR(20), xxx INT)");
|
||||
check_mysql_rc(rc, mysql);
|
||||
|
||||
rc= mysql_query(mysql, "INSERT INTO test_debug_example (name) "
|
||||
"VALUES ('mysql')");
|
||||
check_mysql_rc(rc, mysql);
|
||||
|
||||
rc= mysql_query(mysql, "UPDATE test_debug_example SET name='updated' "
|
||||
"WHERE name='deleted'");
|
||||
check_mysql_rc(rc, mysql);
|
||||
|
||||
rc= mysql_query(mysql, "SELECT * FROM test_debug_example where name='mysql'");
|
||||
check_mysql_rc(rc, mysql);
|
||||
|
||||
result= mysql_use_result(mysql);
|
||||
FAIL_IF(!result, "Invalid result set");
|
||||
|
||||
while (mysql_fetch_row(result));
|
||||
mysql_free_result(result);
|
||||
|
||||
rc= mysql_query(mysql, "DROP TABLE test_debug_example");
|
||||
check_mysql_rc(rc, mysql);
|
||||
return OK;
|
||||
}
|
||||
|
||||
/*
|
||||
Test a crash when invalid/corrupted .frm is used in the
|
||||
SHOW TABLE STATUS
|
||||
bug #93 (reported by serg@mysql.com).
|
||||
*/
|
||||
|
||||
static int test_frm_bug(MYSQL *mysql)
|
||||
{
|
||||
MYSQL_STMT *stmt;
|
||||
MYSQL_BIND my_bind[2];
|
||||
MYSQL_RES *result;
|
||||
MYSQL_ROW row;
|
||||
FILE *test_file;
|
||||
char data_dir[FN_REFLEN];
|
||||
char test_frm[FN_REFLEN];
|
||||
int rc;
|
||||
|
||||
|
||||
mysql_autocommit(mysql, TRUE);
|
||||
|
||||
rc= mysql_query(mysql, "drop table if exists test_frm_bug");
|
||||
check_mysql_rc(rc, mysql);
|
||||
|
||||
rc= mysql_query(mysql, "flush tables");
|
||||
check_mysql_rc(rc, mysql);
|
||||
|
||||
stmt= mysql_stmt_init(mysql);
|
||||
FAIL_IF(!stmt, mysql_error(mysql));
|
||||
rc= mysql_stmt_prepare(stmt, "show variables like 'datadir'", strlen("show variables like 'datadir'"));
|
||||
check_stmt_rc(rc, stmt);
|
||||
|
||||
rc= mysql_stmt_execute(stmt);
|
||||
check_stmt_rc(rc, stmt);
|
||||
|
||||
memset(my_bind, '\0', sizeof(my_bind));
|
||||
my_bind[0].buffer_type= MYSQL_TYPE_STRING;
|
||||
my_bind[0].buffer= data_dir;
|
||||
my_bind[0].buffer_length= FN_REFLEN;
|
||||
my_bind[1]= my_bind[0];
|
||||
|
||||
rc= mysql_stmt_bind_result(stmt, my_bind);
|
||||
check_stmt_rc(rc, stmt);
|
||||
|
||||
rc= mysql_stmt_fetch(stmt);
|
||||
check_stmt_rc(rc, stmt);
|
||||
|
||||
rc= mysql_stmt_fetch(stmt);
|
||||
FAIL_UNLESS(rc == MYSQL_NO_DATA, "rc != MYSQL_NO_DATA");
|
||||
|
||||
sprintf(test_frm, "%s/%s/test_frm_bug.frm", data_dir, schema);
|
||||
|
||||
|
||||
if (!(test_file= my_fopen(test_frm, (int) (O_RDWR | O_CREAT), MYF(MY_WME))))
|
||||
{
|
||||
mysql_stmt_close(stmt);
|
||||
diag("Can't write to file %s -> SKIP", test_frm);
|
||||
return SKIP;
|
||||
}
|
||||
|
||||
rc= mysql_query(mysql, "SHOW TABLE STATUS like 'test_frm_bug'");
|
||||
check_mysql_rc(rc, mysql);
|
||||
|
||||
result= mysql_store_result(mysql);
|
||||
FAIL_IF(!result, "Invalid result set");/* It can't be NULL */
|
||||
|
||||
rc= 0;
|
||||
while (mysql_fetch_row(result))
|
||||
rc++;
|
||||
FAIL_UNLESS(rc == 1, "rowcount != 0");
|
||||
|
||||
mysql_data_seek(result, 0);
|
||||
|
||||
row= mysql_fetch_row(result);
|
||||
FAIL_IF(!row, "couldn't fetch row");
|
||||
|
||||
FAIL_UNLESS(row[17] != 0, "row[17] != 0");
|
||||
|
||||
mysql_free_result(result);
|
||||
mysql_stmt_close(stmt);
|
||||
|
||||
my_fclose(test_file, MYF(0));
|
||||
mysql_query(mysql, "drop table if exists test_frm_bug");
|
||||
return OK;
|
||||
}
|
||||
|
||||
static int test_wl4166_1(MYSQL *mysql)
|
||||
{
|
||||
MYSQL_STMT *stmt;
|
||||
int int_data;
|
||||
char str_data[50];
|
||||
char tiny_data;
|
||||
short small_data;
|
||||
longlong big_data;
|
||||
float real_data;
|
||||
double double_data;
|
||||
ulong length[7];
|
||||
my_bool is_null[7];
|
||||
MYSQL_BIND my_bind[7];
|
||||
static char *query;
|
||||
int rc;
|
||||
int i;
|
||||
|
||||
if (mysql_get_server_version(mysql) < 50100) {
|
||||
diag("Test requires MySQL Server version 5.1 or above");
|
||||
return SKIP;
|
||||
}
|
||||
rc= mysql_query(mysql, "DROP TABLE IF EXISTS table_4166");
|
||||
check_mysql_rc(rc, mysql);
|
||||
|
||||
rc= mysql_query(mysql, "CREATE TABLE table_4166(col1 tinyint NOT NULL, "
|
||||
"col2 varchar(15), col3 int, "
|
||||
"col4 smallint, col5 bigint, "
|
||||
"col6 float, col7 double, "
|
||||
"colX varchar(10) default NULL)");
|
||||
check_mysql_rc(rc, mysql);
|
||||
|
||||
stmt= mysql_stmt_init(mysql);
|
||||
FAIL_IF(!stmt, mysql_error(mysql));
|
||||
query= "INSERT INTO table_4166(col1, col2, col3, col4, col5, col6, col7) "
|
||||
"VALUES(?, ?, ?, ?, ?, ?, ?)";
|
||||
rc= mysql_stmt_prepare(stmt, query, strlen(query));
|
||||
check_stmt_rc(rc, stmt);
|
||||
|
||||
FAIL_IF(mysql_stmt_param_count(stmt) != 7, "param_count != 7");
|
||||
|
||||
memset(my_bind, '\0', sizeof(my_bind));
|
||||
/* tinyint */
|
||||
my_bind[0].buffer_type= MYSQL_TYPE_TINY;
|
||||
my_bind[0].buffer= (void *)&tiny_data;
|
||||
/* string */
|
||||
my_bind[1].buffer_type= MYSQL_TYPE_STRING;
|
||||
my_bind[1].buffer= (void *)str_data;
|
||||
my_bind[1].buffer_length= 1000; /* Max string length */
|
||||
/* integer */
|
||||
my_bind[2].buffer_type= MYSQL_TYPE_LONG;
|
||||
my_bind[2].buffer= (void *)&int_data;
|
||||
/* short */
|
||||
my_bind[3].buffer_type= MYSQL_TYPE_SHORT;
|
||||
my_bind[3].buffer= (void *)&small_data;
|
||||
/* bigint */
|
||||
my_bind[4].buffer_type= MYSQL_TYPE_LONGLONG;
|
||||
my_bind[4].buffer= (void *)&big_data;
|
||||
/* float */
|
||||
my_bind[5].buffer_type= MYSQL_TYPE_FLOAT;
|
||||
my_bind[5].buffer= (void *)&real_data;
|
||||
/* double */
|
||||
my_bind[6].buffer_type= MYSQL_TYPE_DOUBLE;
|
||||
my_bind[6].buffer= (void *)&double_data;
|
||||
|
||||
for (i= 0; i < (int) array_elements(my_bind); i++)
|
||||
{
|
||||
my_bind[i].length= &length[i];
|
||||
my_bind[i].is_null= &is_null[i];
|
||||
is_null[i]= 0;
|
||||
}
|
||||
|
||||
rc= mysql_stmt_bind_param(stmt, my_bind);
|
||||
check_stmt_rc(rc, stmt);
|
||||
|
||||
int_data= 320;
|
||||
small_data= 1867;
|
||||
big_data= 1000;
|
||||
real_data= 2;
|
||||
double_data= 6578.001;
|
||||
|
||||
/* now, execute the prepared statement to insert 10 records.. */
|
||||
for (tiny_data= 0; tiny_data < 10; tiny_data++)
|
||||
{
|
||||
length[1]= sprintf(str_data, "MySQL%d", int_data);
|
||||
rc= mysql_stmt_execute(stmt);
|
||||
check_stmt_rc(rc, stmt);
|
||||
int_data += 25;
|
||||
small_data += 10;
|
||||
big_data += 100;
|
||||
real_data += 1;
|
||||
double_data += 10.09;
|
||||
}
|
||||
|
||||
/* force a re-prepare with some DDL */
|
||||
|
||||
rc= mysql_query(mysql,
|
||||
"ALTER TABLE table_4166 change colX colX varchar(20) default NULL");
|
||||
check_mysql_rc(rc, mysql);
|
||||
|
||||
/*
|
||||
execute the prepared statement again,
|
||||
without changing the types of parameters already bound.
|
||||
*/
|
||||
|
||||
for (tiny_data= 50; tiny_data < 60; tiny_data++)
|
||||
{
|
||||
length[1]= sprintf(str_data, "MySQL%d", int_data);
|
||||
rc= mysql_stmt_execute(stmt);
|
||||
check_stmt_rc(rc, stmt);
|
||||
int_data += 25;
|
||||
small_data += 10;
|
||||
big_data += 100;
|
||||
real_data += 1;
|
||||
double_data += 10.09;
|
||||
}
|
||||
|
||||
mysql_stmt_close(stmt);
|
||||
|
||||
rc= mysql_query(mysql, "DROP TABLE table_4166");
|
||||
check_mysql_rc(rc, mysql);
|
||||
return OK;
|
||||
}
|
||||
|
||||
|
||||
static int test_wl4166_2(MYSQL *mysql)
|
||||
{
|
||||
MYSQL_STMT *stmt;
|
||||
int c_int;
|
||||
MYSQL_TIME d_date;
|
||||
MYSQL_BIND bind_out[2];
|
||||
int rc;
|
||||
|
||||
if (mysql_get_server_version(mysql) < 50100) {
|
||||
diag("Test requires MySQL Server version 5.1 or above");
|
||||
return SKIP;
|
||||
}
|
||||
|
||||
rc= mysql_query(mysql, "drop table if exists t1");
|
||||
check_mysql_rc(rc, mysql);
|
||||
rc= mysql_query(mysql, "create table t1 (c_int int, d_date date)");
|
||||
check_mysql_rc(rc, mysql);
|
||||
rc= mysql_query(mysql,
|
||||
"insert into t1 (c_int, d_date) values (42, '1948-05-15')");
|
||||
check_mysql_rc(rc, mysql);
|
||||
|
||||
stmt= mysql_stmt_init(mysql);
|
||||
FAIL_IF(!stmt, mysql_error(mysql));
|
||||
rc= mysql_stmt_prepare(stmt, "select * from t1", strlen("select * from t1"));
|
||||
check_stmt_rc(rc, stmt);
|
||||
|
||||
memset(bind_out, '\0', sizeof(bind_out));
|
||||
bind_out[0].buffer_type= MYSQL_TYPE_LONG;
|
||||
bind_out[0].buffer= (void*) &c_int;
|
||||
|
||||
bind_out[1].buffer_type= MYSQL_TYPE_DATE;
|
||||
bind_out[1].buffer= (void*) &d_date;
|
||||
|
||||
rc= mysql_stmt_bind_result(stmt, bind_out);
|
||||
check_stmt_rc(rc, stmt);
|
||||
|
||||
/* int -> varchar transition */
|
||||
|
||||
rc= mysql_query(mysql,
|
||||
"alter table t1 change column c_int c_int varchar(11)");
|
||||
check_mysql_rc(rc, mysql);
|
||||
|
||||
rc= mysql_stmt_execute(stmt);
|
||||
check_stmt_rc(rc, stmt);
|
||||
|
||||
rc= mysql_stmt_fetch(stmt);
|
||||
check_stmt_rc(rc, stmt);
|
||||
|
||||
FAIL_UNLESS(c_int == 42, "c_int != 42");
|
||||
FAIL_UNLESS(d_date.year == 1948, "y!=1948");
|
||||
FAIL_UNLESS(d_date.month == 5, "m != 5");
|
||||
FAIL_UNLESS(d_date.day == 15, "d != 15");
|
||||
|
||||
rc= mysql_stmt_fetch(stmt);
|
||||
FAIL_UNLESS(rc == MYSQL_NO_DATA, "rc != MYSQL_NO_DATA");
|
||||
|
||||
/* varchar to int retrieval with truncation */
|
||||
|
||||
rc= mysql_query(mysql, "update t1 set c_int='abcde'");
|
||||
check_mysql_rc(rc, mysql);
|
||||
|
||||
rc= mysql_stmt_execute(stmt);
|
||||
check_stmt_rc(rc, stmt);
|
||||
|
||||
rc= mysql_stmt_fetch(stmt);
|
||||
FAIL_IF(!rc, "Error expected");
|
||||
|
||||
FAIL_UNLESS(c_int == 0, "c != 0");
|
||||
|
||||
rc= mysql_stmt_fetch(stmt);
|
||||
FAIL_UNLESS(rc == MYSQL_NO_DATA, "rc != MYSQL_NO_DATA");
|
||||
|
||||
/* alter table and increase the number of columns */
|
||||
rc= mysql_query(mysql, "alter table t1 add column d_int int");
|
||||
check_mysql_rc(rc, mysql);
|
||||
|
||||
rc= mysql_stmt_execute(stmt);
|
||||
FAIL_IF(!rc, "Error expected");
|
||||
|
||||
rc= mysql_stmt_reset(stmt);
|
||||
check_stmt_rc(rc, stmt);
|
||||
|
||||
/* decrease the number of columns */
|
||||
rc= mysql_query(mysql, "alter table t1 drop d_date, drop d_int");
|
||||
check_mysql_rc(rc, mysql);
|
||||
rc= mysql_stmt_execute(stmt);
|
||||
diag("rc=%d error: %d\n", rc, mysql_stmt_errno(stmt));
|
||||
FAIL_IF(!rc, "Error expected");
|
||||
|
||||
mysql_stmt_close(stmt);
|
||||
rc= mysql_query(mysql, "drop table t1");
|
||||
check_mysql_rc(rc, mysql);
|
||||
|
||||
return OK;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
Test how warnings generated during assignment of parameters
|
||||
are (currently not) preserve in case of reprepare.
|
||||
*/
|
||||
|
||||
static int test_wl4166_3(MYSQL *mysql)
|
||||
{
|
||||
int rc;
|
||||
MYSQL_STMT *stmt;
|
||||
MYSQL_BIND my_bind[1];
|
||||
MYSQL_TIME tm[1];
|
||||
|
||||
if (mysql_get_server_version(mysql) < 50100) {
|
||||
diag("Test requires MySQL Server version 5.1 or above");
|
||||
return SKIP;
|
||||
}
|
||||
|
||||
rc= mysql_query(mysql, "drop table if exists t1");
|
||||
check_mysql_rc(rc, mysql);
|
||||
|
||||
rc= mysql_query(mysql, "create table t1 (year datetime)");
|
||||
check_mysql_rc(rc, mysql);
|
||||
|
||||
stmt= mysql_stmt_init(mysql);
|
||||
FAIL_IF(!stmt, mysql_error(mysql));
|
||||
rc= mysql_stmt_prepare(stmt, "insert into t1 (year) values (?)", strlen("insert into t1 (year) values (?)"));
|
||||
check_stmt_rc(rc, stmt);
|
||||
|
||||
FAIL_IF(mysql_stmt_param_count(stmt) != 1, "param_count != 1");
|
||||
|
||||
memset(my_bind, '\0', sizeof(my_bind));
|
||||
my_bind[0].buffer_type= MYSQL_TYPE_DATETIME;
|
||||
my_bind[0].buffer= &tm[0];
|
||||
|
||||
rc= mysql_stmt_bind_param(stmt, my_bind);
|
||||
check_stmt_rc(rc, stmt);
|
||||
|
||||
tm[0].year= 10000;
|
||||
tm[0].month= 1; tm[0].day= 1;
|
||||
tm[0].hour= 1; tm[0].minute= 1; tm[0].second= 1;
|
||||
tm[0].second_part= 0; tm[0].neg= 0;
|
||||
|
||||
/* Cause a statement reprepare */
|
||||
rc= mysql_query(mysql, "alter table t1 add column c int");
|
||||
check_mysql_rc(rc, mysql);
|
||||
|
||||
rc= mysql_stmt_execute(stmt);
|
||||
check_stmt_rc(rc, stmt);
|
||||
/*
|
||||
Sic: only one warning, instead of two. The warning
|
||||
about data truncation when assigning a parameter is lost.
|
||||
This is a bug.
|
||||
*/
|
||||
FAIL_IF(mysql_warning_count(mysql) != 1, "warning count != 1");
|
||||
|
||||
if (verify_col_data(mysql, "t1", "year", "0000-00-00 00:00:00")) {
|
||||
mysql_stmt_close(stmt);
|
||||
rc= mysql_query(mysql, "drop table t1");
|
||||
return FAIL;
|
||||
}
|
||||
|
||||
mysql_stmt_close(stmt);
|
||||
|
||||
rc= mysql_query(mysql, "drop table t1");
|
||||
check_mysql_rc(rc, mysql);
|
||||
return OK;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
Test that long data parameters, as well as parameters
|
||||
that were originally in a different character set, are
|
||||
preserved in case of reprepare.
|
||||
*/
|
||||
|
||||
static int test_wl4166_4(MYSQL *mysql)
|
||||
{
|
||||
MYSQL_STMT *stmt;
|
||||
int rc;
|
||||
const char *stmt_text;
|
||||
MYSQL_BIND bind_array[2];
|
||||
|
||||
/* Represented as numbers to keep UTF8 tools from clobbering them. */
|
||||
const char *koi8= "\xee\xd5\x2c\x20\xda\xc1\x20\xd2\xd9\xc2\xc1\xcc\xcb\xd5";
|
||||
const char *cp1251= "\xcd\xf3\x2c\x20\xe7\xe0\x20\xf0\xfb\xe1\xe0\xeb\xea\xf3";
|
||||
char buf1[16], buf2[16];
|
||||
ulong buf1_len, buf2_len;
|
||||
|
||||
if (mysql_get_server_version(mysql) < 50100) {
|
||||
diag("Test requires MySQL Server version 5.1 or above");
|
||||
return SKIP;
|
||||
}
|
||||
|
||||
rc= mysql_query(mysql, "drop table if exists t1");
|
||||
check_mysql_rc(rc, mysql);
|
||||
|
||||
/*
|
||||
Create table with binary columns, set session character set to cp1251,
|
||||
client character set to koi8, and make sure that there is conversion
|
||||
on insert and no conversion on select
|
||||
*/
|
||||
rc= mysql_query(mysql,
|
||||
"create table t1 (c1 varbinary(255), c2 varbinary(255))");
|
||||
check_mysql_rc(rc, mysql);
|
||||
rc= mysql_query(mysql, "set character_set_client=koi8r, "
|
||||
"character_set_connection=cp1251, "
|
||||
"character_set_results=koi8r");
|
||||
check_mysql_rc(rc, mysql);
|
||||
|
||||
memset(bind_array, '\0', sizeof(bind_array));
|
||||
|
||||
bind_array[0].buffer_type= MYSQL_TYPE_STRING;
|
||||
|
||||
bind_array[1].buffer_type= MYSQL_TYPE_STRING;
|
||||
bind_array[1].buffer= (void *) koi8;
|
||||
bind_array[1].buffer_length= strlen(koi8);
|
||||
|
||||
stmt= mysql_stmt_init(mysql);
|
||||
check_stmt_rc(rc, stmt);
|
||||
|
||||
stmt_text= "insert into t1 (c1, c2) values (?, ?)";
|
||||
|
||||
rc= mysql_stmt_prepare(stmt, stmt_text, strlen(stmt_text));
|
||||
check_stmt_rc(rc, stmt);
|
||||
|
||||
mysql_stmt_bind_param(stmt, bind_array);
|
||||
|
||||
mysql_stmt_send_long_data(stmt, 0, koi8, strlen(koi8));
|
||||
|
||||
/* Cause a reprepare at statement execute */
|
||||
rc= mysql_query(mysql, "alter table t1 add column d int");
|
||||
check_mysql_rc(rc, mysql);
|
||||
|
||||
rc= mysql_stmt_execute(stmt);
|
||||
check_stmt_rc(rc, stmt);
|
||||
|
||||
stmt_text= "select c1, c2 from t1";
|
||||
|
||||
/* c1 and c2 are binary so no conversion will be done on select */
|
||||
rc= mysql_stmt_prepare(stmt, stmt_text, strlen(stmt_text));
|
||||
check_stmt_rc(rc, stmt);
|
||||
|
||||
rc= mysql_stmt_execute(stmt);
|
||||
check_stmt_rc(rc, stmt);
|
||||
|
||||
bind_array[0].buffer= buf1;
|
||||
bind_array[0].buffer_length= sizeof(buf1);
|
||||
bind_array[0].length= &buf1_len;
|
||||
|
||||
bind_array[1].buffer= buf2;
|
||||
bind_array[1].buffer_length= sizeof(buf2);
|
||||
bind_array[1].length= &buf2_len;
|
||||
|
||||
mysql_stmt_bind_result(stmt, bind_array);
|
||||
|
||||
rc= mysql_stmt_fetch(stmt);
|
||||
check_stmt_rc(rc, stmt);
|
||||
|
||||
FAIL_UNLESS(buf1_len == strlen(cp1251), "");
|
||||
FAIL_UNLESS(buf2_len == strlen(cp1251), "");
|
||||
FAIL_UNLESS(!memcmp(buf1, cp1251, buf1_len), "");
|
||||
FAIL_UNLESS(!memcmp(buf2, cp1251, buf1_len), "");
|
||||
|
||||
rc= mysql_stmt_fetch(stmt);
|
||||
FAIL_UNLESS(rc == MYSQL_NO_DATA, "");
|
||||
|
||||
mysql_stmt_close(stmt);
|
||||
|
||||
rc= mysql_query(mysql, "drop table t1");
|
||||
check_mysql_rc(rc, mysql);
|
||||
rc= mysql_query(mysql, "set names default");
|
||||
check_mysql_rc(rc, mysql);
|
||||
return OK;
|
||||
}
|
||||
|
||||
/**
|
||||
Test that COM_REFRESH issues a implicit commit.
|
||||
*/
|
||||
|
||||
static int test_wl4284_1(MYSQL *mysql)
|
||||
{
|
||||
int rc;
|
||||
MYSQL_ROW row;
|
||||
MYSQL_RES *result;
|
||||
|
||||
if (mysql_get_server_version(mysql) < 60000) {
|
||||
diag("Test requires MySQL Server version 6.0 or above");
|
||||
return SKIP;
|
||||
}
|
||||
|
||||
/* set AUTOCOMMIT to OFF */
|
||||
rc= mysql_autocommit(mysql, FALSE);
|
||||
check_mysql_rc(rc, mysql);
|
||||
|
||||
rc= mysql_query(mysql, "DROP TABLE IF EXISTS trans");
|
||||
check_mysql_rc(rc, mysql);
|
||||
|
||||
rc= mysql_query(mysql, "CREATE TABLE trans (a INT) ENGINE= InnoDB");
|
||||
check_mysql_rc(rc, mysql);
|
||||
|
||||
rc= mysql_query(mysql, "INSERT INTO trans VALUES(1)");
|
||||
check_mysql_rc(rc, mysql);
|
||||
|
||||
rc= mysql_refresh(mysql, REFRESH_GRANT | REFRESH_TABLES);
|
||||
check_mysql_rc(rc, mysql);
|
||||
|
||||
rc= mysql_rollback(mysql);
|
||||
check_mysql_rc(rc, mysql);
|
||||
|
||||
rc= mysql_query(mysql, "SELECT * FROM trans");
|
||||
check_mysql_rc(rc, mysql);
|
||||
|
||||
result= mysql_use_result(mysql);
|
||||
FAIL_IF(!result, "Invalid result set");
|
||||
|
||||
row= mysql_fetch_row(result);
|
||||
FAIL_IF(!row, "Can't fetch row");
|
||||
|
||||
mysql_free_result(result);
|
||||
|
||||
/* set AUTOCOMMIT to OFF */
|
||||
rc= mysql_autocommit(mysql, FALSE);
|
||||
check_mysql_rc(rc, mysql);
|
||||
|
||||
rc= mysql_query(mysql, "DROP TABLE trans");
|
||||
check_mysql_rc(rc, mysql);
|
||||
|
||||
return OK;
|
||||
}
|
||||
|
||||
static int test_bug49694(MYSQL *mysql)
|
||||
{
|
||||
int rc;
|
||||
int i;
|
||||
FILE *fp;
|
||||
|
||||
rc= mysql_query(mysql, "DROP TABLE IF EXISTS enclist");
|
||||
check_mysql_rc(rc, mysql);
|
||||
|
||||
rc= mysql_query(mysql, "CREATE TABLE `enclist` ("
|
||||
" `pat_id` int(11) NOT NULL,"
|
||||
" `episode_id` int(11) NOT NULL,"
|
||||
" `enc_id` double NOT NULL,"
|
||||
" PRIMARY KEY (`pat_id`,`episode_id`,`enc_id`)"
|
||||
") ENGINE=MyISAM DEFAULT CHARSET=latin1");
|
||||
check_mysql_rc(rc, mysql);
|
||||
|
||||
fp= fopen("data.csv", "w");
|
||||
FAIL_IF(!fp, "Can't open data.csv");
|
||||
|
||||
for (i=0; i < 100; i++)
|
||||
fprintf (fp, "%.08d,%d,%f\r\n", 100 + i, i % 3 + 1, 60000.0 + i/100);
|
||||
fclose(fp);
|
||||
|
||||
rc= mysql_query(mysql, "LOAD DATA LOCAL INFILE './data.csv' INTO TABLE enclist "
|
||||
"FIELDS TERMINATED BY '.' LINES TERMINATED BY '\r\n'");
|
||||
check_mysql_rc(rc, mysql);
|
||||
|
||||
rc= mysql_query(mysql, "DELETE FROM enclist");
|
||||
check_mysql_rc(rc, mysql);
|
||||
|
||||
FAIL_IF(mysql_affected_rows(mysql) != 100, "Import failure. Expected 2 imported rows");
|
||||
|
||||
rc= mysql_query(mysql, "DROP TABLE enclist");
|
||||
check_mysql_rc(rc, mysql);
|
||||
return OK;
|
||||
}
|
||||
|
||||
struct my_tests_st my_tests[] = {
|
||||
{"test_bug28075", test_bug28075, TEST_CONNECTION_DEFAULT, 0, NULL, NULL},
|
||||
{"test_bug28505", test_bug28505, TEST_CONNECTION_DEFAULT, 0, NULL, NULL},
|
||||
{"test_debug_example", test_debug_example, TEST_CONNECTION_DEFAULT, 0, NULL, NULL},
|
||||
{"test_bug29692", test_bug29692, TEST_CONNECTION_NEW, CLIENT_FOUND_ROWS, NULL, NULL},
|
||||
{"test_bug31418", test_bug31418, TEST_CONNECTION_DEFAULT, 0, NULL, NULL},
|
||||
{"test_bug6081", test_bug6081, TEST_CONNECTION_DEFAULT, 0, NULL, NULL},
|
||||
{"test_frm_bug", test_frm_bug, TEST_CONNECTION_NEW, 0, NULL, NULL},
|
||||
{"test_wl4166_1", test_wl4166_1, TEST_CONNECTION_NEW, 0, NULL, NULL},
|
||||
{"test_wl4166_2", test_wl4166_2, TEST_CONNECTION_NEW, 0, NULL, NULL},
|
||||
{"test_wl4166_3", test_wl4166_3, TEST_CONNECTION_NEW, 0, NULL, NULL},
|
||||
{"test_wl4166_4", test_wl4166_4, TEST_CONNECTION_NEW, 0, NULL, NULL},
|
||||
{"test_wl4284_1", test_wl4284_1, TEST_CONNECTION_NEW, 0, NULL, NULL},
|
||||
{"test_bug49694", test_bug49694, TEST_CONNECTION_NEW, 0, NULL, NULL},
|
||||
{NULL, NULL, 0, 0, NULL, 0}
|
||||
};
|
||||
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
if (argc > 1)
|
||||
get_options(argc, argv);
|
||||
|
||||
get_envvars();
|
||||
|
||||
run_tests(my_tests);
|
||||
|
||||
return(exit_status());
|
||||
}
|
517
unittest/libmariadb/my_test.h
Normal file
517
unittest/libmariadb/my_test.h
Normal file
@@ -0,0 +1,517 @@
|
||||
/*
|
||||
Copyright (c) 2009, 2010, Oracle and/or its affiliates. All rights reserved.
|
||||
|
||||
The MySQL Connector/C is licensed under the terms of the GPLv2
|
||||
<http://www.gnu.org/licenses/old-licenses/gpl-2.0.html>, like most
|
||||
MySQL Connectors. There are special exceptions to the terms and
|
||||
conditions of the GPLv2 as it is applied to this software, see the
|
||||
FLOSS License Exception
|
||||
<http://www.mysql.com/about/legal/licensing/foss-exception.html>.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published
|
||||
by the Free Software Foundation; version 2 of the License.
|
||||
|
||||
This program is distributed in the hope that it will be useful, but
|
||||
WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License along
|
||||
with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
#include <my_global.h>
|
||||
#include <my_sys.h>
|
||||
#include <mysql.h>
|
||||
#include <tap.h>
|
||||
#include <getopt.h>
|
||||
#include <memory.h>
|
||||
#include <errmsg.h>
|
||||
|
||||
#ifndef OK
|
||||
# define OK 0
|
||||
#endif
|
||||
#ifndef FAIL
|
||||
# define FAIL 1
|
||||
#endif
|
||||
#ifndef SKIP
|
||||
# define SKIP -1
|
||||
#endif
|
||||
#ifndef FALSE
|
||||
# define FALSE 0
|
||||
#endif
|
||||
#ifndef TRUE
|
||||
# define TRUE 1
|
||||
#endif
|
||||
|
||||
#define MAX_KEY MAX_INDEXES
|
||||
#define MAX_KEY_LENGTH_DECIMAL_WIDTH 4 /* strlen("4096") */
|
||||
|
||||
#define MAX_TEST_QUERY_LENGTH 300 /* MAX QUERY BUFFER LENGTH */
|
||||
|
||||
#define check_mysql_rc(rc, mysql) \
|
||||
if (rc)\
|
||||
{\
|
||||
diag("Error (%d): %s (%d) in %s line %d", rc, mysql_error(mysql), \
|
||||
mysql_errno(mysql), __FILE__, __LINE__);\
|
||||
return(FAIL);\
|
||||
}
|
||||
|
||||
#define check_stmt_rc(rc, stmt) \
|
||||
if (rc)\
|
||||
{\
|
||||
diag("Error: %s (%s: %d)", mysql_stmt_error(stmt), __FILE__, __LINE__);\
|
||||
return(FAIL);\
|
||||
}
|
||||
|
||||
#define FAIL_IF(expr, reason)\
|
||||
if (expr)\
|
||||
{\
|
||||
diag("Error: %s (%s: %d)", (reason) ? reason : "", __FILE__, __LINE__);\
|
||||
return FAIL;\
|
||||
}
|
||||
|
||||
#define FAIL_UNLESS(expr, reason)\
|
||||
if (!(expr))\
|
||||
{\
|
||||
diag("Error: %s (%s: %d)", reason, __FILE__, __LINE__);\
|
||||
return FAIL;\
|
||||
}
|
||||
|
||||
/* connection options */
|
||||
#define TEST_CONNECTION_DEFAULT 1 /* default connection */
|
||||
#define TEST_CONNECTION_NONE 2 /* tests creates own connection */
|
||||
#define TEST_CONNECTION_NEW 4 /* create a separate connection */
|
||||
#define TEST_CONNECTION_DONT_CLOSE 8 /* don't close connection */
|
||||
|
||||
struct my_option_st
|
||||
{
|
||||
enum mysql_option option;
|
||||
char *value;
|
||||
};
|
||||
|
||||
struct my_tests_st
|
||||
{
|
||||
const char *name;
|
||||
int (*function)(MYSQL *);
|
||||
int connection;
|
||||
ulong connect_flags;
|
||||
struct my_option_st *options;
|
||||
char *skipmsg;
|
||||
};
|
||||
|
||||
static char *schema = "test";
|
||||
static char *hostname = 0;
|
||||
static char *password = 0;
|
||||
static unsigned int port = 0;
|
||||
static char *socketname = 0;
|
||||
static char *username = 0;
|
||||
/*
|
||||
static struct my_option test_options[] =
|
||||
{
|
||||
{"schema", 'd', "database to use", (uchar **) &schema, (uchar **) &schema,
|
||||
0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
|
||||
{"help", '?', "Display this help and exit", 0, 0, 0, GET_NO_ARG, NO_ARG, 0,
|
||||
0, 0, 0, 0, 0},
|
||||
{"host", 'h', "Connect to host", (uchar **) &hostname, (uchar **) &hostname,
|
||||
0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
|
||||
{"password", 'p',
|
||||
"Password to use when connecting to server.", (uchar **) &password, (uchar **) &password,
|
||||
0, GET_STR, OPT_ARG, 0, 0, 0, 0, 0, 0},
|
||||
{"port", 'P', "Port number to use for connection or 0 for default to, in "
|
||||
"order of preference, my.cnf, $MYSQL_TCP_PORT, "
|
||||
#if MYSQL_PORT_DEFAULT == 0
|
||||
"/etc/services, "
|
||||
#endif
|
||||
"built-in default (" STRINGIFY_ARG(MYSQL_PORT) ").",
|
||||
(uchar **) &port,
|
||||
(uchar **) &port, 0, GET_UINT, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
|
||||
{"socket", 'S', "Socket file to use for connection",
|
||||
(uchar **) &socketname, (uchar **) &socketname, 0, GET_STR,
|
||||
REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
|
||||
{"user", 'u', "User for login if not current user", (uchar **) &username,
|
||||
(uchar **) &username, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
|
||||
{ 0, 0, 0, 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}
|
||||
};
|
||||
*/
|
||||
#define verify_prepare_field(result,no,name,org_name,type,table,\
|
||||
org_table,db,length,def) \
|
||||
do_verify_prepare_field((result),(no),(name),(org_name),(type), \
|
||||
(table),(org_table),(db),(length),(def), \
|
||||
__FILE__, __LINE__)
|
||||
|
||||
int do_verify_prepare_field(MYSQL_RES *result,
|
||||
unsigned int no, const char *name,
|
||||
const char *org_name,
|
||||
enum enum_field_types type,
|
||||
const char *table,
|
||||
const char *org_table, const char *db,
|
||||
unsigned long length, const char *def,
|
||||
const char *file, int line)
|
||||
{
|
||||
MYSQL_FIELD *field;
|
||||
/* CHARSET_INFO *cs; */
|
||||
|
||||
FAIL_IF(!(field= mysql_fetch_field_direct(result, no)), "FAILED to get result");
|
||||
/* cs= mysql_find_charset_nr(field->charsetnr);
|
||||
FAIL_UNLESS(cs, "Couldn't get character set"); */
|
||||
FAIL_UNLESS(strcmp(field->name, name) == 0, "field->name differs");
|
||||
FAIL_UNLESS(strcmp(field->org_name, org_name) == 0, "field->org_name differs");
|
||||
/*
|
||||
if ((expected_field_length= length * cs->mbmaxlen) > UINT_MAX32)
|
||||
expected_field_length= UINT_MAX32;
|
||||
*/
|
||||
/*
|
||||
XXX: silent column specification change works based on number of
|
||||
bytes a column occupies. So CHAR -> VARCHAR upgrade is possible even
|
||||
for CHAR(2) column if its character set is multibyte.
|
||||
VARCHAR -> CHAR downgrade won't work for VARCHAR(3) as one would
|
||||
expect.
|
||||
*/
|
||||
// if (cs->char_maxlen == 1)
|
||||
// FAIL_UNLESS(field->type == type, "field->type differs");
|
||||
if (table)
|
||||
FAIL_UNLESS(strcmp(field->table, table) == 0, "field->table differs");
|
||||
if (org_table)
|
||||
FAIL_UNLESS(strcmp(field->org_table, org_table) == 0, "field->org_table differs");
|
||||
FAIL_UNLESS(strcmp(field->db, db) == 0, "field->db differs");
|
||||
/*
|
||||
Character set should be taken into account for multibyte encodings, such
|
||||
as utf8. Field length is calculated as number of characters * maximum
|
||||
number of bytes a character can occupy.
|
||||
*/
|
||||
|
||||
return OK;
|
||||
}
|
||||
|
||||
/* Prepare statement, execute, and process result set for given query */
|
||||
|
||||
int my_stmt_result(MYSQL *mysql, const char *buff)
|
||||
{
|
||||
MYSQL_STMT *stmt;
|
||||
int row_count= 0;
|
||||
int rc;
|
||||
|
||||
stmt= mysql_stmt_init(mysql);
|
||||
|
||||
rc= mysql_stmt_prepare(stmt, buff, strlen(buff));
|
||||
FAIL_IF(rc, mysql_stmt_error(stmt));
|
||||
|
||||
rc= mysql_stmt_execute(stmt);
|
||||
FAIL_IF(rc, mysql_stmt_error(stmt));
|
||||
|
||||
while (mysql_stmt_fetch(stmt) != MYSQL_NO_DATA)
|
||||
row_count++;
|
||||
|
||||
mysql_stmt_close(stmt);
|
||||
|
||||
return row_count;
|
||||
}
|
||||
/*
|
||||
static my_bool
|
||||
get_one_option(int optid, const struct my_option *opt __attribute__((unused)),
|
||||
char *argument)
|
||||
{
|
||||
switch (optid) {
|
||||
case '?':
|
||||
case 'I':
|
||||
my_print_help(test_options);
|
||||
exit(0);
|
||||
break;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
*/
|
||||
/* Utility function to verify a particular column data */
|
||||
|
||||
int verify_col_data(MYSQL *mysql, const char *table, const char *col,
|
||||
const char *exp_data)
|
||||
{
|
||||
static char query[MAX_TEST_QUERY_LENGTH];
|
||||
MYSQL_RES *result;
|
||||
MYSQL_ROW row;
|
||||
int rc;
|
||||
|
||||
if (table && col)
|
||||
{
|
||||
sprintf(query, "SELECT %s FROM %s LIMIT 1", col, table);
|
||||
rc= mysql_query(mysql, query);
|
||||
check_mysql_rc(rc, mysql);
|
||||
}
|
||||
result= mysql_use_result(mysql);
|
||||
FAIL_IF(!result, "Invalid result set");
|
||||
|
||||
if (!(row= mysql_fetch_row(result)) || !row[0]) {
|
||||
diag("Failed to get the result");
|
||||
goto error;
|
||||
}
|
||||
if(strcmp(row[0], exp_data)) {
|
||||
diag("Expected %s, got %s", exp_data, row[0]);
|
||||
goto error;
|
||||
}
|
||||
mysql_free_result(result);
|
||||
|
||||
return OK;
|
||||
|
||||
error:
|
||||
mysql_free_result(result);
|
||||
return FAIL;
|
||||
}
|
||||
|
||||
my_bool query_int_variable(MYSQL *con, const char *var_name, int *var_value)
|
||||
{
|
||||
MYSQL_RES *rs;
|
||||
MYSQL_ROW row;
|
||||
|
||||
char query_buffer[MAX_TEST_QUERY_LENGTH];
|
||||
|
||||
my_bool is_null;
|
||||
|
||||
sprintf(query_buffer,
|
||||
"SELECT %s",
|
||||
(const char *) var_name);
|
||||
|
||||
FAIL_IF(mysql_query(con, query_buffer), "Query failed");
|
||||
FAIL_UNLESS(rs= mysql_store_result(con), "Invaliid result set");
|
||||
FAIL_UNLESS(row= mysql_fetch_row(rs), "Nothing to fetch");
|
||||
|
||||
is_null= row[0] == NULL;
|
||||
|
||||
if (!is_null)
|
||||
*var_value= atoi(row[0]);
|
||||
|
||||
mysql_free_result(rs);
|
||||
|
||||
return is_null;
|
||||
}
|
||||
|
||||
static void usage()
|
||||
{
|
||||
printf("Execute test with the following options:\n");
|
||||
printf("-h hostname\n");
|
||||
printf("-u username\n");
|
||||
printf("-p password\n");
|
||||
printf("-d database\n");
|
||||
printf("-S socketname\n");
|
||||
printf("-P port number\n");
|
||||
printf("? displays this help and exits\n");
|
||||
}
|
||||
|
||||
void get_options(int argc, char **argv)
|
||||
{
|
||||
int c= 0;
|
||||
|
||||
while ((c=getopt(argc,argv, "h:u:p:d:P:S:?")) >= 0)
|
||||
{
|
||||
switch(c) {
|
||||
case 'h':
|
||||
hostname= optarg;
|
||||
break;
|
||||
case 'u':
|
||||
username= optarg;
|
||||
break;
|
||||
case 'p':
|
||||
password= optarg;
|
||||
break;
|
||||
case 'd':
|
||||
schema= optarg;
|
||||
break;
|
||||
case 'P':
|
||||
port= atoi(optarg);
|
||||
break;
|
||||
case 'S':
|
||||
socketname= optarg;
|
||||
break;
|
||||
case '?':
|
||||
usage();
|
||||
exit(0);
|
||||
break;
|
||||
default:
|
||||
printf("Unknown option %c\n", c);
|
||||
usage();
|
||||
exit(0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
int check_variable(MYSQL *mysql, char *variable, char *value)
|
||||
{
|
||||
char query[MAX_TEST_QUERY_LENGTH];
|
||||
MYSQL_RES *result;
|
||||
MYSQL_ROW row;
|
||||
|
||||
sprintf(query, "SELECT %s", variable);
|
||||
result= mysql_store_result(mysql);
|
||||
if (!result)
|
||||
return FAIL;
|
||||
|
||||
if ((row = mysql_fetch_row(result)))
|
||||
if (strcmp(row[0], value) == 0) {
|
||||
mysql_free_result(result);
|
||||
return OK;
|
||||
}
|
||||
mysql_free_result(result);
|
||||
return FAIL;
|
||||
}
|
||||
|
||||
/*
|
||||
* function *test_connect
|
||||
*
|
||||
* returns a new connection. This function will be called, if the test doesn't
|
||||
* use default_connection.
|
||||
*/
|
||||
MYSQL *test_connect(struct my_tests_st *test) {
|
||||
MYSQL *mysql;
|
||||
char query[255];
|
||||
|
||||
if (!(mysql = mysql_init(NULL))) {
|
||||
diag("%s", "mysql_init failed - exiting");
|
||||
return(NULL);
|
||||
}
|
||||
|
||||
mysql_options(mysql, MYSQL_REPORT_DATA_TRUNCATION, "1");
|
||||
|
||||
/* option handling */
|
||||
if (test && test->options) {
|
||||
int i=0;
|
||||
|
||||
while (test->options[i].option)
|
||||
{
|
||||
if (mysql_options(mysql, test->options[i].option, test->options[i].value)) {
|
||||
diag("Couldn't set option %d. Error (%d) %s", test->options[i].option,
|
||||
mysql_errno(mysql), mysql_error(mysql));
|
||||
mysql_close(mysql);
|
||||
return(NULL);
|
||||
}
|
||||
i++;
|
||||
}
|
||||
}
|
||||
|
||||
if (!(mysql_real_connect(mysql, hostname, username, password,
|
||||
NULL, port, socketname, (test) ? test->connect_flags:0)))
|
||||
{
|
||||
diag("Couldn't establish connection to server %s. Error (%d): %s",
|
||||
hostname, mysql_errno(mysql), mysql_error(mysql));
|
||||
mysql_close(mysql);
|
||||
return(NULL);
|
||||
}
|
||||
|
||||
/* change database or create if it doesn't exist */
|
||||
if (mysql_select_db(mysql, schema)) {
|
||||
if(mysql_errno(mysql) == 1049) {
|
||||
sprintf(query, "CREATE DATABASE %s", schema);
|
||||
if (mysql_query(mysql, query)) {
|
||||
diag("Can't create database %s", schema);
|
||||
mysql_close(mysql);
|
||||
return NULL;
|
||||
}
|
||||
} else {
|
||||
diag("Error (%d): %s", mysql_errno(mysql), mysql_error(mysql));
|
||||
mysql_close(mysql);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
return(mysql);
|
||||
}
|
||||
|
||||
static int reset_connection(MYSQL *mysql) {
|
||||
int rc;
|
||||
|
||||
rc= mysql_change_user(mysql, username, password, schema);
|
||||
check_mysql_rc(rc, mysql);
|
||||
if (mysql_get_server_version(mysql) < 50400)
|
||||
rc= mysql_query(mysql, "SET table_type='MyISAM'");
|
||||
else
|
||||
rc= mysql_query(mysql, "SET storage_engine='MyISAM'");
|
||||
check_mysql_rc(rc, mysql);
|
||||
rc= mysql_query(mysql, "SET sql_mode=''");
|
||||
check_mysql_rc(rc, mysql);
|
||||
|
||||
return OK;
|
||||
}
|
||||
|
||||
/*
|
||||
* function get_envvars((
|
||||
*
|
||||
* checks for connection related environment variables
|
||||
*/
|
||||
void get_envvars() {
|
||||
char *envvar;
|
||||
|
||||
if (!hostname && (envvar= getenv("MYSQL_TEST_HOST")))
|
||||
hostname= envvar;
|
||||
if (!username && (envvar= getenv("MYSQL_TEST_USER")))
|
||||
username= envvar;
|
||||
if (!password && (envvar= getenv("MYSQL_TEST_PASSWD")))
|
||||
password= envvar;
|
||||
if (!schema && (envvar= getenv("MYSQL_TEST_DB")))
|
||||
schema= envvar;
|
||||
if (!port && (envvar= getenv("MYSQL_TEST_PORT")))
|
||||
port= atoi(envvar);
|
||||
if (!socketname && (envvar= getenv("MYSQL_TEST_SOCKET")))
|
||||
socketname= envvar;
|
||||
}
|
||||
|
||||
void run_tests(struct my_tests_st *test) {
|
||||
int i, rc, total=0;
|
||||
MYSQL *mysql, *mysql_default= NULL; /* default connection */
|
||||
|
||||
|
||||
while (test[total].function)
|
||||
total++;
|
||||
plan(total);
|
||||
|
||||
if ((mysql_default= test_connect(NULL)))
|
||||
diag("Testing against MySQL Server %s", mysql_get_server_info(mysql_default));
|
||||
else
|
||||
{
|
||||
diag("Can't connect to a server. Aborting....");
|
||||
exit(0);
|
||||
}
|
||||
|
||||
for (i=0; i < total; i++) {
|
||||
if (!mysql_default && (test[i].connection & TEST_CONNECTION_DEFAULT))
|
||||
{
|
||||
diag("MySQL server not running");
|
||||
skip(1, test[i].name);
|
||||
} else if (!test[i].skipmsg) {
|
||||
mysql= mysql_default;
|
||||
if (test[i].connection & TEST_CONNECTION_NEW)
|
||||
mysql= test_connect(&test[i]);
|
||||
if (test[i].connection & TEST_CONNECTION_NONE)
|
||||
mysql= NULL;
|
||||
|
||||
/* run test */
|
||||
rc= test[i].function(mysql);
|
||||
|
||||
if (rc == SKIP)
|
||||
skip(1, test[i].name);
|
||||
else
|
||||
ok(rc == OK, test[i].name);
|
||||
|
||||
/* if test failed, close and reopen default connection to prevent
|
||||
errors for further tests */
|
||||
if ((rc == FAIL || mysql_errno(mysql_default)) && (test[i].connection & TEST_CONNECTION_DEFAULT)) {
|
||||
mysql_close(mysql_default);
|
||||
mysql_default= test_connect(&test[i]);
|
||||
}
|
||||
/* clear connection: reset default connection or close extra connection */
|
||||
else if (mysql_default && (test[i].connection & TEST_CONNECTION_DEFAULT)) {
|
||||
if (reset_connection(mysql))
|
||||
return; /* default doesn't work anymore */
|
||||
}
|
||||
else if (mysql && !(test[i].connection & TEST_CONNECTION_DONT_CLOSE))
|
||||
mysql_close(mysql);
|
||||
} else {
|
||||
skip(1, test[i].skipmsg);
|
||||
}
|
||||
}
|
||||
if (mysql_default) {
|
||||
mysql_close(mysql_default);
|
||||
}
|
||||
mysql_server_end();
|
||||
}
|
||||
|
4619
unittest/libmariadb/ps.c
Normal file
4619
unittest/libmariadb/ps.c
Normal file
File diff suppressed because it is too large
Load Diff
3779
unittest/libmariadb/ps_bugs.c
Normal file
3779
unittest/libmariadb/ps_bugs.c
Normal file
File diff suppressed because it is too large
Load Diff
147
unittest/libmariadb/ps_new.c
Normal file
147
unittest/libmariadb/ps_new.c
Normal file
@@ -0,0 +1,147 @@
|
||||
/************************************************************************************
|
||||
Copyright (C) 2012 Monty Program AB
|
||||
|
||||
This library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Library General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2 of the License, or (at your option) any later version.
|
||||
|
||||
This library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Library General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Library General Public
|
||||
License along with this library; if not see <http://www.gnu.org/licenses>
|
||||
or write to the Free Software Foundation, Inc.,
|
||||
51 Franklin St., Fifth Floor, Boston, MA 02110, USA
|
||||
*************************************************************************************/
|
||||
|
||||
#include "my_test.h"
|
||||
|
||||
/* Utility function to verify the field members */
|
||||
|
||||
|
||||
static int test_multi_result(MYSQL *mysql)
|
||||
{
|
||||
MYSQL_STMT *stmt;
|
||||
MYSQL_BIND ps_params[3]; /* input parameter buffers */
|
||||
MYSQL_BIND rs_bind[3];
|
||||
int int_data[3]; /* input/output values */
|
||||
my_bool is_null[3]; /* output value nullability */
|
||||
int rc, i;
|
||||
|
||||
/* set up stored procedure */
|
||||
rc = mysql_query(mysql, "DROP PROCEDURE IF EXISTS p1");
|
||||
check_mysql_rc(rc, mysql);
|
||||
|
||||
rc = mysql_query(mysql,
|
||||
"CREATE PROCEDURE p1("
|
||||
" IN p_in INT, "
|
||||
" OUT p_out INT, "
|
||||
" INOUT p_inout INT) "
|
||||
"BEGIN "
|
||||
" SELECT p_in, p_out, p_inout; "
|
||||
" SET p_in = 100, p_out = 200, p_inout = 300; "
|
||||
" SELECT p_in, p_out, p_inout; "
|
||||
"END");
|
||||
check_mysql_rc(rc, mysql);
|
||||
|
||||
/* initialize and prepare CALL statement with parameter placeholders */
|
||||
stmt = mysql_stmt_init(mysql);
|
||||
if (!stmt)
|
||||
{
|
||||
printf("Could not initialize statement\n");
|
||||
exit(1);
|
||||
}
|
||||
rc = mysql_stmt_prepare(stmt, "CALL p1(?, ?, ?)", 16);
|
||||
check_stmt_rc(rc, stmt);
|
||||
|
||||
/* initialize parameters: p_in, p_out, p_inout (all INT) */
|
||||
memset(ps_params, 0, sizeof (ps_params));
|
||||
|
||||
ps_params[0].buffer_type = MYSQL_TYPE_LONG;
|
||||
ps_params[0].buffer = (char *) &int_data[0];
|
||||
ps_params[0].length = 0;
|
||||
ps_params[0].is_null = 0;
|
||||
|
||||
ps_params[1].buffer_type = MYSQL_TYPE_LONG;
|
||||
ps_params[1].buffer = (char *) &int_data[1];
|
||||
ps_params[1].length = 0;
|
||||
ps_params[1].is_null = 0;
|
||||
|
||||
ps_params[2].buffer_type = MYSQL_TYPE_LONG;
|
||||
ps_params[2].buffer = (char *) &int_data[2];
|
||||
ps_params[2].length = 0;
|
||||
ps_params[2].is_null = 0;
|
||||
|
||||
/* bind parameters */
|
||||
rc = mysql_stmt_bind_param(stmt, ps_params);
|
||||
check_stmt_rc(rc, stmt);
|
||||
|
||||
/* assign values to parameters and execute statement */
|
||||
int_data[0]= 10; /* p_in */
|
||||
int_data[1]= 20; /* p_out */
|
||||
int_data[2]= 30; /* p_inout */
|
||||
|
||||
rc = mysql_stmt_execute(stmt);
|
||||
check_stmt_rc(rc, stmt);
|
||||
|
||||
FAIL_IF(mysql_stmt_field_count(stmt) != 3, "expected 3 fields");
|
||||
|
||||
memset(rs_bind, 0, sizeof (MYSQL_BIND) * 3);
|
||||
for (i=0; i < 3; i++)
|
||||
{
|
||||
rs_bind[i].buffer = (char *) &(int_data[i]);
|
||||
rs_bind[i].buffer_length = sizeof (int_data);
|
||||
rs_bind[i].buffer_type = MYSQL_TYPE_LONG;
|
||||
rs_bind[i].is_null = &is_null[i];
|
||||
}
|
||||
rc= mysql_stmt_bind_result(stmt, rs_bind);
|
||||
check_stmt_rc(rc, stmt);
|
||||
|
||||
rc= mysql_stmt_fetch(stmt);
|
||||
check_stmt_rc(rc, stmt);
|
||||
|
||||
FAIL_IF(int_data[0] != 10 || int_data[1] != 20 || int_data[2] != 30,
|
||||
"expected 10 20 30");
|
||||
|
||||
FAIL_IF(mysql_stmt_next_result(stmt) != 0, "expected more results");
|
||||
rc= mysql_stmt_bind_result(stmt, rs_bind);
|
||||
|
||||
rc= mysql_stmt_fetch(stmt);
|
||||
FAIL_IF(mysql_stmt_field_count(stmt) != 3, "expected 3 fields");
|
||||
FAIL_IF(int_data[0] != 100 || int_data[1] != 200 || int_data[2] != 300,
|
||||
"expected 100 200 300");
|
||||
|
||||
FAIL_IF(mysql_stmt_next_result(stmt) != 0, "expected more results");
|
||||
rc= mysql_stmt_bind_result(stmt, rs_bind);
|
||||
|
||||
rc= mysql_stmt_fetch(stmt);
|
||||
FAIL_IF(mysql_stmt_field_count(stmt) != 2, "expected 2 fields");
|
||||
FAIL_IF(int_data[0] != 200 || int_data[1] != 300,
|
||||
"expected 100 200 300");
|
||||
|
||||
FAIL_IF(mysql_stmt_next_result(stmt) != 0, "expected more results");
|
||||
FAIL_IF(mysql_stmt_field_count(stmt) != 0, "expected 0 fields");
|
||||
|
||||
rc= mysql_stmt_close(stmt);
|
||||
check_stmt_rc(rc, stmt);
|
||||
}
|
||||
|
||||
struct my_tests_st my_tests[] = {
|
||||
{"test_multi_result", test_multi_result, TEST_CONNECTION_NEW, CLIENT_MULTI_STATEMENTS, NULL , NULL},
|
||||
{NULL, NULL, 0, 0, NULL, NULL}
|
||||
};
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
if (argc > 1)
|
||||
get_options(argc, argv);
|
||||
|
||||
get_envvars();
|
||||
|
||||
run_tests(my_tests);
|
||||
|
||||
return(exit_status());
|
||||
}
|
1064
unittest/libmariadb/result.c
Normal file
1064
unittest/libmariadb/result.c
Normal file
File diff suppressed because it is too large
Load Diff
91
unittest/libmariadb/sp.c
Normal file
91
unittest/libmariadb/sp.c
Normal file
@@ -0,0 +1,91 @@
|
||||
/*
|
||||
Copyright (c) 2009, 2010, Oracle and/or its affiliates. All rights reserved.
|
||||
|
||||
The MySQL Connector/C is licensed under the terms of the GPLv2
|
||||
<http://www.gnu.org/licenses/old-licenses/gpl-2.0.html>, like most
|
||||
MySQL Connectors. There are special exceptions to the terms and
|
||||
conditions of the GPLv2 as it is applied to this software, see the
|
||||
FLOSS License Exception
|
||||
<http://www.mysql.com/about/legal/licensing/foss-exception.html>.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published
|
||||
by the Free Software Foundation; version 2 of the License.
|
||||
|
||||
This program is distributed in the hope that it will be useful, but
|
||||
WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License along
|
||||
with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
#include "my_test.h"
|
||||
|
||||
/* Bug#15752 "Lost connection to MySQL server when calling a SP from C API" */
|
||||
|
||||
static int test_bug15752(MYSQL *mysql)
|
||||
{
|
||||
int rc, i;
|
||||
const int ITERATION_COUNT= 100;
|
||||
const char *query= "CALL p1()";
|
||||
|
||||
|
||||
rc= mysql_query(mysql, "drop procedure if exists p1");
|
||||
check_mysql_rc(rc, mysql);
|
||||
rc= mysql_query(mysql, "create procedure p1() select 1");
|
||||
check_mysql_rc(rc, mysql);
|
||||
|
||||
rc= mysql_real_query(mysql, query, strlen(query));
|
||||
check_mysql_rc(rc, mysql);
|
||||
mysql_free_result(mysql_store_result(mysql));
|
||||
|
||||
rc= mysql_real_query(mysql, query, strlen(query));
|
||||
FAIL_UNLESS(rc && mysql_errno(mysql) == CR_COMMANDS_OUT_OF_SYNC, "Error expected");
|
||||
|
||||
rc= mysql_next_result(mysql);
|
||||
check_mysql_rc(rc, mysql);
|
||||
|
||||
mysql_free_result(mysql_store_result(mysql));
|
||||
|
||||
rc= mysql_next_result(mysql);
|
||||
FAIL_IF(rc != -1, "rc != -1");
|
||||
|
||||
for (i = 0; i < ITERATION_COUNT; i++)
|
||||
{
|
||||
rc= mysql_real_query(mysql, query, strlen(query));
|
||||
check_mysql_rc(rc, mysql);
|
||||
mysql_free_result(mysql_store_result(mysql));
|
||||
rc= mysql_next_result(mysql);
|
||||
check_mysql_rc(rc, mysql);
|
||||
mysql_free_result(mysql_store_result(mysql));
|
||||
rc= mysql_next_result(mysql);
|
||||
FAIL_IF(rc != -1, "rc != -1");
|
||||
|
||||
}
|
||||
rc= mysql_query(mysql, "drop procedure p1");
|
||||
check_mysql_rc(rc, mysql);
|
||||
|
||||
return OK;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
struct my_tests_st my_tests[] = {
|
||||
{"test_bug15752", test_bug15752, TEST_CONNECTION_NEW, 0, NULL , NULL},
|
||||
{NULL, NULL, 0, 0, NULL, NULL}
|
||||
};
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
if (argc > 1)
|
||||
get_options(argc, argv);
|
||||
|
||||
get_envvars();
|
||||
|
||||
run_tests(my_tests);
|
||||
|
||||
return(exit_status());
|
||||
}
|
239
unittest/libmariadb/ssl.c
Normal file
239
unittest/libmariadb/ssl.c
Normal file
@@ -0,0 +1,239 @@
|
||||
/************************************************************************************
|
||||
Copyright (C) 2012 Monty Program AB
|
||||
|
||||
This library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Library General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2 of the License, or (at your option) any later version.
|
||||
|
||||
This library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Library General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Library General Public
|
||||
License along with this library; if not see <http://www.gnu.org/licenses>
|
||||
or write to the Free Software Foundation, Inc.,
|
||||
51 Franklin St., Fifth Floor, Boston, MA 02110, USA
|
||||
*************************************************************************************/
|
||||
|
||||
#include "my_test.h"
|
||||
#include <my_pthread.h>
|
||||
|
||||
static int skip_ssl= 1;
|
||||
|
||||
#ifdef THREAD
|
||||
pthread_mutex_t LOCK_test;
|
||||
#endif
|
||||
|
||||
int check_skip_ssl()
|
||||
{
|
||||
#ifndef HAVE_OPENSSL
|
||||
diag("client library built without OpenSSL support -> skip");
|
||||
return 1;
|
||||
#endif
|
||||
if (skip_ssl)
|
||||
{
|
||||
diag("server doesn't support SSL -> skip");
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int test_ssl(MYSQL *mysql)
|
||||
{
|
||||
int rc;
|
||||
MYSQL_RES *res;
|
||||
MYSQL_ROW row;
|
||||
|
||||
rc= mysql_query(mysql, "SELECT @@have_ssl");
|
||||
check_mysql_rc(rc, mysql);
|
||||
|
||||
res= mysql_store_result(mysql);
|
||||
FAIL_IF(!res, mysql_error(mysql));
|
||||
|
||||
if ((row= mysql_fetch_row(res)))
|
||||
{
|
||||
if (!strcmp(row[0], "YES"))
|
||||
skip_ssl= 0;
|
||||
diag("SSL: %s", row[0]);
|
||||
}
|
||||
mysql_free_result(res);
|
||||
|
||||
return OK;
|
||||
}
|
||||
|
||||
static int test_ssl_cipher(MYSQL *unused)
|
||||
{
|
||||
MYSQL *my;
|
||||
char *cipher;
|
||||
|
||||
if (check_skip_ssl())
|
||||
return SKIP;
|
||||
|
||||
my= mysql_init(NULL);
|
||||
FAIL_IF(!my, "mysql_init() failed");
|
||||
|
||||
mysql_ssl_set(my,0, 0, "./ca.pem", 0, 0);
|
||||
|
||||
FAIL_IF(!mysql_real_connect(my, hostname, username, password, schema,
|
||||
port, socketname, 0), mysql_error(my));
|
||||
|
||||
cipher= (char *)mysql_get_ssl_cipher(my);
|
||||
FAIL_IF(strcmp(cipher, "DHE-RSA-AES256-SHA") != 0, "Cipher != DHE-RSA-AES256-SHA");
|
||||
mysql_close(my);
|
||||
return OK;
|
||||
}
|
||||
|
||||
static int test_multi_ssl_connections(MYSQL *unused)
|
||||
{
|
||||
MYSQL *mysql[50], *my;
|
||||
char *cipher;
|
||||
int i, rc;
|
||||
int old_connections= 0, new_connections= 0;
|
||||
MYSQL_RES *res;
|
||||
MYSQL_ROW row;
|
||||
|
||||
if (check_skip_ssl())
|
||||
return SKIP;
|
||||
|
||||
my= mysql_init(NULL);
|
||||
FAIL_IF(!my,"mysql_init() failed");
|
||||
FAIL_IF(!mysql_real_connect(my, hostname, username, password, schema,
|
||||
port, socketname, 0), mysql_error(my));
|
||||
|
||||
rc= mysql_query(my, "SHOW STATUS LIKE 'Ssl_accepts'");
|
||||
check_mysql_rc(rc, my);
|
||||
|
||||
res= mysql_store_result(my);
|
||||
if ((row= mysql_fetch_row(res)))
|
||||
old_connections= atoi(row[1]);
|
||||
mysql_free_result(res);
|
||||
|
||||
for (i=0; i < 50; i++)
|
||||
{
|
||||
mysql[i]= mysql_init(NULL);
|
||||
FAIL_IF(!mysql[i],"mysql_init() failed");
|
||||
|
||||
mysql_ssl_set(mysql[i], 0, 0, "./ca.pem", 0, 0);
|
||||
|
||||
FAIL_IF(!mysql_real_connect(mysql[i], hostname, username, password, schema,
|
||||
port, socketname, 0), mysql_error(mysql[i]));
|
||||
|
||||
cipher= (char *)mysql_get_ssl_cipher(mysql[i]);
|
||||
FAIL_IF(strcmp(cipher, "DHE-RSA-AES256-SHA") != 0, "Cipher != DHE-RSA-AES256-SHA");
|
||||
}
|
||||
for (i=0; i < 50; i++)
|
||||
mysql_close(mysql[i]);
|
||||
|
||||
rc= mysql_query(my, "SHOW STATUS LIKE 'Ssl_accepts'");
|
||||
check_mysql_rc(rc, my);
|
||||
|
||||
res= mysql_store_result(my);
|
||||
if ((row= mysql_fetch_row(res)))
|
||||
new_connections= atoi(row[1]);
|
||||
mysql_free_result(res);
|
||||
|
||||
mysql_close(my);
|
||||
|
||||
FAIL_IF(new_connections - old_connections < 50, "new_connections should be at least old_connections + 50");
|
||||
diag("%d SSL connections processed", new_connections - old_connections);
|
||||
return OK;
|
||||
}
|
||||
|
||||
#ifndef WIN32
|
||||
#ifdef THREAD
|
||||
static void ssl_thread(void)
|
||||
{
|
||||
MYSQL *mysql;
|
||||
|
||||
mysql_thread_init();
|
||||
|
||||
if (!(mysql= mysql_init(NULL)))
|
||||
{
|
||||
mysql_thread_end();
|
||||
pthread_exit(-1);
|
||||
}
|
||||
mysql_ssl_set(mysql, 0, 0, "./ca.pem", 0, 0);
|
||||
|
||||
if(!mysql_real_connect(mysql, hostname, username, password, schema,
|
||||
port, socketname, 0))
|
||||
{
|
||||
diag("Error: %s", mysql_error(mysql));
|
||||
mysql_close(mysql);
|
||||
mysql_thread_end();
|
||||
pthread_exit(-1);
|
||||
}
|
||||
|
||||
pthread_mutex_lock(&LOCK_test);
|
||||
mysql_query(mysql, "UPDATE ssltest SET a=a+1");
|
||||
pthread_mutex_unlock(&LOCK_test);
|
||||
mysql_close(mysql);
|
||||
mysql_thread_end();
|
||||
pthread_exit(0);
|
||||
}
|
||||
#endif
|
||||
|
||||
static int test_ssl_threads(MYSQL *mysql)
|
||||
{
|
||||
#ifdef THREAD
|
||||
int i, rc;
|
||||
pthread_t thread[50];
|
||||
MYSQL_RES *res;
|
||||
MYSQL_ROW row;
|
||||
|
||||
rc= mysql_query(mysql, "DROP TABLE IF exists ssltest");
|
||||
check_mysql_rc(rc, mysql);
|
||||
rc= mysql_query(mysql, "CREATE TABLE ssltest (a int)");
|
||||
check_mysql_rc(rc, mysql);
|
||||
rc= mysql_query(mysql, "INSERT into ssltest VALUES (0)");
|
||||
check_mysql_rc(rc, mysql);
|
||||
|
||||
pthread_mutex_init(&LOCK_test, NULL);
|
||||
|
||||
for (i=0; i < 50; i++)
|
||||
pthread_create(&thread[i], NULL, (void *)&ssl_thread, NULL);
|
||||
for (i=0; i < 50; i++)
|
||||
pthread_join(thread[i], NULL);
|
||||
|
||||
pthread_mutex_destroy(&LOCK_test);
|
||||
|
||||
rc= mysql_query(mysql, "SELECT a FROM ssltest");
|
||||
check_mysql_rc(rc, mysql);
|
||||
res= mysql_store_result(mysql);
|
||||
row= mysql_fetch_row(res);
|
||||
diag("Found: %s", row[0]);
|
||||
FAIL_IF(strcmp(row[0], "50") != 0, "Expected 50");
|
||||
mysql_free_result(res);
|
||||
return OK;
|
||||
#else
|
||||
diag("no thread support -> skip");
|
||||
return SKIP;
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
|
||||
struct my_tests_st my_tests[] = {
|
||||
{"test_ssl", test_ssl, TEST_CONNECTION_NEW, 0, NULL, NULL},
|
||||
{"test_ssl_cipher", test_ssl_cipher, TEST_CONNECTION_NONE, 0, NULL, NULL},
|
||||
{"test_multi_ssl_connections", test_multi_ssl_connections, TEST_CONNECTION_NONE, 0, NULL, NULL},
|
||||
#ifndef WIN32
|
||||
{"test_ssl_threads", test_ssl_threads, TEST_CONNECTION_NEW, 0, NULL, NULL},
|
||||
#endif
|
||||
{NULL, NULL, 0, 0, NULL, NULL}
|
||||
};
|
||||
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
get_envvars();
|
||||
|
||||
if (argc > 1)
|
||||
get_options(argc, argv);
|
||||
|
||||
|
||||
run_tests(my_tests);
|
||||
|
||||
mysql_server_end();
|
||||
return(exit_status());
|
||||
}
|
700
unittest/libmariadb/view.c
Normal file
700
unittest/libmariadb/view.c
Normal file
@@ -0,0 +1,700 @@
|
||||
/*
|
||||
Copyright (c) 2009, 2010, Oracle and/or its affiliates. All rights reserved.
|
||||
|
||||
The MySQL Connector/C is licensed under the terms of the GPLv2
|
||||
<http://www.gnu.org/licenses/old-licenses/gpl-2.0.html>, like most
|
||||
MySQL Connectors. There are special exceptions to the terms and
|
||||
conditions of the GPLv2 as it is applied to this software, see the
|
||||
FLOSS License Exception
|
||||
<http://www.mysql.com/about/legal/licensing/foss-exception.html>.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published
|
||||
by the Free Software Foundation; version 2 of the License.
|
||||
|
||||
This program is distributed in the hope that it will be useful, but
|
||||
WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License along
|
||||
with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
#include "my_test.h"
|
||||
|
||||
static int test_view(MYSQL *mysql)
|
||||
{
|
||||
MYSQL_STMT *stmt;
|
||||
int rc, i;
|
||||
MYSQL_BIND my_bind[1];
|
||||
char str_data[50];
|
||||
ulong length = 0L;
|
||||
long is_null = 0L;
|
||||
const char *query=
|
||||
"SELECT COUNT(*) FROM v1 WHERE SERVERNAME=?";
|
||||
|
||||
rc = mysql_query(mysql, "DROP TABLE IF EXISTS t1,t2,t3,v1");
|
||||
check_mysql_rc(rc, mysql);
|
||||
|
||||
rc = mysql_query(mysql, "DROP VIEW IF EXISTS v1,t1,t2,t3");
|
||||
check_mysql_rc(rc, mysql);
|
||||
rc= mysql_query(mysql,"CREATE TABLE t1 ("
|
||||
" SERVERGRP varchar(20) NOT NULL default '', "
|
||||
" DBINSTANCE varchar(20) NOT NULL default '', "
|
||||
" PRIMARY KEY (SERVERGRP)) "
|
||||
" CHARSET=latin1 collate=latin1_bin");
|
||||
check_mysql_rc(rc, mysql);
|
||||
rc= mysql_query(mysql,"CREATE TABLE t2 ("
|
||||
" SERVERNAME varchar(20) NOT NULL, "
|
||||
" SERVERGRP varchar(20) NOT NULL, "
|
||||
" PRIMARY KEY (SERVERNAME)) "
|
||||
" CHARSET=latin1 COLLATE latin1_bin");
|
||||
check_mysql_rc(rc, mysql);
|
||||
rc= mysql_query(mysql,
|
||||
"CREATE TABLE t3 ("
|
||||
" SERVERGRP varchar(20) BINARY NOT NULL, "
|
||||
" TABNAME varchar(30) NOT NULL, MAPSTATE char(1) NOT NULL, "
|
||||
" ACTSTATE char(1) NOT NULL , "
|
||||
" LOCAL_NAME varchar(30) NOT NULL, "
|
||||
" CHG_DATE varchar(8) NOT NULL default '00000000', "
|
||||
" CHG_TIME varchar(6) NOT NULL default '000000', "
|
||||
" MXUSER varchar(12) NOT NULL default '', "
|
||||
" PRIMARY KEY (SERVERGRP, TABNAME, MAPSTATE, ACTSTATE, "
|
||||
" LOCAL_NAME)) CHARSET=latin1 COLLATE latin1_bin");
|
||||
check_mysql_rc(rc, mysql);
|
||||
rc= mysql_query(mysql,"CREATE VIEW v1 AS select sql_no_cache"
|
||||
" T0001.SERVERNAME AS SERVERNAME, T0003.TABNAME AS"
|
||||
" TABNAME,T0003.LOCAL_NAME AS LOCAL_NAME,T0002.DBINSTANCE AS"
|
||||
" DBINSTANCE from t2 T0001 join t1 T0002 join t3 T0003 where"
|
||||
" ((T0002.SERVERGRP = T0001.SERVERGRP) and"
|
||||
" (T0002.SERVERGRP = T0003.SERVERGRP)"
|
||||
" and (T0003.MAPSTATE = _latin1'A') and"
|
||||
" (T0003.ACTSTATE = _latin1' '))");
|
||||
check_mysql_rc(rc, mysql);
|
||||
|
||||
stmt= mysql_stmt_init(mysql);
|
||||
rc= mysql_stmt_prepare(stmt, query, strlen(query));
|
||||
check_stmt_rc(rc, stmt);
|
||||
|
||||
strcpy(str_data, "TEST");
|
||||
memset(my_bind, '\0', sizeof(MYSQL_BIND));
|
||||
my_bind[0].buffer_type= MYSQL_TYPE_STRING;
|
||||
my_bind[0].buffer= (char *)&str_data;
|
||||
my_bind[0].buffer_length= 50;
|
||||
my_bind[0].length= &length;
|
||||
length= 4;
|
||||
my_bind[0].is_null= (char*)&is_null;
|
||||
rc= mysql_stmt_bind_param(stmt, my_bind);
|
||||
check_stmt_rc(rc, stmt);
|
||||
|
||||
for (i= 0; i < 3; i++)
|
||||
{
|
||||
int rowcount= 0;
|
||||
|
||||
rc= mysql_stmt_execute(stmt);
|
||||
check_stmt_rc(rc, stmt);
|
||||
|
||||
while (mysql_stmt_fetch(stmt) != MYSQL_NO_DATA)
|
||||
rowcount++;
|
||||
FAIL_IF(rowcount != 1, "Expected 1 row");
|
||||
}
|
||||
mysql_stmt_close(stmt);
|
||||
|
||||
rc= mysql_query(mysql, "DROP TABLE t1,t2,t3");
|
||||
check_mysql_rc(rc, mysql);
|
||||
rc= mysql_query(mysql, "DROP VIEW v1");
|
||||
check_mysql_rc(rc, mysql);
|
||||
|
||||
return OK;
|
||||
}
|
||||
|
||||
|
||||
static int test_view_where(MYSQL *mysql)
|
||||
{
|
||||
MYSQL_STMT *stmt;
|
||||
int rc, i;
|
||||
const char *query=
|
||||
"select v1.c,v2.c from v1, v2";
|
||||
|
||||
rc = mysql_query(mysql, "DROP TABLE IF EXISTS t1,v1,v2");
|
||||
check_mysql_rc(rc, mysql);
|
||||
|
||||
rc = mysql_query(mysql, "DROP VIEW IF EXISTS v1,v2,t1");
|
||||
check_mysql_rc(rc, mysql);
|
||||
rc= mysql_query(mysql,"CREATE TABLE t1 (a int, b int)");
|
||||
check_mysql_rc(rc, mysql);
|
||||
rc= mysql_query(mysql,"insert into t1 values (1,2), (1,3), (2,4), (2,5), (3,10)");
|
||||
check_mysql_rc(rc, mysql);
|
||||
rc= mysql_query(mysql,"create view v1 (c) as select b from t1 where a<3");
|
||||
check_mysql_rc(rc, mysql);
|
||||
rc= mysql_query(mysql,"create view v2 (c) as select b from t1 where a>=3");
|
||||
check_mysql_rc(rc, mysql);
|
||||
|
||||
stmt= mysql_stmt_init(mysql);
|
||||
rc= mysql_stmt_prepare(stmt, query, strlen(query));
|
||||
check_stmt_rc(rc, stmt);
|
||||
|
||||
for (i= 0; i < 3; i++)
|
||||
{
|
||||
int rowcount= 0;
|
||||
|
||||
rc= mysql_stmt_execute(stmt);
|
||||
check_stmt_rc(rc, stmt);
|
||||
while (mysql_stmt_fetch(stmt) != MYSQL_NO_DATA)
|
||||
rowcount++;
|
||||
FAIL_UNLESS(4 == rowcount, "Expected 4 rows");
|
||||
}
|
||||
mysql_stmt_close(stmt);
|
||||
|
||||
rc= mysql_query(mysql, "DROP TABLE t1");
|
||||
check_mysql_rc(rc, mysql);
|
||||
rc= mysql_query(mysql, "DROP VIEW v1, v2");
|
||||
check_mysql_rc(rc, mysql);
|
||||
|
||||
return OK;
|
||||
}
|
||||
|
||||
|
||||
static int test_view_2where(MYSQL *mysql)
|
||||
{
|
||||
MYSQL_STMT *stmt;
|
||||
int rc, i;
|
||||
MYSQL_BIND my_bind[8];
|
||||
char parms[8][100];
|
||||
ulong length[8];
|
||||
const char *query=
|
||||
"select relid, report, handle, log_group, username, variant, type, "
|
||||
"version, erfdat, erftime, erfname, aedat, aetime, aename, dependvars, "
|
||||
"inactive from V_LTDX where mandt = ? and relid = ? and report = ? and "
|
||||
"handle = ? and log_group = ? and username in ( ? , ? ) and type = ?";
|
||||
|
||||
rc= mysql_query(mysql, "DROP TABLE IF EXISTS LTDX");
|
||||
check_mysql_rc(rc, mysql);
|
||||
rc= mysql_query(mysql, "DROP VIEW IF EXISTS V_LTDX");
|
||||
check_mysql_rc(rc, mysql);
|
||||
rc= mysql_query(mysql,
|
||||
"CREATE TABLE LTDX (MANDT char(3) NOT NULL default '000', "
|
||||
" RELID char(2) NOT NULL, REPORT varchar(40) NOT NULL,"
|
||||
" HANDLE varchar(4) NOT NULL, LOG_GROUP varchar(4) NOT NULL,"
|
||||
" USERNAME varchar(12) NOT NULL,"
|
||||
" VARIANT varchar(12) NOT NULL,"
|
||||
" TYPE char(1) NOT NULL, SRTF2 int(11) NOT NULL,"
|
||||
" VERSION varchar(6) NOT NULL default '000000',"
|
||||
" ERFDAT varchar(8) NOT NULL default '00000000',"
|
||||
" ERFTIME varchar(6) NOT NULL default '000000',"
|
||||
" ERFNAME varchar(12) NOT NULL,"
|
||||
" AEDAT varchar(8) NOT NULL default '00000000',"
|
||||
" AETIME varchar(6) NOT NULL default '000000',"
|
||||
" AENAME varchar(12) NOT NULL,"
|
||||
" DEPENDVARS varchar(10) NOT NULL,"
|
||||
" INACTIVE char(1) NOT NULL, CLUSTR smallint(6) NOT NULL,"
|
||||
" CLUSTD blob,"
|
||||
" PRIMARY KEY (MANDT, RELID, REPORT, HANDLE, LOG_GROUP, "
|
||||
"USERNAME, VARIANT, TYPE, SRTF2))"
|
||||
" CHARSET=latin1 COLLATE latin1_bin");
|
||||
check_mysql_rc(rc, mysql);
|
||||
rc= mysql_query(mysql,
|
||||
"CREATE VIEW V_LTDX AS select T0001.MANDT AS "
|
||||
" MANDT,T0001.RELID AS RELID,T0001.REPORT AS "
|
||||
" REPORT,T0001.HANDLE AS HANDLE,T0001.LOG_GROUP AS "
|
||||
" LOG_GROUP,T0001.USERNAME AS USERNAME,T0001.VARIANT AS "
|
||||
" VARIANT,T0001.TYPE AS TYPE,T0001.VERSION AS "
|
||||
" VERSION,T0001.ERFDAT AS ERFDAT,T0001.ERFTIME AS "
|
||||
" ERFTIME,T0001.ERFNAME AS ERFNAME,T0001.AEDAT AS "
|
||||
" AEDAT,T0001.AETIME AS AETIME,T0001.AENAME AS "
|
||||
" AENAME,T0001.DEPENDVARS AS DEPENDVARS,T0001.INACTIVE AS "
|
||||
" INACTIVE from LTDX T0001 where (T0001.SRTF2 = 0)");
|
||||
check_mysql_rc(rc, mysql);
|
||||
memset(my_bind, '\0', sizeof(MYSQL_BIND));
|
||||
for (i=0; i < 8; i++) {
|
||||
strcpy(parms[i], "1");
|
||||
my_bind[i].buffer_type = MYSQL_TYPE_VAR_STRING;
|
||||
my_bind[i].buffer = (char *)&parms[i];
|
||||
my_bind[i].buffer_length = 100;
|
||||
my_bind[i].is_null = 0;
|
||||
my_bind[i].length = &length[i];
|
||||
length[i] = 1;
|
||||
}
|
||||
stmt= mysql_stmt_init(mysql);
|
||||
rc= mysql_stmt_prepare(stmt, query, strlen(query));
|
||||
check_stmt_rc(rc, stmt);
|
||||
|
||||
rc= mysql_stmt_bind_param(stmt, my_bind);
|
||||
check_stmt_rc(rc, stmt);
|
||||
|
||||
rc= mysql_stmt_execute(stmt);
|
||||
check_stmt_rc(rc, stmt);
|
||||
|
||||
rc= mysql_stmt_fetch(stmt);
|
||||
FAIL_UNLESS(MYSQL_NO_DATA == rc, "Expected 0 rows");
|
||||
|
||||
mysql_stmt_close(stmt);
|
||||
|
||||
rc= mysql_query(mysql, "DROP VIEW V_LTDX");
|
||||
check_mysql_rc(rc, mysql);
|
||||
rc= mysql_query(mysql, "DROP TABLE LTDX");
|
||||
check_mysql_rc(rc, mysql);
|
||||
|
||||
return OK;
|
||||
}
|
||||
|
||||
|
||||
static int test_view_star(MYSQL *mysql)
|
||||
{
|
||||
MYSQL_STMT *stmt;
|
||||
int rc, i;
|
||||
MYSQL_BIND my_bind[8];
|
||||
char parms[8][100];
|
||||
ulong length[8];
|
||||
const char *query= "SELECT * FROM vt1 WHERE a IN (?,?)";
|
||||
|
||||
rc= mysql_query(mysql, "DROP TABLE IF EXISTS t1, vt1");
|
||||
check_mysql_rc(rc, mysql);
|
||||
rc= mysql_query(mysql, "DROP VIEW IF EXISTS t1, vt1");
|
||||
check_mysql_rc(rc, mysql);
|
||||
rc= mysql_query(mysql, "CREATE TABLE t1 (a int)");
|
||||
check_mysql_rc(rc, mysql);
|
||||
rc= mysql_query(mysql, "CREATE VIEW vt1 AS SELECT a FROM t1");
|
||||
check_mysql_rc(rc, mysql);
|
||||
memset(my_bind, '\0', sizeof(MYSQL_BIND));
|
||||
for (i= 0; i < 2; i++) {
|
||||
sprintf((char *)&parms[i], "%d", i);
|
||||
my_bind[i].buffer_type = MYSQL_TYPE_VAR_STRING;
|
||||
my_bind[i].buffer = (char *)&parms[i];
|
||||
my_bind[i].buffer_length = 100;
|
||||
my_bind[i].is_null = 0;
|
||||
my_bind[i].length = &length[i];
|
||||
length[i] = 1;
|
||||
}
|
||||
|
||||
stmt= mysql_stmt_init(mysql);
|
||||
rc= mysql_stmt_prepare(stmt, query, strlen(query));
|
||||
check_stmt_rc(rc, stmt);
|
||||
|
||||
rc= mysql_stmt_bind_param(stmt, my_bind);
|
||||
check_stmt_rc(rc, stmt);
|
||||
|
||||
for (i= 0; i < 3; i++)
|
||||
{
|
||||
rc= mysql_stmt_execute(stmt);
|
||||
check_stmt_rc(rc, stmt);
|
||||
rc= mysql_stmt_fetch(stmt);
|
||||
FAIL_UNLESS(MYSQL_NO_DATA == rc, "Expected 0 rows");
|
||||
}
|
||||
|
||||
mysql_stmt_close(stmt);
|
||||
|
||||
rc= mysql_query(mysql, "DROP TABLE t1");
|
||||
check_mysql_rc(rc, mysql);
|
||||
rc= mysql_query(mysql, "DROP VIEW vt1");
|
||||
check_mysql_rc(rc, mysql);
|
||||
|
||||
return OK;
|
||||
}
|
||||
|
||||
|
||||
static int test_view_insert(MYSQL *mysql)
|
||||
{
|
||||
MYSQL_STMT *insert_stmt, *select_stmt;
|
||||
int rc, i;
|
||||
MYSQL_BIND my_bind[1];
|
||||
int my_val = 0;
|
||||
ulong my_length = 0L;
|
||||
long my_null = 0L;
|
||||
const char *query=
|
||||
"insert into v1 values (?)";
|
||||
|
||||
rc = mysql_query(mysql, "DROP TABLE IF EXISTS t1,v1");
|
||||
check_mysql_rc(rc, mysql);
|
||||
rc = mysql_query(mysql, "DROP VIEW IF EXISTS t1,v1");
|
||||
check_mysql_rc(rc, mysql);
|
||||
|
||||
rc= mysql_query(mysql,"create table t1 (a int, primary key (a))");
|
||||
check_mysql_rc(rc, mysql);
|
||||
|
||||
rc= mysql_query(mysql, "create view v1 as select a from t1 where a>=1");
|
||||
check_mysql_rc(rc, mysql);
|
||||
|
||||
insert_stmt= mysql_stmt_init(mysql);
|
||||
rc= mysql_stmt_prepare(insert_stmt, query, strlen(query));
|
||||
check_stmt_rc(rc, insert_stmt);
|
||||
query= "select * from t1";
|
||||
select_stmt= mysql_stmt_init(mysql);
|
||||
rc= mysql_stmt_prepare(select_stmt, query, strlen(query));
|
||||
check_stmt_rc(rc, select_stmt);
|
||||
|
||||
memset(my_bind, '\0', sizeof(MYSQL_BIND));
|
||||
my_bind[0].buffer_type = MYSQL_TYPE_LONG;
|
||||
my_bind[0].buffer = (char *)&my_val;
|
||||
my_bind[0].length = &my_length;
|
||||
my_bind[0].is_null = (char*)&my_null;
|
||||
rc= mysql_stmt_bind_param(insert_stmt, my_bind);
|
||||
check_stmt_rc(rc, select_stmt);
|
||||
|
||||
for (i= 0; i < 3; i++)
|
||||
{
|
||||
int rowcount= 0;
|
||||
my_val= i;
|
||||
|
||||
rc= mysql_stmt_execute(insert_stmt);
|
||||
check_stmt_rc(rc, insert_stmt);;
|
||||
|
||||
rc= mysql_stmt_execute(select_stmt);
|
||||
check_stmt_rc(rc, select_stmt);;
|
||||
while (mysql_stmt_fetch(select_stmt) != MYSQL_NO_DATA)
|
||||
rowcount++;
|
||||
FAIL_UNLESS((i+1) == rowcount, "rowcount != i+1");
|
||||
}
|
||||
mysql_stmt_close(insert_stmt);
|
||||
mysql_stmt_close(select_stmt);
|
||||
|
||||
rc= mysql_query(mysql, "DROP VIEW v1");
|
||||
check_mysql_rc(rc, mysql);
|
||||
rc= mysql_query(mysql, "DROP TABLE t1");
|
||||
check_mysql_rc(rc, mysql);
|
||||
|
||||
return OK;
|
||||
}
|
||||
|
||||
|
||||
static int test_left_join_view(MYSQL *mysql)
|
||||
{
|
||||
MYSQL_STMT *stmt;
|
||||
int rc, i;
|
||||
const char *query=
|
||||
"select t1.a, v1.x from t1 left join v1 on (t1.a= v1.x);";
|
||||
|
||||
rc = mysql_query(mysql, "DROP TABLE IF EXISTS t1,v1");
|
||||
check_mysql_rc(rc, mysql);
|
||||
|
||||
rc = mysql_query(mysql, "DROP VIEW IF EXISTS v1,t1");
|
||||
check_mysql_rc(rc, mysql);
|
||||
rc= mysql_query(mysql,"CREATE TABLE t1 (a int)");
|
||||
check_mysql_rc(rc, mysql);
|
||||
rc= mysql_query(mysql,"insert into t1 values (1), (2), (3)");
|
||||
check_mysql_rc(rc, mysql);
|
||||
rc= mysql_query(mysql,"create view v1 (x) as select a from t1 where a > 1");
|
||||
check_mysql_rc(rc, mysql);
|
||||
stmt= mysql_stmt_init(mysql);
|
||||
rc= mysql_stmt_prepare(stmt, query, strlen(query));
|
||||
check_stmt_rc(rc, stmt);
|
||||
|
||||
for (i= 0; i < 3; i++)
|
||||
{
|
||||
int rowcount= 0;
|
||||
|
||||
rc= mysql_stmt_execute(stmt);
|
||||
check_stmt_rc(rc, stmt);
|
||||
while (mysql_stmt_fetch(stmt) != MYSQL_NO_DATA)
|
||||
rowcount++;
|
||||
FAIL_UNLESS(3 == rowcount, "Expected 3 rows");
|
||||
}
|
||||
mysql_stmt_close(stmt);
|
||||
|
||||
rc= mysql_query(mysql, "DROP VIEW v1");
|
||||
check_mysql_rc(rc, mysql);
|
||||
rc= mysql_query(mysql, "DROP TABLE t1");
|
||||
check_mysql_rc(rc, mysql);
|
||||
|
||||
return OK;
|
||||
}
|
||||
|
||||
|
||||
static int test_view_insert_fields(MYSQL *mysql)
|
||||
{
|
||||
MYSQL_STMT *stmt;
|
||||
char parm[11][1000];
|
||||
ulong l[11];
|
||||
int rc, i;
|
||||
int rowcount= 0;
|
||||
MYSQL_BIND my_bind[11];
|
||||
const char *query= "INSERT INTO `v1` ( `K1C4` ,`K2C4` ,`K3C4` ,`K4N4` ,`F1C4` ,`F2I4` ,`F3N5` ,`F7F8` ,`F6N4` ,`F5C8` ,`F9D8` ) VALUES( ? , ? , ? , ? , ? , ? , ? , ? , ? , ? , ? )";
|
||||
|
||||
rc= mysql_query(mysql, "DROP TABLE IF EXISTS t1, v1");
|
||||
check_mysql_rc(rc, mysql);
|
||||
rc= mysql_query(mysql, "DROP VIEW IF EXISTS t1, v1");
|
||||
check_mysql_rc(rc, mysql);
|
||||
rc= mysql_query(mysql,
|
||||
"CREATE TABLE t1 (K1C4 varchar(4) NOT NULL,"
|
||||
"K2C4 varchar(4) NOT NULL, K3C4 varchar(4) NOT NULL,"
|
||||
"K4N4 varchar(4) NOT NULL default '0000',"
|
||||
"F1C4 varchar(4) NOT NULL, F2I4 int(11) NOT NULL,"
|
||||
"F3N5 varchar(5) NOT NULL default '00000',"
|
||||
"F4I4 int(11) NOT NULL default '0', F5C8 varchar(8) NOT NULL,"
|
||||
"F6N4 varchar(4) NOT NULL default '0000',"
|
||||
"F7F8 double NOT NULL default '0',"
|
||||
"F8F8 double NOT NULL default '0',"
|
||||
"F9D8 decimal(8,2) NOT NULL default '0.00',"
|
||||
"PRIMARY KEY (K1C4,K2C4,K3C4,K4N4)) "
|
||||
"CHARSET=latin1 COLLATE latin1_bin");
|
||||
check_mysql_rc(rc, mysql);
|
||||
rc= mysql_query(mysql,
|
||||
"CREATE VIEW v1 AS select sql_no_cache "
|
||||
" K1C4 AS K1C4, K2C4 AS K2C4, K3C4 AS K3C4, K4N4 AS K4N4, "
|
||||
" F1C4 AS F1C4, F2I4 AS F2I4, F3N5 AS F3N5,"
|
||||
" F7F8 AS F7F8, F6N4 AS F6N4, F5C8 AS F5C8, F9D8 AS F9D8"
|
||||
" from t1 T0001");
|
||||
|
||||
memset(my_bind, '\0', sizeof(my_bind));
|
||||
for (i= 0; i < 11; i++)
|
||||
{
|
||||
l[i]= 20;
|
||||
my_bind[i].buffer_type= MYSQL_TYPE_STRING;
|
||||
my_bind[i].is_null= 0;
|
||||
my_bind[i].buffer= (char *)&parm[i];
|
||||
|
||||
strcpy(parm[i], "1");
|
||||
my_bind[i].buffer_length= 2;
|
||||
my_bind[i].length= &l[i];
|
||||
}
|
||||
stmt= mysql_stmt_init(mysql);
|
||||
rc= mysql_stmt_prepare(stmt, query, strlen(query));
|
||||
check_stmt_rc(rc, stmt);
|
||||
rc= mysql_stmt_bind_param(stmt, my_bind);
|
||||
check_stmt_rc(rc, stmt);
|
||||
|
||||
rc= mysql_stmt_execute(stmt);
|
||||
check_stmt_rc(rc, stmt);
|
||||
mysql_stmt_close(stmt);
|
||||
|
||||
query= "select * from t1";
|
||||
stmt= mysql_stmt_init(mysql);
|
||||
rc= mysql_stmt_prepare(stmt, query, strlen(query));
|
||||
check_stmt_rc(rc, stmt);
|
||||
rc= mysql_stmt_execute(stmt);
|
||||
check_stmt_rc(rc, stmt);
|
||||
while (mysql_stmt_fetch(stmt) != MYSQL_NO_DATA)
|
||||
rowcount++;
|
||||
FAIL_UNLESS(1 == rowcount, "Expected 1 row");
|
||||
|
||||
mysql_stmt_close(stmt);
|
||||
rc= mysql_query(mysql, "DROP VIEW v1");
|
||||
check_mysql_rc(rc, mysql);
|
||||
rc= mysql_query(mysql, "DROP TABLE t1");
|
||||
check_mysql_rc(rc, mysql);
|
||||
|
||||
return OK;
|
||||
}
|
||||
|
||||
static int test_view_sp_list_fields(MYSQL *mysql)
|
||||
{
|
||||
int rc;
|
||||
MYSQL_RES *res;
|
||||
MYSQL_ROW row;
|
||||
int skip;
|
||||
|
||||
/* skip this test if bin_log is on */
|
||||
rc= mysql_query(mysql, "SHOW VARIABLES LIKE 'log_bin'");
|
||||
check_mysql_rc(rc, mysql);
|
||||
res= mysql_store_result(mysql);
|
||||
FAIL_IF(!res, "empty/invalid resultset");
|
||||
row = mysql_fetch_row(res);
|
||||
skip= (strcmp((char *)row[1], "ON") == 0);
|
||||
mysql_free_result(res);
|
||||
|
||||
if (skip) {
|
||||
diag("bin_log is ON -> skip");
|
||||
return SKIP;
|
||||
}
|
||||
|
||||
rc= mysql_query(mysql, "DROP FUNCTION IF EXISTS f1");
|
||||
check_mysql_rc(rc, mysql);
|
||||
rc= mysql_query(mysql, "DROP TABLE IF EXISTS v1, t1, t2");
|
||||
check_mysql_rc(rc, mysql);
|
||||
rc= mysql_query(mysql, "DROP VIEW IF EXISTS v1, t1, t2");
|
||||
check_mysql_rc(rc, mysql);
|
||||
rc= mysql_query(mysql, "create function f1 () returns int return 5");
|
||||
check_mysql_rc(rc, mysql);
|
||||
rc= mysql_query(mysql, "create table t1 (s1 char,s2 char)");
|
||||
check_mysql_rc(rc, mysql);
|
||||
rc= mysql_query(mysql, "create table t2 (s1 int);");
|
||||
check_mysql_rc(rc, mysql);
|
||||
rc= mysql_query(mysql, "create view v1 as select s2,sum(s1) - \
|
||||
count(s2) as vx from t1 group by s2 having sum(s1) - count(s2) < (select f1() \
|
||||
from t2);");
|
||||
check_mysql_rc(rc, mysql);
|
||||
res= mysql_list_fields(mysql, "v1", NullS);
|
||||
FAIL_UNLESS(res != 0 && mysql_num_fields(res) != 0, "0 Fields");
|
||||
rc= mysql_query(mysql, "DROP FUNCTION f1");
|
||||
check_mysql_rc(rc, mysql);
|
||||
rc= mysql_query(mysql, "DROP VIEW v1");
|
||||
check_mysql_rc(rc, mysql);
|
||||
rc= mysql_query(mysql, "DROP TABLE t1, t2");
|
||||
mysql_free_result(res);
|
||||
check_mysql_rc(rc, mysql);
|
||||
|
||||
return OK;
|
||||
}
|
||||
|
||||
static int test_bug19671(MYSQL *mysql)
|
||||
{
|
||||
MYSQL_RES *result;
|
||||
MYSQL_FIELD *field;
|
||||
int rc, retcode= OK;
|
||||
|
||||
|
||||
rc= mysql_query(mysql, "set sql_mode=''");
|
||||
check_mysql_rc(rc, mysql);
|
||||
rc= mysql_query(mysql, "drop table if exists t1");
|
||||
check_mysql_rc(rc, mysql);
|
||||
|
||||
rc= mysql_query(mysql, "drop view if exists v1");
|
||||
check_mysql_rc(rc, mysql);
|
||||
|
||||
rc= mysql_query(mysql, "create table t1(f1 int)");
|
||||
check_mysql_rc(rc, mysql);
|
||||
|
||||
rc= mysql_query(mysql, "create view v1 as select va.* from t1 va");
|
||||
check_mysql_rc(rc, mysql);
|
||||
|
||||
rc= mysql_query(mysql, "SELECT * FROM v1");
|
||||
check_mysql_rc(rc, mysql);
|
||||
|
||||
result= mysql_store_result(mysql);
|
||||
FAIL_IF(!result, "Invalid result set");
|
||||
|
||||
field= mysql_fetch_field(result);
|
||||
FAIL_IF(!field, "Can't fetch field");
|
||||
|
||||
if (strcmp(field->table, "v1") != 0) {
|
||||
diag("Wrong value '%s' for field_table. Expected 'v1'. (%s: %d)", field->table, __FILE__, __LINE__);
|
||||
retcode= FAIL;
|
||||
}
|
||||
|
||||
mysql_free_result(result);
|
||||
|
||||
rc= mysql_query(mysql, "drop view v1");
|
||||
check_mysql_rc(rc, mysql);
|
||||
rc= mysql_query(mysql, "drop table t1");
|
||||
check_mysql_rc(rc, mysql);
|
||||
|
||||
return OK;
|
||||
}
|
||||
|
||||
/*
|
||||
Bug#11111: fetch from view returns wrong data
|
||||
*/
|
||||
|
||||
static int test_bug11111(MYSQL *mysql)
|
||||
{
|
||||
MYSQL_STMT *stmt;
|
||||
MYSQL_BIND my_bind[2];
|
||||
char buf[2][20];
|
||||
ulong len[2];
|
||||
int i;
|
||||
int rc;
|
||||
const char *query= "SELECT DISTINCT f1,ff2 FROM v1";
|
||||
|
||||
rc= mysql_query(mysql, "drop table if exists t1, t2, v1");
|
||||
check_mysql_rc(rc, mysql);
|
||||
rc= mysql_query(mysql, "drop view if exists t1, t2, v1");
|
||||
check_mysql_rc(rc, mysql);
|
||||
rc= mysql_query(mysql, "create table t1 (f1 int, f2 int)");
|
||||
check_mysql_rc(rc, mysql);
|
||||
rc= mysql_query(mysql, "create table t2 (ff1 int, ff2 int)");
|
||||
check_mysql_rc(rc, mysql);
|
||||
rc= mysql_query(mysql, "create view v1 as select * from t1, t2 where f1=ff1");
|
||||
check_mysql_rc(rc, mysql);
|
||||
rc= mysql_query(mysql, "insert into t1 values (1,1), (2,2), (3,3)");
|
||||
check_mysql_rc(rc, mysql);
|
||||
rc= mysql_query(mysql, "insert into t2 values (1,1), (2,2), (3,3)");
|
||||
check_mysql_rc(rc, mysql);
|
||||
|
||||
stmt= mysql_stmt_init(mysql);
|
||||
|
||||
rc= mysql_stmt_prepare(stmt, query, strlen(query));
|
||||
check_stmt_rc(rc, stmt);
|
||||
rc= mysql_stmt_execute(stmt);
|
||||
check_stmt_rc(rc, stmt);
|
||||
|
||||
memset(my_bind, '\0', sizeof(my_bind));
|
||||
for (i=0; i < 2; i++)
|
||||
{
|
||||
my_bind[i].buffer_type= MYSQL_TYPE_STRING;
|
||||
my_bind[i].buffer= (uchar* *)&buf[i];
|
||||
my_bind[i].buffer_length= 20;
|
||||
my_bind[i].length= &len[i];
|
||||
}
|
||||
|
||||
rc= mysql_stmt_bind_result(stmt, my_bind);
|
||||
check_stmt_rc(rc, stmt);
|
||||
|
||||
rc= mysql_stmt_fetch(stmt);
|
||||
check_stmt_rc(rc, stmt);
|
||||
FAIL_UNLESS(!strcmp(buf[1],"1"), "buf[1] != '1'");
|
||||
mysql_stmt_close(stmt);
|
||||
rc= mysql_query(mysql, "drop view v1");
|
||||
check_mysql_rc(rc, mysql);
|
||||
rc= mysql_query(mysql, "drop table t1, t2");
|
||||
check_mysql_rc(rc, mysql);
|
||||
|
||||
return OK;
|
||||
}
|
||||
|
||||
/**
|
||||
Bug#29306 Truncated data in MS Access with decimal (3,1) columns in a VIEW
|
||||
*/
|
||||
|
||||
static int test_bug29306(MYSQL *mysql)
|
||||
{
|
||||
MYSQL_FIELD *field;
|
||||
int rc;
|
||||
MYSQL_RES *res;
|
||||
|
||||
DBUG_ENTER("test_bug29306");
|
||||
|
||||
rc= mysql_query(mysql, "DROP TABLE IF EXISTS tab17557");
|
||||
check_mysql_rc(rc, mysql);
|
||||
rc= mysql_query(mysql, "DROP VIEW IF EXISTS view17557");
|
||||
check_mysql_rc(rc, mysql);
|
||||
rc= mysql_query(mysql, "CREATE TABLE tab17557 (dd decimal (3,1))");
|
||||
check_mysql_rc(rc, mysql);
|
||||
rc= mysql_query(mysql, "CREATE VIEW view17557 as SELECT dd FROM tab17557");
|
||||
check_mysql_rc(rc, mysql);
|
||||
rc= mysql_query(mysql, "INSERT INTO tab17557 VALUES (7.6)");
|
||||
check_mysql_rc(rc, mysql);
|
||||
|
||||
/* Checking the view */
|
||||
res= mysql_list_fields(mysql, "view17557", NULL);
|
||||
while ((field= mysql_fetch_field(res)))
|
||||
{
|
||||
FAIL_UNLESS(field->decimals == 1, "field->decimals != 1");
|
||||
}
|
||||
mysql_free_result(res);
|
||||
|
||||
rc= mysql_query(mysql, "DROP TABLE tab17557");
|
||||
check_mysql_rc(rc, mysql);
|
||||
rc= mysql_query(mysql, "DROP VIEW view17557");
|
||||
check_mysql_rc(rc, mysql);
|
||||
|
||||
return OK;
|
||||
}
|
||||
|
||||
|
||||
struct my_tests_st my_tests[] = {
|
||||
{"test_view", test_view, TEST_CONNECTION_DEFAULT, 0, NULL , NULL},
|
||||
{"test_view_where", test_view_where, TEST_CONNECTION_DEFAULT, 0, NULL , NULL},
|
||||
{"test_view_2where", test_view_2where, TEST_CONNECTION_DEFAULT, 0, NULL , NULL},
|
||||
{"test_view_star", test_view_star, TEST_CONNECTION_DEFAULT, 0, NULL , NULL},
|
||||
{"test_view_insert", test_view_insert, TEST_CONNECTION_DEFAULT, 0, NULL , NULL},
|
||||
{"test_left_join_view", test_left_join_view, TEST_CONNECTION_DEFAULT, 0, NULL , NULL},
|
||||
{"test_view_insert_fields", test_view_insert_fields, TEST_CONNECTION_DEFAULT, 0, NULL , NULL},
|
||||
{"test_view_sp_list_fields", test_view_sp_list_fields,TEST_CONNECTION_DEFAULT, 0, NULL , NULL},
|
||||
{"test_bug19671", test_bug19671, TEST_CONNECTION_DEFAULT, 0, NULL , NULL},
|
||||
{"test_bug29306", test_bug29306, TEST_CONNECTION_DEFAULT, 0, NULL , NULL},
|
||||
{"test_bug11111", test_bug11111, TEST_CONNECTION_DEFAULT, 0, NULL , NULL},
|
||||
{NULL, NULL, 0, 0, NULL, NULL}
|
||||
};
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
// if (argc > 1)
|
||||
// get_options(&argc, &argv);
|
||||
|
||||
get_envvars();
|
||||
|
||||
run_tests(my_tests);
|
||||
|
||||
return(exit_status());
|
||||
}
|
Reference in New Issue
Block a user