Skip to content

Commit c255959

Browse files
committed
added testcases
1 parent 24af46e commit c255959

4 files changed

Lines changed: 215 additions & 0 deletions

File tree

google/cloud/odbc/integration_tests/odbc_driver_tests/catalog_test.cc

Lines changed: 82 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1016,6 +1016,88 @@ TEST(CatalogTest, ANSI_SQLPrimaryKeys_TableWithoutPrimaryKeys) {
10161016
EXPECT_EQ(Disconnect(conn), SQL_SUCCESS);
10171017
}
10181018

1019+
#ifndef BQ_DRIVER_INTEGRATION_TESTS
1020+
TEST(CatalogTest, SQLSpecialColumns_SQL_BEST_ROWID_TableWithPrimaryKeys) {
1021+
auto conn = std::make_shared<ODBCHandles>();
1022+
EXPECT_EQ(Connect(kDefaultConnectionString, conn), SQL_SUCCESS);
1023+
CreateTableDirect(conn, kTableWithPKSchema);
1024+
1025+
RowWiseResults special_columns = Catalog::GetSpecialColumns(
1026+
conn, SQL_BEST_ROWID, kDatasetName, kCatalogDatasetTableWithPK);
1027+
1028+
// existing driver returns an empty result set for SQL_BEST_ROWID.
1029+
EXPECT_TRUE(special_columns.empty());
1030+
1031+
EXPECT_EQ(Disconnect(conn), SQL_SUCCESS);
1032+
}
1033+
1034+
TEST(CatalogTest, SQLSpecialColumns_SQL_BEST_ROWID_TableWithoutPrimaryKeys) {
1035+
auto conn = std::make_shared<ODBCHandles>();
1036+
EXPECT_EQ(Connect(kDefaultConnectionString, conn), SQL_SUCCESS);
1037+
CreateTableDirect(conn, kTableWithOutPKSchema);
1038+
1039+
RowWiseResults special_columns = Catalog::GetSpecialColumns(
1040+
conn, SQL_BEST_ROWID, kDatasetName, kCatalogDatasetTableWithoutPK);
1041+
1042+
EXPECT_TRUE(special_columns.empty());
1043+
EXPECT_EQ(Disconnect(conn), SQL_SUCCESS);
1044+
}
1045+
1046+
TEST(CatalogTest, SQLSpecialColumns_SQL_ROWVER) {
1047+
auto conn = std::make_shared<ODBCHandles>();
1048+
EXPECT_EQ(Connect(kDefaultConnectionString, conn), SQL_SUCCESS);
1049+
CreateTableDirect(conn, kTableWithPKSchema);
1050+
1051+
RowWiseResults special_columns = Catalog::GetSpecialColumns(
1052+
conn, SQL_ROWVER, kDatasetName, kCatalogDatasetTableWithPK);
1053+
1054+
EXPECT_TRUE(special_columns.empty());
1055+
EXPECT_EQ(Disconnect(conn), SQL_SUCCESS);
1056+
}
1057+
1058+
TEST(CatalogTest, ANSI_SQLSpecialColumns_SQL_BEST_ROWID_TableWithPrimaryKeys) {
1059+
auto conn = std::make_shared<ODBCHandles>();
1060+
EXPECT_EQ(Connect(kDefaultConnectionString, conn, true), SQL_SUCCESS);
1061+
CreateTableDirect(conn, kTableWithPKSchema, true);
1062+
1063+
RowWiseResults special_columns = Catalog::GetSpecialColumns(
1064+
conn, SQL_BEST_ROWID, kDatasetName, kCatalogDatasetTableWithPK,
1065+
SQL_SCOPE_SESSION, SQL_NO_NULLS, true);
1066+
1067+
// existing driver returns an empty result set for SQL_BEST_ROWID.
1068+
EXPECT_TRUE(special_columns.empty());
1069+
1070+
EXPECT_EQ(Disconnect(conn), SQL_SUCCESS);
1071+
}
1072+
1073+
TEST(CatalogTest,
1074+
ANSI_SQLSpecialColumns_SQL_BEST_ROWID_TableWithoutPrimaryKeys) {
1075+
auto conn = std::make_shared<ODBCHandles>();
1076+
EXPECT_EQ(Connect(kDefaultConnectionString, conn, true), SQL_SUCCESS);
1077+
CreateTableDirect(conn, kTableWithOutPKSchema, true);
1078+
1079+
RowWiseResults special_columns = Catalog::GetSpecialColumns(
1080+
conn, SQL_BEST_ROWID, kDatasetName, kCatalogDatasetTableWithoutPK,
1081+
SQL_SCOPE_SESSION, SQL_NO_NULLS, true);
1082+
1083+
EXPECT_TRUE(special_columns.empty());
1084+
EXPECT_EQ(Disconnect(conn), SQL_SUCCESS);
1085+
}
1086+
1087+
TEST(CatalogTest, ANSI_SQLSpecialColumns_SQL_ROWVER) {
1088+
auto conn = std::make_shared<ODBCHandles>();
1089+
EXPECT_EQ(Connect(kDefaultConnectionString, conn, true), SQL_SUCCESS);
1090+
CreateTableDirect(conn, kTableWithPKSchema, true);
1091+
1092+
RowWiseResults special_columns = Catalog::GetSpecialColumns(
1093+
conn, SQL_ROWVER, kDatasetName, kCatalogDatasetTableWithPK,
1094+
SQL_SCOPE_SESSION, SQL_NO_NULLS, true);
1095+
1096+
EXPECT_TRUE(special_columns.empty());
1097+
EXPECT_EQ(Disconnect(conn), SQL_SUCCESS);
1098+
}
1099+
#endif // BQ_DRIVER_INTEGRATION_TESTS
1100+
10191101
////////////////////////////////////////////////////////////////
10201102
// TODO(b/360994080): SQLForeignKeys is not implemented
10211103
// correctly by existing Driver. Move all SQLForeignKeys function

google/cloud/odbc/integration_tests/odbc_driver_tests/statement_test.cc

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -889,6 +889,35 @@ TEST(StatementTest, SQLPrimaryKeys_VerifyMetadata) {
889889
EXPECT_EQ(Disconnect(conn), SQL_SUCCESS);
890890
}
891891

892+
#ifndef BQ_DRIVER_INTEGRATION_TESTS
893+
TEST(StatementTest, SQLSpecialColumns_VerifyMetadata) {
894+
auto conn = std::make_shared<ODBCHandles>();
895+
ASSERT_EQ(Connect(kDefaultConnectionString, conn), SQL_SUCCESS);
896+
897+
SQLRETURN ret = SQLSpecialColumns(
898+
conn->hstmt, SQL_BEST_ROWID, (SQLCHAR*)"bigquery-devtools-drivers",
899+
SQL_NTS, (SQLCHAR*)"INTEGRATION_TESTS", SQL_NTS, (SQLCHAR*)"Test_Table",
900+
SQL_NTS, SQL_SCOPE_SESSION, SQL_NULLABLE);
901+
ASSERT_TRUE(SQL_SUCCEEDED(ret));
902+
903+
ExpectedColMetadata expected[] = {
904+
{"SCOPE", SQL_SMALLINT, 5, 0, SQL_NULLABLE},
905+
{"COLUMN_NAME", SQL_WVARCHAR, 128, 0, SQL_NO_NULLS},
906+
{"DATA_TYPE", SQL_SMALLINT, 5, 0, SQL_NO_NULLS},
907+
{"TYPE_NAME", SQL_WVARCHAR, 128, 0, SQL_NO_NULLS},
908+
{"COLUMN_SIZE", SQL_INTEGER, 10, 0, SQL_NULLABLE},
909+
{"BUFFER_LENGTH", SQL_INTEGER, 10, 0, SQL_NULLABLE},
910+
{"DECIMAL_DIGITS", SQL_SMALLINT, 5, 0, SQL_NULLABLE},
911+
{"PSEUDO_COLUMN", SQL_SMALLINT, 5, 0, SQL_NULLABLE},
912+
};
913+
914+
VerifyResultSetMetadata(
915+
conn->hstmt, static_cast<SQLSMALLINT>(std::size(expected)), expected);
916+
917+
EXPECT_EQ(Disconnect(conn), SQL_SUCCESS);
918+
}
919+
#endif // BQ_DRIVER_INTEGRATION_TESTS
920+
892921
TEST(StatementTest, SQLForeignKeys_VerifyMetadata) {
893922
auto conn = std::make_shared<ODBCHandles>();
894923
ASSERT_EQ(Connect(kDefaultConnectionString, conn), SQL_SUCCESS);

google/cloud/odbc/testing/odbc_utils/catalog.cc

Lines changed: 97 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -403,6 +403,103 @@ RowWiseResults Catalog::GetPrimaryKeys(std::shared_ptr<ODBCHandles> const& conn,
403403
return results;
404404
}
405405

406+
RowWiseResults Catalog::GetSpecialColumns(
407+
std::shared_ptr<ODBCHandles> const& conn, SQLUSMALLINT identifier_type,
408+
std::string const& dataset, std::string const& table, SQLUSMALLINT scope,
409+
SQLUSMALLINT nullable, bool use_ansi) {
410+
SQLRETURN status;
411+
int const res_cols = 8;
412+
RowWiseResults results;
413+
414+
if (dataset.empty() || table.empty()) {
415+
return results;
416+
}
417+
418+
std::optional<std::string> project_id_opt = ::google::cloud::internal::GetEnv(
419+
"CPP_BIGQUERY_ODBC_TEST_GOOGLE_CLOUD_PROJECT");
420+
auto catalog_name =
421+
(!project_id_opt.has_value()) ? kCatalogName : project_id_opt.value();
422+
423+
status = SQLSetStmtAttr(conn->hstmt, SQL_ATTR_METADATA_ID,
424+
ToSqlPointer(SQL_FALSE), 0);
425+
CheckError(status, "SQLSetStmtAttr", conn);
426+
427+
TestingDataBuffer columns[res_cols];
428+
429+
// 1. SCOPE (Smallint)
430+
// 2. COLUMN_NAME (Varchar)
431+
// 3. DATA_TYPE (Smallint)
432+
// 4. TYPE_NAME (Varchar)
433+
// 5. COLUMN_SIZE (Integer)
434+
// 6. BUFFER_LENGTH (Integer)
435+
// 7. DECIMAL_DIGITS (Smallint)
436+
// 8. PSEUDO_COLUMN (Smallint)
437+
for (int i = 0; i < res_cols; i++) {
438+
if (i == 0 || i == 2 || i == 6 || i == 7) {
439+
columns[i].target_type = SQL_C_SSHORT;
440+
} else if (i == 4 || i == 5) {
441+
columns[i].target_type = SQL_C_SLONG;
442+
} else {
443+
columns[i].target_type = SQL_C_CHAR;
444+
}
445+
status = SQLBindCol(conn->hstmt, static_cast<SQLUSMALLINT>(i + 1),
446+
columns[i].target_type, columns[i].target_value,
447+
columns[i].buffer_length, &(columns[i].str_len));
448+
CheckError(status, "SQLBindCol", conn);
449+
}
450+
451+
if (use_ansi) {
452+
status = SQLSpecialColumnsA(
453+
conn->hstmt, identifier_type,
454+
const_cast<SQLCHAR*>(
455+
reinterpret_cast<const SQLCHAR*>(catalog_name.c_str())),
456+
static_cast<SQLSMALLINT>(catalog_name.length()),
457+
const_cast<SQLCHAR*>(reinterpret_cast<const SQLCHAR*>(dataset.c_str())),
458+
static_cast<SQLSMALLINT>(dataset.length()),
459+
const_cast<SQLCHAR*>(reinterpret_cast<const SQLCHAR*>(table.c_str())),
460+
static_cast<SQLSMALLINT>(table.length()), scope, nullable);
461+
} else {
462+
status = SQLSpecialColumns(
463+
conn->hstmt, identifier_type,
464+
const_cast<SQLCHAR*>(
465+
reinterpret_cast<const SQLCHAR*>(catalog_name.c_str())),
466+
static_cast<SQLSMALLINT>(catalog_name.length()),
467+
const_cast<SQLCHAR*>(reinterpret_cast<const SQLCHAR*>(dataset.c_str())),
468+
static_cast<SQLSMALLINT>(dataset.length()),
469+
const_cast<SQLCHAR*>(reinterpret_cast<const SQLCHAR*>(table.c_str())),
470+
static_cast<SQLSMALLINT>(table.length()), scope, nullable);
471+
}
472+
CheckError(status, "SQLSpecialColumns", conn, use_ansi);
473+
474+
while (true) {
475+
Row row_result;
476+
status = SQLFetch(conn->hstmt);
477+
if (status == SQL_NO_DATA) {
478+
break;
479+
}
480+
if (!SQL_SUCCEEDED(status)) {
481+
CheckError(status, "SQLFetch", conn);
482+
}
483+
for (int i = 0; i < res_cols; i++) {
484+
if (columns[i].str_len == SQL_NULL_DATA) {
485+
} else if (i == 0 || i == 2 || i == 6 || i == 7) {
486+
row_result.insert(
487+
{i + 1, std::to_string(*reinterpret_cast<SQLSMALLINT*>(
488+
columns[i].target_value))});
489+
} else if (i == 4 || i == 5) {
490+
row_result.insert({i + 1, std::to_string(*reinterpret_cast<SQLINTEGER*>(
491+
columns[i].target_value))});
492+
} else {
493+
row_result.insert(
494+
{i + 1, reinterpret_cast<char*>(columns[i].target_value)});
495+
}
496+
}
497+
results.emplace_back(row_result);
498+
}
499+
500+
return results;
501+
}
502+
406503
RowWiseResults Catalog::GetForeignKeys(std::shared_ptr<ODBCHandles> const& conn,
407504
std::string const& dataset,
408505
std::string const& pk_table,

google/cloud/odbc/testing/odbc_utils/catalog.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -147,6 +147,13 @@ class Catalog {
147147
std::string const& table = "",
148148
bool use_ansi = false);
149149

150+
// Uses the SQLSpecialColumns API to fetch special columns in a dataset.
151+
static RowWiseResults GetSpecialColumns(
152+
std::shared_ptr<ODBCHandles> const& conn, SQLUSMALLINT identifier_type,
153+
std::string const& dataset = "", std::string const& table = "",
154+
SQLUSMALLINT scope = SQL_SCOPE_SESSION,
155+
SQLUSMALLINT nullable = SQL_NO_NULLS, bool use_ansi = false);
156+
150157
// Uses the SQLForeignKeys API to fetch foreign keys in a dataset.
151158
static RowWiseResults GetForeignKeys(std::shared_ptr<ODBCHandles> const& conn,
152159
std::string const& dataset = "",

0 commit comments

Comments
 (0)