Skip to content

Commit

Permalink
[AD-771] fix issue of JDBC not returning tables (#37)
Browse files Browse the repository at this point in the history
### Summary

<!--- General summary / title -->
Make JDBC return tables/columns to ODBC
### Description

<!--- Details of what you changed -->
* Tableau passes catalog, schema, table name, and table type as null pointers to SQLTables.
PowerBI passes catalog, schema, and table name as null pointers to SQLTables.

PowerBI passes column name as null pointers to SQLColumns.

Therefore, if null is passed in ODBC as table pattern, "%" needs to be passed as table pattern to JDBC.
Same thing with null being passed to ODBC as column name pattern.
### Related Issue

<!--- Link to issue where this is tracked -->
https://bitquill.atlassian.net/browse/AD-771

* [AD-771] fix merge issues

* [AD-771] resolve code review comments

* move comments for SQLTables and SQLColumns from odbc.h to odbc.cpp.
* refactor code to use `get_value_or` when retrieving values for table and column name
  • Loading branch information
alinaliBQ authored Jun 8, 2022
1 parent afaf7d7 commit 5ebaab9
Show file tree
Hide file tree
Showing 2 changed files with 45 additions and 9 deletions.
37 changes: 35 additions & 2 deletions src/odbc-test/src/meta_queries_test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -767,13 +767,12 @@ BOOST_AUTO_TEST_CASE(TestDataTypes) {
Connect(dsnConnectionString);

SQLCHAR table[] = "meta_queries_test_001";
SQLCHAR column[] = "%";
SQLCHAR empty[] = "";
SQLCHAR *schemaName = (SQLCHAR *)databaseName.c_str();


SQLRETURN ret = SQLColumns(stmt, nullptr, 0, schemaName, SQL_NTS, table,
SQL_NTS, column, SQL_NTS);
SQL_NTS, nullptr, 0);

if (!SQL_SUCCEEDED(ret))
BOOST_FAIL(GetOdbcErrorMessage(SQL_HANDLE_STMT, stmt));
Expand Down Expand Up @@ -988,6 +987,7 @@ BOOST_AUTO_TEST_CASE(TestGetDataWithTablesReturnsMany) {
SQLCHAR empty[] = "";
SQLCHAR table[] = "%";

// test with table passed as "%"
SQLRETURN ret = SQLTables(stmt, empty, SQL_NTS, nullptr, 0, table,
SQL_NTS, empty, SQL_NTS);

Expand All @@ -1002,6 +1002,23 @@ BOOST_AUTO_TEST_CASE(TestGetDataWithTablesReturnsMany) {
BOOST_CHECK(count > 1);

BOOST_REQUIRE_EQUAL(ret, SQL_NO_DATA);

// test with table passed as nullptr
ret =
SQLTables(stmt, empty, SQL_NTS, nullptr, 0, nullptr, 0,
empty, SQL_NTS);

if (!SQL_SUCCEEDED(ret))
BOOST_FAIL(GetOdbcErrorMessage(SQL_HANDLE_STMT, stmt));

count = 0;
do {
ret = SQLFetch(stmt);
count++;
} while (SQL_SUCCEEDED(ret));
BOOST_CHECK(count > 1);

BOOST_REQUIRE_EQUAL(ret, SQL_NO_DATA);
}

BOOST_AUTO_TEST_CASE(TestGetDataWithColumnsReturnsOneFromLocalServer) {
Expand Down Expand Up @@ -1090,6 +1107,7 @@ BOOST_AUTO_TEST_CASE(TestGetDataWithColumnsReturnsMany) {
SQLCHAR table[] = "meta_queries_test_002";
SQLCHAR column[] = "%";

// test with column name "%"
SQLRETURN ret =
SQLColumns(stmt, nullptr, 0, nullptr, 0, table,
SQL_NTS, column, SQL_NTS);
Expand All @@ -1105,6 +1123,21 @@ BOOST_AUTO_TEST_CASE(TestGetDataWithColumnsReturnsMany) {
BOOST_CHECK(count > 1);

BOOST_REQUIRE_EQUAL(ret, SQL_NO_DATA);

// test with column name passed as nullptr
ret = SQLColumns(stmt, nullptr, 0, nullptr, 0, table, SQL_NTS, nullptr, 0);

if (!SQL_SUCCEEDED(ret))
BOOST_FAIL(GetOdbcErrorMessage(SQL_HANDLE_STMT, stmt));

count = 0;
do {
ret = SQLFetch(stmt);
count++;
} while (SQL_SUCCEEDED(ret));
BOOST_CHECK(count > 1);

BOOST_REQUIRE_EQUAL(ret, SQL_NO_DATA);
}

BOOST_AUTO_TEST_CASE(TestGetDataWithPrimaryKeysReturnsOneFromLocalServer) {
Expand Down
17 changes: 10 additions & 7 deletions src/odbc/src/odbc.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -625,13 +625,13 @@ SQLRETURN SQLNumResultCols(SQLHSTMT stmt, SQLSMALLINT* columnNum) {
return statement->GetDiagnosticRecords().GetReturnCode();
}

/** If NULL tableName is passed, it will automatically be converted to "%". */
SQLRETURN SQLTables(SQLHSTMT stmt, SQLCHAR* catalogName,
SQLSMALLINT catalogNameLen, SQLCHAR* schemaName,
SQLSMALLINT schemaNameLen, SQLCHAR* tableName,
SQLSMALLINT tableNameLen, SQLCHAR* tableType,
SQLSMALLINT tableTypeLen) {
using odbc::Statement;
using odbc::utility::SqlStringToString;
using odbc::utility::SqlStringToOptString;

LOG_DEBUG_MSG("SQLTables called");
Expand All @@ -647,7 +647,7 @@ SQLRETURN SQLTables(SQLHSTMT stmt, SQLCHAR* catalogName,

boost::optional< std::string > catalog = SqlStringToOptString(catalogName, catalogNameLen);
boost::optional< std::string > schema = SqlStringToOptString(schemaName, schemaNameLen);
std::string table = SqlStringToString(tableName, tableNameLen);
std::string table = SqlStringToOptString(tableName, tableNameLen).get_value_or("%");
boost::optional< std::string > tableTypeStr = SqlStringToOptString(tableType, tableTypeLen);

LOG_INFO_MSG("catalog: " << catalog);
Expand All @@ -662,13 +662,14 @@ SQLRETURN SQLTables(SQLHSTMT stmt, SQLCHAR* catalogName,
return statement->GetDiagnosticRecords().GetReturnCode();
}

/** If NULL tableName is passed, it will automatically be converted to "%".
* If NULL columnName is passed, it will automatically be converted to "%". */
SQLRETURN SQLColumns(SQLHSTMT stmt, SQLCHAR* catalogName,
SQLSMALLINT catalogNameLen, SQLCHAR* schemaName,
SQLSMALLINT schemaNameLen, SQLCHAR* tableName,
SQLSMALLINT tableNameLen, SQLCHAR* columnName,
SQLSMALLINT columnNameLen) {
using odbc::Statement;
using odbc::utility::SqlStringToString;
using odbc::utility::SqlStringToOptString;

LOG_DEBUG_MSG("SQLColumns called");
Expand All @@ -682,12 +683,14 @@ SQLRETURN SQLColumns(SQLHSTMT stmt, SQLCHAR* catalogName,
return SQL_INVALID_HANDLE;
}

const boost::optional< std::string > catalog =
boost::optional< std::string > catalog =
SqlStringToOptString(catalogName, catalogNameLen);
const boost::optional< std::string > schema =
boost::optional< std::string > schema =
SqlStringToOptString(schemaName, schemaNameLen);
std::string table = SqlStringToString(tableName, tableNameLen);
std::string column = SqlStringToString(columnName, columnNameLen);
std::string table =
SqlStringToOptString(tableName, tableNameLen).get_value_or("%");
std::string column =
SqlStringToOptString(columnName, columnNameLen).get_value_or("%");

LOG_INFO_MSG("catalog: " << catalog.get_value_or(""));
LOG_INFO_MSG("schema: " << schema.get_value_or(""));
Expand Down

0 comments on commit 5ebaab9

Please sign in to comment.