Issue Details (XML | Word | Printable)

Key: ODBC-202
Type: Bug Bug
Status: Open Open
Priority: Minor Minor
Assignee: Alexander Potapchenko
Reporter: zxMarce
Votes: 0
Watchers: 0
Operations

If you were logged in you would be able to see more operations.
ODBC Driver

SQLGetConnectAttr() misbehaves.

Created: 17/Nov/16 12:10 PM   Updated: 03/Feb/19 09:49 AM
Component/s: None
Affects Version/s: None
Fix Version/s: None

Environment: Ubuntu Linux 16.04LTS with unixODBC.


 Description  « Hide
I'm enhancing an existing ODBC component for use in Gambas 3, a Visual Basic 6 lookalike for Linux platforms. It works against unixODBC and whatever ODBC driver is set up in the system.

When used with FreeTDS v0.91 against a MSSQL database, SQLGetConnectAttr() with the SQL_ATTR_CURRENT_CATALOG attribute correctly fetches the current catalog name (database name).
Please note that I never call SQLSetConnectAttr() in order to later obtain this value, and I'm using SQLDriverConnect() with a connection string to connect to MSSQL, not a DSN.

When I do the same against a Firebird 2.5 server running on Localhost with a test database, the call returns a two-character string, usually -but not always- a lowercase "L" followed by a non-printable char. The routine is calling SQLGetConnectAttr() twice: First to get the necessary buffer length, second to retrieve the string itself.

After I posted these details to the Firebird-odbc-devel mailing list, I was asked to register an issue here.
In the list I was told that I should first call SQLSetConnectAttr() with SQL_ATTR_CURRENT_CATALOG to get data back, to which I replied that FreeTDS does not need it.
Then I was told that SQLGetConnectAttr() with SQL_ATTR_CURRENT_CATALOG should return SQL_NO_DATA, but it does not; my code checks for ODBC errors after each API call.

My code, called no matter which driver is used, is this (pardon my messy C, I'm not that fluent):

void GetConnectedDBName(DB_DESC *desc, SQLHANDLE *connHandle)
{

SQLRETURN retcode;
SQLINTEGER charsNeeded = 0;
char *dbName;

if (DB.IsDebug())
{
if (desc->name)
{
fprintf(stderr, "gb.db.odbc.GetConnectedDBName: pre desc->name:'%s'.\n", desc->name);
} else {
fprintf(stderr, "gb.db.odbc.GetConnectedDBName: pre desc->name: NULL.\n");
}
}

if (desc->name)
{
GB.FreeString(POINTER(&desc->name));
}

//zxMarce: Attribute to fetch is SQL_ATTR_CURRENT_CATALOG
retcode = SQLGetConnectAttr(connHandle, SQL_ATTR_CURRENT_CATALOG, NULL, (SQLINTEGER) 0, (SQLINTEGER *) &charsNeeded);
if (SQL_SUCCEEDED(retcode))
{
dbName = malloc(charsNeeded++);
dbName[charsNeeded++] = 0;
retcode = SQLGetConnectAttr(connHandle, SQL_ATTR_CURRENT_CATALOG, dbName, charsNeeded, &charsNeeded);
if (SQL_SUCCEEDED(retcode))
{
desc->name = GB.NewZeroString(dbName);
} else {
reportODBCError("SQLGetConnectAttr SQL_ATTR_CURRENT_CATALOG (string)", connHandle, SQL_HANDLE_DBC);
}
} else {
reportODBCError("SQLGetConnectAttr SQL_ATTR_CURRENT_CATALOG (len)", connHandle, SQL_HANDLE_DBC);
}


if (DB.IsDebug())
{
if (desc->name)
{
fprintf(stderr, "gb.db.odbc.GetConnectedDBName: post dbName: '%s' desc->name (%d chars):'%s'.\n", dbName, (int)charsNeeded, desc->name);
} else {
fprintf(stderr, "gb.db.odbc.GetConnectedDBName: post desc->name: NULL.\n");
}
}

if (dbName)
{
free(dbName);
}

}

The routine reportODBCError() is never called. DB.IsDebug() is a flag to post or not low-level debugging info. GB.FreeString and GB.NewZeroString are Gambas 3 API calls to destroy and create Gambas strings.

zxMarce.

 All   Comments   Change History   Subversion Commits      Sort Order: Ascending order - Click to sort in descending order
Julien Nabet added a comment - 03/Feb/19 09:49 AM
So perhaps this patch may help:
diff --git a/OdbcConnection.cpp b/OdbcConnection.cpp
index cd27689..0afb9d7 100644
--- a/OdbcConnection.cpp
+++ b/OdbcConnection.cpp
@@ -2060,6 +2060,7 @@ SQLRETURN OdbcConnection::sqlGetConnectAttr(int attribute, SQLPOINTER ptr, int b
 
        case SQL_ATTR_CURRENT_CATALOG:
                string = databaseName;
+ value = SQL_NO_DATA;
                break;
 
        case SQL_LOGIN_TIMEOUT: // 103