Skip to content

Commit

Permalink
[ODBC-91] The fix and the testcase. If the connection handles was
Browse files Browse the repository at this point in the history
reused, the connector would try to use default database from previous
connection (and if there wasn't such database the connect would fail).
That happened because connector copied database name form connection
string to the structure field where SQL_ATTR_CURRENT_CATALOG attribute
is stored, if it wasn't set.
  • Loading branch information
lawrinn committed May 22, 2018
1 parent d6cc40c commit b68cc3d
Show file tree
Hide file tree
Showing 3 changed files with 113 additions and 6 deletions.
3 changes: 2 additions & 1 deletion ma_connection.c
Original file line number Diff line number Diff line change
Expand Up @@ -315,7 +315,8 @@ SQLRETURN MADB_DbcGetAttr(MADB_Dbc *Dbc, SQLINTEGER Attribute, SQLPOINTER ValueP
case SQL_ATTR_CURRENT_CATALOG:
{
SQLSMALLINT StrLen;
SQLRETURN ret;
SQLRETURN ret;

ret= MADB_Dbc_GetCurrentDB(Dbc, ValuePtr, BufferLength, &StrLen, isWChar);
/* if we weren't able to determine the current db, we will return the cached catalog name */
if (!SQL_SUCCEEDED(ret) && Dbc->CatalogName)
Expand Down
106 changes: 101 additions & 5 deletions test/basic.c
Original file line number Diff line number Diff line change
Expand Up @@ -1398,8 +1398,8 @@ ODBC_TEST(t_odbc69)
SQLSMALLINT conn_out_len;

/* Testing also that key names are case insensitve. Supposing, that there is no mariadb/mysql on 3310 port with same login credentials */
sprintf((char *)conn, "DSN=%s;UID=%s;PWD=%s;PORT=3310;DATABASE=%s;OPTION=%lu;SERVER=%s;PoRt=%s;charset=UTF8",
my_dsn, my_uid, my_pwd, my_schema, my_options, my_servername, ma_strport);
sprintf((char *)conn, "DSN=%s;UID=%s;PWD=%s;PORT=3310;DATABASE=%s;OPTION=%lu;SERVER=%s;PoRt=%u;charset=UTF8",
my_dsn, my_uid, my_pwd, my_schema, my_options, my_servername, my_port);

CHECK_ENV_RC(Env, SQLAllocHandle(SQL_HANDLE_DBC, Env, &hdbc1));

Expand All @@ -1410,8 +1410,102 @@ ODBC_TEST(t_odbc69)

CHECK_DBC_RC(hdbc1, SQLDisconnect(hdbc1));

CHECK_DBC_RC(hdbc1, SQLFreeHandle(SQL_HANDLE_DBC, hdbc1));

return OK;
}

/* If connection handle re-used, it would try to select database used in previous connection */
ODBC_TEST(t_odbc91)
{
HDBC hdbc;
HSTMT hstmt;
SQLCHAR conn[512], conn_out[1024], buffer[32];
SQLSMALLINT conn_out_len;

OK_SIMPLE_STMT(Stmt, "DROP DATABASE IF EXISTS t_odbc91");
OK_SIMPLE_STMT(Stmt, "CREATE DATABASE t_odbc91");

/* Connecting to newly created tatabase */
sprintf((char *)conn, "DSN=%s;UID=%s;PWD=%s;DATABASE=%s;OPTION=%lu;SERVER=%s%s",
my_dsn, my_uid, my_pwd, "t_odbc91", my_options, my_servername, ma_strport);

CHECK_ENV_RC(Env, SQLAllocHandle(SQL_HANDLE_DBC, Env, &hdbc));

CHECK_DBC_RC(hdbc, SQLDriverConnect(hdbc, NULL, conn, (SQLSMALLINT)strlen(conn),
conn_out, (SQLSMALLINT)sizeof(conn_out), &conn_out_len,
SQL_DRIVER_NOPROMPT));

CHECK_DBC_RC(hdbc, SQLDisconnect(hdbc));

OK_SIMPLE_STMT(Stmt, "DROP DATABASE t_odbc91");

/* Now we do not specify any database */
sprintf((char *)conn, "DSN=%s;UID=%s;PWD=%s;OPTION=%lu;SERVER=%s;DATABASE=%s%s",
my_dsn, my_uid, my_pwd, my_options, my_servername, my_schema, ma_strport);

CHECK_DBC_RC(hdbc, SQLDriverConnect(hdbc, NULL, conn, (SQLSMALLINT)strlen(conn),
conn_out, (SQLSMALLINT)sizeof(conn_out), &conn_out_len,
SQL_DRIVER_NOPROMPT));

CHECK_DBC_RC(hdbc, SQLDisconnect(hdbc));

/* Now testing scenario, there default database is set via connetion attribute, and connection handler is re-used
after disconnect. This doesn't work with UnixODBC, because smart UnixODBC implicicitly deallocates connection handle
when SQLDisconnect is called */
if (UnixOdbc(Env))
{
diag("UnixODBC detected - Skipping part of the test");
return OK;
}
OK_SIMPLE_STMT(Stmt, "CREATE DATABASE t_odbc91");
CHECK_DBC_RC(hdbc, SQLSetConnectAttr(hdbc, SQL_ATTR_CURRENT_CATALOG, (SQLPOINTER)"t_odbc91", SQL_NTS));

sprintf((char *)conn, "Driver=%s;UID=%s;PWD=%s;OPTION=%lu;SERVER=%s%s",
my_drivername, my_uid, my_pwd, my_options, my_servername, ma_strport);

CHECK_DBC_RC(hdbc, SQLDriverConnect(hdbc, NULL, conn, (SQLSMALLINT)strlen(conn),
conn_out, (SQLSMALLINT)sizeof(conn_out), &conn_out_len,
SQL_DRIVER_NOPROMPT));

CHECK_DBC_RC(hdbc, SQLGetConnectAttr(hdbc, SQL_ATTR_CURRENT_CATALOG, (SQLPOINTER)buffer, sizeof(buffer), NULL));

IS_STR(buffer, "t_odbc91", sizeof("t_odbc91"));
buffer[0]= '\0';

CHECK_DBC_RC(hdbc, SQLAllocHandle(SQL_HANDLE_STMT, hdbc, &hstmt));

OK_SIMPLE_STMT(hstmt, "SELECT DATABASE()");
CHECK_STMT_RC(hstmt, SQLFetch(hstmt));
IS_STR(my_fetch_str(hstmt, buffer, 1), "t_odbc91", sizeof("t_odbc91"));

CHECK_DBC_RC(hdbc, SQLDisconnect(hdbc));

buffer[0]= '\0';

/* Checking that attribute value is preserved - this doesn't work with UnixODBC */
CHECK_DBC_RC(hdbc, SQLGetConnectAttr(hdbc, SQL_ATTR_CURRENT_CATALOG, (SQLPOINTER)buffer, sizeof(buffer), NULL));
IS_STR(buffer, "t_odbc91", sizeof("t_odbc91"));

CHECK_DBC_RC(hdbc, SQLDriverConnect(hdbc, NULL, conn, (SQLSMALLINT)strlen(conn),
conn_out, (SQLSMALLINT)sizeof(conn_out), &conn_out_len,
SQL_DRIVER_NOPROMPT));
CHECK_DBC_RC(hdbc, SQLAllocHandle(SQL_HANDLE_STMT, hdbc, &hstmt));

OK_SIMPLE_STMT(hstmt, "SELECT DATABASE()");
CHECK_STMT_RC(hstmt, SQLFetch(hstmt));
IS_STR(my_fetch_str(hstmt, buffer, 1), "t_odbc91", sizeof("t_odbc91"));

CHECK_STMT_RC(hstmt, SQLFreeStmt(hstmt, SQL_CLOSE));

CHECK_DBC_RC(hdbc, SQLDisconnect(hdbc));
CHECK_DBC_RC(hdbc, SQLFreeHandle(SQL_HANDLE_DBC, hdbc));
OK_SIMPLE_STMT(Stmt, "DROP DATABASE t_odbc91");

return OK;
}


MA_ODBC_TESTS my_tests[]=
{
{t_disconnect, "t_disconnect", NORMAL},
Expand Down Expand Up @@ -1448,9 +1542,11 @@ MA_ODBC_TESTS my_tests[]=
{t_bug45378, "t_bug45378", NORMAL},
{t_mysqld_stmt_reset, "tmysqld_stmt_reset bug", NORMAL},
{t_odbc32, "odbc32_SQL_ATTR_PACKET_SIZE_option", NORMAL},
{t_gh_issue3, "leading_space_gh_issue3", NORMAL},
{t_odbc48, "odbc48_iso_call_format", NORMAL},
{t_odbc69, "odbc69_ci_connstring", NORMAL},
{t_gh_issue3, "leading_space_gh_issue3", NORMAL},
{t_odbc48, "odbc48_iso_call_format", NORMAL},
{t_odbc69, "odbc69_ci_connstring", NORMAL},
{t_odbc91, "odbc91_hdbc_reuse", NORMAL},

{NULL, NULL, 0}
};

Expand Down
10 changes: 10 additions & 0 deletions test/tap.h
Original file line number Diff line number Diff line change
Expand Up @@ -1154,4 +1154,14 @@ BOOL ServerNotOlderThan(SQLHDBC Conn, unsigned int major, unsigned int minor, un

return TRUE;
}


BOOL UnixOdbc(HENV Env)
{
#ifdef SQL_ATTR_UNIXODBC_VERSION
return TRUE;
#endif
return FALSE;
}

#endif /* #ifndef _tap_h_ */

0 comments on commit b68cc3d

Please sign in to comment.