From d88f5c04a0a8b9a6d1bc07210867067b97b7cd15 Mon Sep 17 00:00:00 2001 From: "Alina (Xi) Li" Date: Wed, 6 Aug 2025 11:22:48 -0700 Subject: [PATCH 1/6] Add SQLGetFunctions test in-progress --- .../flight/sql/odbc/tests/CMakeLists.txt | 1 + .../sql/odbc/tests/get_functions_test.cc | 143 ++++++++++++++++++ 2 files changed, 144 insertions(+) create mode 100644 cpp/src/arrow/flight/sql/odbc/tests/get_functions_test.cc diff --git a/cpp/src/arrow/flight/sql/odbc/tests/CMakeLists.txt b/cpp/src/arrow/flight/sql/odbc/tests/CMakeLists.txt index 606b3cb7e4a..2dc719fa05e 100644 --- a/cpp/src/arrow/flight/sql/odbc/tests/CMakeLists.txt +++ b/cpp/src/arrow/flight/sql/odbc/tests/CMakeLists.txt @@ -35,6 +35,7 @@ add_arrow_test(flight_sql_odbc_test connection_attr_test.cc connection_info_test.cc errors_test.cc + get_functions_test.cc statement_attr_test.cc statement_test.cc tables_test.cc diff --git a/cpp/src/arrow/flight/sql/odbc/tests/get_functions_test.cc b/cpp/src/arrow/flight/sql/odbc/tests/get_functions_test.cc new file mode 100644 index 00000000000..5e1a170103d --- /dev/null +++ b/cpp/src/arrow/flight/sql/odbc/tests/get_functions_test.cc @@ -0,0 +1,143 @@ +// Licensed to the Apache Software Foundation (ASF) under one +// or more contributor license agreements. See the NOTICE file +// distributed with this work for additional information +// regarding copyright ownership. The ASF licenses this file +// to you under the Apache License, Version 2.0 (the +// "License"); you may not use this file except in compliance +// with the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, +// software distributed under the License is distributed on an +// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. See the License for the +// specific language governing permissions and limitations +// under the License. +#include "arrow/flight/sql/odbc/tests/odbc_test_suite.h" + +#ifdef _WIN32 +# include +#endif + +#include +#include +#include + +#include "gtest/gtest.h" + +namespace arrow::flight::sql::odbc { + +// -AL- todo add tests for SQLGetFunctions + // -AL- [ ] test "all functions" with ODBC3 + // [ ] test singular functions with ODBC3 + // [ ] test singular functions with ODBC2 + // [ ] test "all functions" with ODBC2 + +// Supported functions: +/* +SQL_API_SQLALLOCHANDLE +SQL_API_SQLBINDCOL +SQL_API_SQLGETDIAGFIELD +SQL_API_SQLCLOSECURSOR +SQL_API_SQLGETDIAGREC +SQL_API_SQLCOLATTRIBUTE +SQL_API_SQLGETENVATTR +SQL_API_SQLCONNECT +SQL_API_SQLGETFUNCTIONS +SQL_API_SQLGETINFO +SQL_API_SQLGETSTMTATTR +SQL_API_SQLDESCRIBECOL //-AL- this will be really implemented after Rob implements the func +// -AL- not sure if driver returning IM001 in diag will change SQLGetFunctions return result or not +SQL_API_SQLGETTYPEINFO +SQL_API_SQLDISCONNECT +SQL_API_SQLNUMRESULTCOLS +SQL_API_SQLPREPARE +SQL_API_SQLEXECDIRECT +SQL_API_SQLPUTDATA +SQL_API_SQLEXECUTE +SQL_API_SQLROWCOUNT +SQL_API_SQLFETCH +SQL_API_SQLSETCONNECTATTR +SQL_API_SQLFETCHSCROLL +SQL_API_SQLFREEHANDLE +SQL_API_SQLFREESTMT +SQL_API_SQLGETCONNECTATTR +SQL_API_SQLSETENVATTR +SQL_API_SQLSETSTMTATTR +SQL_API_SQLGETDATA +SQL_API_SQLCOLUMNS +SQL_API_SQLTABLES + +SQL_API_SQLNATIVESQL + +SQL_API_SQLDRIVERCONNECT + +SQL_API_SQLMORERESULTS + +// ODBC 2.0 APIs +SQL_API_SQLSETSTMTOPTION +SQL_API_SQLGETSTMTOPTION +SQL_API_SQLSETCONNECTOPTION +SQL_API_SQLGETCONNECTOPTION + +SQL_API_SQLALLOCCONNECT +SQL_API_SQLALLOCENV +SQL_API_SQLALLOCSTMT +SQL_API_SQLFREEENV +SQL_API_SQLFREESTMT +SQL_API_SQLFREECONNECT +*/ +// -AL- Not supported functions: +// (May return supported? need to double check) +/* +SQL_API_SQLGETDESCFIELD +SQL_API_SQLGETDESCREC +SQL_API_SQLCANCEL +SQL_API_SQLCOPYDESC +SQL_API_SQLDATASOURCES +SQL_API_SQLPARAMDATA +SQL_API_SQLDRIVERS +SQL_API_SQLENDTRAN +SQL_API_SQLSETCURSORNAME +SQL_API_SQLSETDESCFIELD +SQL_API_SQLSETDESCREC +SQL_API_SQLGETCURSORNAME + +SQL_API_SQLSTATISTICS +SQL_API_SQLSPECIALCOLUMNS + +SQL_API_SQLBINDPARAMETER +SQL_API_SQLBROWSECONNECT + +SQL_API_SQLNUMPARAMS +SQL_API_SQLBULKOPERATIONS +SQL_API_SQLPRIMARYKEYS +SQL_API_SQLCOLUMNPRIVILEGES +SQL_API_SQLPROCEDURECOLUMNS +SQL_API_SQLDESCRIBEPARAM +SQL_API_SQLPROCEDURES +SQL_API_SQLSETPOS +SQL_API_SQLFOREIGNKEYS +SQL_API_SQLTABLEPRIVILEGES + +// Note: SQLCancelHandle and SQLCompleteAsync are 3.8 only. +*/ + +TYPED_TEST(FlightSQLODBCTestBase, TestSQLGetFunctions) { + // -AL- todo driver manager implements SQLGetFunctions. + // -AL- this test verifies Driver manager is able to detect functions and return correct + // values for SQLGetFunctions + this->connect(); + + SQLUSMALLINT supported_functions[SQL_API_ODBC3_ALL_FUNCTIONS_SIZE]; + SQLRETURN ret = SQLGetFunctions(this->conn, SQL_API_ODBC3_ALL_FUNCTIONS, supported_functions); + + EXPECT_EQ(ret, SQL_SUCCESS); + + + + this->disconnect(); +} + +} // namespace arrow::flight::sql::odbc From e19f99bd819f26e929903e5a6373ba8cb85f13ed Mon Sep 17 00:00:00 2001 From: "Alina (Xi) Li" Date: Wed, 6 Aug 2025 11:52:37 -0700 Subject: [PATCH 2/6] find which api fails Add TestSQLGetFunctionsCheckSQLTables. * Using `SQL_FUNC_EXISTS` macro fixed the issue of `api_exists` not read correctly --- .../sql/odbc/tests/get_functions_test.cc | 61 ++++++++++++++++--- 1 file changed, 53 insertions(+), 8 deletions(-) diff --git a/cpp/src/arrow/flight/sql/odbc/tests/get_functions_test.cc b/cpp/src/arrow/flight/sql/odbc/tests/get_functions_test.cc index 5e1a170103d..f4e36c32a41 100644 --- a/cpp/src/arrow/flight/sql/odbc/tests/get_functions_test.cc +++ b/cpp/src/arrow/flight/sql/odbc/tests/get_functions_test.cc @@ -47,21 +47,20 @@ SQL_API_SQLCONNECT SQL_API_SQLGETFUNCTIONS SQL_API_SQLGETINFO SQL_API_SQLGETSTMTATTR -SQL_API_SQLDESCRIBECOL //-AL- this will be really implemented after Rob implements the func +SQL_API_SQLDESCRIBECOL +//-AL- SQLDescribeCol will be implemented afterwards. // -AL- not sure if driver returning IM001 in diag will change SQLGetFunctions return result or not SQL_API_SQLGETTYPEINFO SQL_API_SQLDISCONNECT SQL_API_SQLNUMRESULTCOLS SQL_API_SQLPREPARE SQL_API_SQLEXECDIRECT -SQL_API_SQLPUTDATA SQL_API_SQLEXECUTE SQL_API_SQLROWCOUNT SQL_API_SQLFETCH SQL_API_SQLSETCONNECTATTR SQL_API_SQLFETCHSCROLL SQL_API_SQLFREEHANDLE -SQL_API_SQLFREESTMT SQL_API_SQLGETCONNECTATTR SQL_API_SQLSETENVATTR SQL_API_SQLSETSTMTATTR @@ -91,6 +90,7 @@ SQL_API_SQLFREECONNECT // -AL- Not supported functions: // (May return supported? need to double check) /* +SQL_API_SQLPUTDATA SQL_API_SQLGETDESCFIELD SQL_API_SQLGETDESCREC SQL_API_SQLCANCEL @@ -125,17 +125,62 @@ SQL_API_SQLTABLEPRIVILEGES */ TYPED_TEST(FlightSQLODBCTestBase, TestSQLGetFunctions) { - // -AL- todo driver manager implements SQLGetFunctions. - // -AL- this test verifies Driver manager is able to detect functions and return correct - // values for SQLGetFunctions + // Verify driver manager return values for SQLGetFunctions this->connect(); - SQLUSMALLINT supported_functions[SQL_API_ODBC3_ALL_FUNCTIONS_SIZE]; - SQLRETURN ret = SQLGetFunctions(this->conn, SQL_API_ODBC3_ALL_FUNCTIONS, supported_functions); + SQLUSMALLINT api_exists[SQL_API_ODBC3_ALL_FUNCTIONS_SIZE]; + const std::vector supported_functions = { + SQL_API_SQLALLOCHANDLE, SQL_API_SQLBINDCOL, SQL_API_SQLGETDIAGFIELD, + SQL_API_SQLCLOSECURSOR, SQL_API_SQLGETDIAGREC, SQL_API_SQLCOLATTRIBUTE, + SQL_API_SQLGETENVATTR, SQL_API_SQLCONNECT, SQL_API_SQLGETFUNCTIONS, + SQL_API_SQLGETINFO, SQL_API_SQLGETSTMTATTR, + // SQL_API_SQLDESCRIBECOL, // -AL- todo enable once SQLDescribeCol is implemented. + SQL_API_SQLGETTYPEINFO, SQL_API_SQLDISCONNECT, SQL_API_SQLNUMRESULTCOLS, + SQL_API_SQLPREPARE, SQL_API_SQLEXECDIRECT, SQL_API_SQLEXECUTE, + SQL_API_SQLROWCOUNT, SQL_API_SQLFETCH, SQL_API_SQLSETCONNECTATTR, + SQL_API_SQLFETCHSCROLL, SQL_API_SQLFREEHANDLE, SQL_API_SQLFREESTMT, + SQL_API_SQLGETCONNECTATTR, SQL_API_SQLSETENVATTR, SQL_API_SQLSETSTMTATTR, + SQL_API_SQLGETDATA, SQL_API_SQLCOLUMNS, SQL_API_SQLTABLES, SQL_API_SQLNATIVESQL, + SQL_API_SQLDRIVERCONNECT, SQL_API_SQLMORERESULTS, + + // ODBC 2.0 APIs + SQL_API_SQLSETSTMTOPTION, SQL_API_SQLGETSTMTOPTION, SQL_API_SQLSETCONNECTOPTION, + SQL_API_SQLGETCONNECTOPTION, SQL_API_SQLALLOCCONNECT, SQL_API_SQLALLOCENV, + SQL_API_SQLALLOCSTMT, SQL_API_SQLFREEENV, SQL_API_SQLFREECONNECT}; + SQLRETURN ret = SQLGetFunctions(this->conn, SQL_API_ODBC3_ALL_FUNCTIONS, api_exists); EXPECT_EQ(ret, SQL_SUCCESS); + for (int api : supported_functions) { + EXPECT_EQ(SQL_FUNC_EXISTS(api_exists, api), SQL_TRUE); + } + + this->disconnect(); +} + +TEST_F(FlightSQLODBCMockTestBase, TestSQLGetFunctionsTEMP) { + // -AL- use this test to find singular values. + this->connect(); + + SQLUSMALLINT sql_tables_exists; + SQLRETURN ret = SQLGetFunctions(this->conn, SQL_API_SQLTABLES, &sql_tables_exists); + + EXPECT_EQ(ret, SQL_SUCCESS); + + EXPECT_EQ(sql_tables_exists, SQL_TRUE); + + this->disconnect(); +} + +TYPED_TEST(FlightSQLODBCTestBase, TestSQLGetFunctionsCheckSQLTables) { + this->connect(); + + SQLUSMALLINT sql_tables_exists; + SQLRETURN ret = SQLGetFunctions(this->conn, SQL_API_SQLTABLES, &sql_tables_exists); + + EXPECT_EQ(ret, SQL_SUCCESS); + EXPECT_EQ(sql_tables_exists, SQL_TRUE); this->disconnect(); } From b3806a90f6d0dab153ce1c34e22ca262b0a7e432 Mon Sep 17 00:00:00 2001 From: "Alina (Xi) Li" Date: Wed, 6 Aug 2025 13:48:15 -0700 Subject: [PATCH 3/6] Fix SQLGetTypeInfo naming for ODBC ver 2 tests --- .../arrow/flight/sql/odbc/tests/type_info_test.cc | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/cpp/src/arrow/flight/sql/odbc/tests/type_info_test.cc b/cpp/src/arrow/flight/sql/odbc/tests/type_info_test.cc index e642575210b..916befb774d 100644 --- a/cpp/src/arrow/flight/sql/odbc/tests/type_info_test.cc +++ b/cpp/src/arrow/flight/sql/odbc/tests/type_info_test.cc @@ -521,7 +521,7 @@ TEST_F(FlightSQLODBCMockTestBase, TestSQLGetTypeInfoAllTypes) { this->disconnect(); } -TEST_F(FlightSQLODBCMockTestBase, TestSQLGetTypeInfoAllTypesVer2) { +TEST_F(FlightSQLODBCMockTestBase, TestSQLGetTypeInfoAllTypesODBCVer2) { this->connect(SQL_OV_ODBC2); SQLRETURN ret = SQLGetTypeInfo(this->stmt, SQL_ALL_TYPES); @@ -1546,7 +1546,7 @@ TEST_F(FlightSQLODBCMockTestBase, TestSQLGetTypeInfoSQLDate) { this->disconnect(); } -TEST_F(FlightSQLODBCMockTestBase, TestSQLGetTypeInfoDateVer2) { +TEST_F(FlightSQLODBCMockTestBase, TestSQLGetTypeInfoDateODBCVer2) { this->connect(SQL_OV_ODBC2); SQLRETURN ret = SQLGetTypeInfo(this->stmt, SQL_DATE); @@ -1584,7 +1584,7 @@ TEST_F(FlightSQLODBCMockTestBase, TestSQLGetTypeInfoDateVer2) { this->disconnect(); } -TEST_F(FlightSQLODBCMockTestBase, TestSQLGetTypeInfoSQLTypeDateVer2) { +TEST_F(FlightSQLODBCMockTestBase, TestSQLGetTypeInfoSQLTypeDateODBCVer2) { this->connect(SQL_OV_ODBC2); // Pass ODBC Ver 3 data type @@ -1675,7 +1675,7 @@ TEST_F(FlightSQLODBCMockTestBase, TestSQLGetTypeInfoSQLTime) { this->disconnect(); } -TEST_F(FlightSQLODBCMockTestBase, TestSQLGetTypeInfoTimeVer2) { +TEST_F(FlightSQLODBCMockTestBase, TestSQLGetTypeInfoTimeODBCVer2) { this->connect(SQL_OV_ODBC2); SQLRETURN ret = SQLGetTypeInfo(this->stmt, SQL_TIME); @@ -1713,7 +1713,7 @@ TEST_F(FlightSQLODBCMockTestBase, TestSQLGetTypeInfoTimeVer2) { this->disconnect(); } -TEST_F(FlightSQLODBCMockTestBase, TestSQLGetTypeInfoSQLTypeTimeVer2) { +TEST_F(FlightSQLODBCMockTestBase, TestSQLGetTypeInfoSQLTypeTimeODBCVer2) { this->connect(SQL_OV_ODBC2); // Pass ODBC Ver 3 data type @@ -1804,7 +1804,7 @@ TEST_F(FlightSQLODBCMockTestBase, TestSQLGetTypeInfoSQLTimestamp) { this->disconnect(); } -TEST_F(FlightSQLODBCMockTestBase, TestSQLGetTypeInfoSQLTimestampVer2) { +TEST_F(FlightSQLODBCMockTestBase, TestSQLGetTypeInfoSQLTimestampODBCVer2) { this->connect(SQL_OV_ODBC2); SQLRETURN ret = SQLGetTypeInfo(this->stmt, SQL_TIMESTAMP); @@ -1842,7 +1842,7 @@ TEST_F(FlightSQLODBCMockTestBase, TestSQLGetTypeInfoSQLTimestampVer2) { this->disconnect(); } -TEST_F(FlightSQLODBCMockTestBase, TestSQLGetTypeInfoSQLTypeTimestampVer2) { +TEST_F(FlightSQLODBCMockTestBase, TestSQLGetTypeInfoSQLTypeTimestampODBCVer2) { this->connect(SQL_OV_ODBC2); // Pass ODBC Ver 3 data type From 5ad5d61028d4f6fe73559dcaee165bd09c7ecd49 Mon Sep 17 00:00:00 2001 From: "Alina (Xi) Li" Date: Wed, 6 Aug 2025 14:01:55 -0700 Subject: [PATCH 4/6] Add more tests Add unsupported API checks. Add `TestSQLGetFunctionsODBCVer2`. Add `TestSQLGetFunctionsCheckSingleAPI`. --- .../sql/odbc/tests/get_functions_test.cc | 293 +++++++++++------- 1 file changed, 175 insertions(+), 118 deletions(-) diff --git a/cpp/src/arrow/flight/sql/odbc/tests/get_functions_test.cc b/cpp/src/arrow/flight/sql/odbc/tests/get_functions_test.cc index f4e36c32a41..e505f3fbf67 100644 --- a/cpp/src/arrow/flight/sql/odbc/tests/get_functions_test.cc +++ b/cpp/src/arrow/flight/sql/odbc/tests/get_functions_test.cc @@ -28,125 +28,42 @@ namespace arrow::flight::sql::odbc { -// -AL- todo add tests for SQLGetFunctions - // -AL- [ ] test "all functions" with ODBC3 - // [ ] test singular functions with ODBC3 - // [ ] test singular functions with ODBC2 - // [ ] test "all functions" with ODBC2 - -// Supported functions: -/* -SQL_API_SQLALLOCHANDLE -SQL_API_SQLBINDCOL -SQL_API_SQLGETDIAGFIELD -SQL_API_SQLCLOSECURSOR -SQL_API_SQLGETDIAGREC -SQL_API_SQLCOLATTRIBUTE -SQL_API_SQLGETENVATTR -SQL_API_SQLCONNECT -SQL_API_SQLGETFUNCTIONS -SQL_API_SQLGETINFO -SQL_API_SQLGETSTMTATTR -SQL_API_SQLDESCRIBECOL -//-AL- SQLDescribeCol will be implemented afterwards. -// -AL- not sure if driver returning IM001 in diag will change SQLGetFunctions return result or not -SQL_API_SQLGETTYPEINFO -SQL_API_SQLDISCONNECT -SQL_API_SQLNUMRESULTCOLS -SQL_API_SQLPREPARE -SQL_API_SQLEXECDIRECT -SQL_API_SQLEXECUTE -SQL_API_SQLROWCOUNT -SQL_API_SQLFETCH -SQL_API_SQLSETCONNECTATTR -SQL_API_SQLFETCHSCROLL -SQL_API_SQLFREEHANDLE -SQL_API_SQLGETCONNECTATTR -SQL_API_SQLSETENVATTR -SQL_API_SQLSETSTMTATTR -SQL_API_SQLGETDATA -SQL_API_SQLCOLUMNS -SQL_API_SQLTABLES - -SQL_API_SQLNATIVESQL - -SQL_API_SQLDRIVERCONNECT - -SQL_API_SQLMORERESULTS - -// ODBC 2.0 APIs -SQL_API_SQLSETSTMTOPTION -SQL_API_SQLGETSTMTOPTION -SQL_API_SQLSETCONNECTOPTION -SQL_API_SQLGETCONNECTOPTION - -SQL_API_SQLALLOCCONNECT -SQL_API_SQLALLOCENV -SQL_API_SQLALLOCSTMT -SQL_API_SQLFREEENV -SQL_API_SQLFREESTMT -SQL_API_SQLFREECONNECT -*/ -// -AL- Not supported functions: -// (May return supported? need to double check) -/* -SQL_API_SQLPUTDATA -SQL_API_SQLGETDESCFIELD -SQL_API_SQLGETDESCREC -SQL_API_SQLCANCEL -SQL_API_SQLCOPYDESC -SQL_API_SQLDATASOURCES -SQL_API_SQLPARAMDATA -SQL_API_SQLDRIVERS -SQL_API_SQLENDTRAN -SQL_API_SQLSETCURSORNAME -SQL_API_SQLSETDESCFIELD -SQL_API_SQLSETDESCREC -SQL_API_SQLGETCURSORNAME - -SQL_API_SQLSTATISTICS -SQL_API_SQLSPECIALCOLUMNS - -SQL_API_SQLBINDPARAMETER -SQL_API_SQLBROWSECONNECT - -SQL_API_SQLNUMPARAMS -SQL_API_SQLBULKOPERATIONS -SQL_API_SQLPRIMARYKEYS -SQL_API_SQLCOLUMNPRIVILEGES -SQL_API_SQLPROCEDURECOLUMNS -SQL_API_SQLDESCRIBEPARAM -SQL_API_SQLPROCEDURES -SQL_API_SQLSETPOS -SQL_API_SQLFOREIGNKEYS -SQL_API_SQLTABLEPRIVILEGES - -// Note: SQLCancelHandle and SQLCompleteAsync are 3.8 only. -*/ - -TYPED_TEST(FlightSQLODBCTestBase, TestSQLGetFunctions) { +TYPED_TEST(FlightSQLODBCTestBase, TestSQLGetFunctionsAllFunctions) { // Verify driver manager return values for SQLGetFunctions this->connect(); SQLUSMALLINT api_exists[SQL_API_ODBC3_ALL_FUNCTIONS_SIZE]; const std::vector supported_functions = { SQL_API_SQLALLOCHANDLE, SQL_API_SQLBINDCOL, SQL_API_SQLGETDIAGFIELD, - SQL_API_SQLCLOSECURSOR, SQL_API_SQLGETDIAGREC, SQL_API_SQLCOLATTRIBUTE, - SQL_API_SQLGETENVATTR, SQL_API_SQLCONNECT, SQL_API_SQLGETFUNCTIONS, + SQL_API_SQLCANCEL, SQL_API_SQLCLOSECURSOR, SQL_API_SQLGETDIAGREC, + SQL_API_SQLCOLATTRIBUTE, SQL_API_SQLGETENVATTR, SQL_API_SQLCONNECT, SQL_API_SQLGETINFO, SQL_API_SQLGETSTMTATTR, // SQL_API_SQLDESCRIBECOL, // -AL- todo enable once SQLDescribeCol is implemented. SQL_API_SQLGETTYPEINFO, SQL_API_SQLDISCONNECT, SQL_API_SQLNUMRESULTCOLS, - SQL_API_SQLPREPARE, SQL_API_SQLEXECDIRECT, SQL_API_SQLEXECUTE, - SQL_API_SQLROWCOUNT, SQL_API_SQLFETCH, SQL_API_SQLSETCONNECTATTR, - SQL_API_SQLFETCHSCROLL, SQL_API_SQLFREEHANDLE, SQL_API_SQLFREESTMT, - SQL_API_SQLGETCONNECTATTR, SQL_API_SQLSETENVATTR, SQL_API_SQLSETSTMTATTR, - SQL_API_SQLGETDATA, SQL_API_SQLCOLUMNS, SQL_API_SQLTABLES, SQL_API_SQLNATIVESQL, - SQL_API_SQLDRIVERCONNECT, SQL_API_SQLMORERESULTS, + SQL_API_SQLPREPARE, SQL_API_SQLEXECDIRECT, SQL_API_SQLEXECUTE, SQL_API_SQLROWCOUNT, + SQL_API_SQLFETCH, SQL_API_SQLSETCONNECTATTR, SQL_API_SQLFETCHSCROLL, + SQL_API_SQLFREEHANDLE, SQL_API_SQLFREESTMT, SQL_API_SQLGETCONNECTATTR, + SQL_API_SQLSETENVATTR, SQL_API_SQLSETSTMTATTR, SQL_API_SQLGETDATA, + SQL_API_SQLCOLUMNS, SQL_API_SQLTABLES, SQL_API_SQLNATIVESQL, + SQL_API_SQLDRIVERCONNECT, SQL_API_SQLMORERESULTS, SQL_API_SQLPRIMARYKEYS, + SQL_API_SQLFOREIGNKEYS, // ODBC 2.0 APIs SQL_API_SQLSETSTMTOPTION, SQL_API_SQLGETSTMTOPTION, SQL_API_SQLSETCONNECTOPTION, SQL_API_SQLGETCONNECTOPTION, SQL_API_SQLALLOCCONNECT, SQL_API_SQLALLOCENV, - SQL_API_SQLALLOCSTMT, SQL_API_SQLFREEENV, SQL_API_SQLFREECONNECT}; + SQL_API_SQLALLOCSTMT, SQL_API_SQLFREEENV, SQL_API_SQLFREECONNECT, + + // Driver Manager APIs + SQL_API_SQLGETFUNCTIONS, SQL_API_SQLDRIVERS, SQL_API_SQLDATASOURCES}; + const std::vector unsupported_functions = { + SQL_API_SQLPUTDATA, SQL_API_SQLGETDESCFIELD, SQL_API_SQLGETDESCREC, + SQL_API_SQLCOPYDESC, SQL_API_SQLPARAMDATA, SQL_API_SQLENDTRAN, + SQL_API_SQLSETCURSORNAME, SQL_API_SQLSETDESCFIELD, SQL_API_SQLSETDESCREC, + SQL_API_SQLGETCURSORNAME, SQL_API_SQLSTATISTICS, SQL_API_SQLSPECIALCOLUMNS, + SQL_API_SQLBINDPARAMETER, SQL_API_SQLBROWSECONNECT, SQL_API_SQLNUMPARAMS, + SQL_API_SQLBULKOPERATIONS, SQL_API_SQLCOLUMNPRIVILEGES, SQL_API_SQLPROCEDURECOLUMNS, + SQL_API_SQLDESCRIBEPARAM, SQL_API_SQLPROCEDURES, SQL_API_SQLSETPOS, + SQL_API_SQLTABLEPRIVILEGES}; SQLRETURN ret = SQLGetFunctions(this->conn, SQL_API_ODBC3_ALL_FUNCTIONS, api_exists); EXPECT_EQ(ret, SQL_SUCCESS); @@ -155,32 +72,172 @@ TYPED_TEST(FlightSQLODBCTestBase, TestSQLGetFunctions) { EXPECT_EQ(SQL_FUNC_EXISTS(api_exists, api), SQL_TRUE); } + for (int api : unsupported_functions) { + EXPECT_EQ(SQL_FUNC_EXISTS(api_exists, api), SQL_FALSE); + } + this->disconnect(); } -TEST_F(FlightSQLODBCMockTestBase, TestSQLGetFunctionsTEMP) { - // -AL- use this test to find singular values. - this->connect(); +TYPED_TEST(FlightSQLODBCTestBase, TestSQLGetFunctionsAllFunctionsODBCVer2) { + // Verify driver manager return values for SQLGetFunctions + this->connect(SQL_OV_ODBC2); - SQLUSMALLINT sql_tables_exists; - SQLRETURN ret = SQLGetFunctions(this->conn, SQL_API_SQLTABLES, &sql_tables_exists); + // ODBC 2.0 SQLGetFunctions returns 100 elements according to spec + SQLUSMALLINT api_exists[100]; + const std::vector supported_functions = { + SQL_API_SQLCONNECT, SQL_API_SQLGETINFO, + // SQL_API_SQLDESCRIBECOL, // -AL- todo enable once SQLDescribeCol is implemented. + SQL_API_SQLGETTYPEINFO, SQL_API_SQLDISCONNECT, SQL_API_SQLNUMRESULTCOLS, + SQL_API_SQLPREPARE, SQL_API_SQLEXECDIRECT, SQL_API_SQLEXECUTE, SQL_API_SQLROWCOUNT, + SQL_API_SQLFETCH, SQL_API_SQLFREESTMT, SQL_API_SQLGETDATA, SQL_API_SQLCOLUMNS, + SQL_API_SQLTABLES, SQL_API_SQLNATIVESQL, SQL_API_SQLDRIVERCONNECT, + SQL_API_SQLMORERESULTS, SQL_API_SQLSETSTMTOPTION, SQL_API_SQLGETSTMTOPTION, + SQL_API_SQLSETCONNECTOPTION, SQL_API_SQLGETCONNECTOPTION, SQL_API_SQLALLOCCONNECT, + SQL_API_SQLALLOCENV, SQL_API_SQLALLOCSTMT, SQL_API_SQLFREEENV, + SQL_API_SQLFREECONNECT, SQL_API_SQLPRIMARYKEYS, SQL_API_SQLFOREIGNKEYS, + + // Driver Manager APIs + SQL_API_SQLGETFUNCTIONS, SQL_API_SQLDRIVERS, SQL_API_SQLDATASOURCES}; + const std::vector unsupported_functions = { + SQL_API_SQLPUTDATA, SQL_API_SQLPARAMDATA, SQL_API_SQLSETCURSORNAME, + SQL_API_SQLGETCURSORNAME, SQL_API_SQLSTATISTICS, SQL_API_SQLSPECIALCOLUMNS, + SQL_API_SQLBINDPARAMETER, SQL_API_SQLBROWSECONNECT, SQL_API_SQLNUMPARAMS, + SQL_API_SQLBULKOPERATIONS, SQL_API_SQLCOLUMNPRIVILEGES, SQL_API_SQLPROCEDURECOLUMNS, + SQL_API_SQLDESCRIBEPARAM, SQL_API_SQLPROCEDURES, SQL_API_SQLSETPOS, + SQL_API_SQLTABLEPRIVILEGES}; + SQLRETURN ret = SQLGetFunctions(this->conn, SQL_API_ALL_FUNCTIONS, api_exists); EXPECT_EQ(ret, SQL_SUCCESS); - EXPECT_EQ(sql_tables_exists, SQL_TRUE); + for (int api : supported_functions) { + EXPECT_EQ(api_exists[api], SQL_TRUE); + } + + for (int api : unsupported_functions) { + EXPECT_EQ(api_exists[api], SQL_FALSE); + } this->disconnect(); } -TYPED_TEST(FlightSQLODBCTestBase, TestSQLGetFunctionsCheckSQLTables) { +TYPED_TEST(FlightSQLODBCTestBase, TestSQLGetFunctionsSupportedSingleAPI) { this->connect(); - - SQLUSMALLINT sql_tables_exists; - SQLRETURN ret = SQLGetFunctions(this->conn, SQL_API_SQLTABLES, &sql_tables_exists); - EXPECT_EQ(ret, SQL_SUCCESS); + const std::vector supported_functions = { + SQL_API_SQLALLOCHANDLE, SQL_API_SQLBINDCOL, SQL_API_SQLGETDIAGFIELD, + SQL_API_SQLCANCEL, SQL_API_SQLCLOSECURSOR, SQL_API_SQLGETDIAGREC, + SQL_API_SQLCOLATTRIBUTE, SQL_API_SQLGETENVATTR, SQL_API_SQLCONNECT, + SQL_API_SQLGETINFO, SQL_API_SQLGETSTMTATTR, + // SQL_API_SQLDESCRIBECOL, // -AL- todo enable once SQLDescribeCol is implemented. + SQL_API_SQLGETTYPEINFO, SQL_API_SQLDISCONNECT, SQL_API_SQLNUMRESULTCOLS, + SQL_API_SQLPREPARE, SQL_API_SQLEXECDIRECT, SQL_API_SQLEXECUTE, SQL_API_SQLROWCOUNT, + SQL_API_SQLFETCH, SQL_API_SQLSETCONNECTATTR, SQL_API_SQLFETCHSCROLL, + SQL_API_SQLFREEHANDLE, SQL_API_SQLFREESTMT, SQL_API_SQLGETCONNECTATTR, + SQL_API_SQLSETENVATTR, SQL_API_SQLSETSTMTATTR, SQL_API_SQLGETDATA, + SQL_API_SQLCOLUMNS, SQL_API_SQLTABLES, SQL_API_SQLNATIVESQL, + SQL_API_SQLDRIVERCONNECT, SQL_API_SQLMORERESULTS, SQL_API_SQLPRIMARYKEYS, + SQL_API_SQLFOREIGNKEYS, + + // ODBC 2.0 APIs + SQL_API_SQLSETSTMTOPTION, SQL_API_SQLGETSTMTOPTION, SQL_API_SQLSETCONNECTOPTION, + SQL_API_SQLGETCONNECTOPTION, SQL_API_SQLALLOCCONNECT, SQL_API_SQLALLOCENV, + SQL_API_SQLALLOCSTMT, SQL_API_SQLFREEENV, SQL_API_SQLFREECONNECT, + + // Driver Manager APIs + SQL_API_SQLGETFUNCTIONS, SQL_API_SQLDRIVERS, SQL_API_SQLDATASOURCES}; + SQLUSMALLINT api_exists; + for (SQLUSMALLINT api : supported_functions) { + SQLRETURN ret = SQLGetFunctions(this->conn, api, &api_exists); + + EXPECT_EQ(ret, SQL_SUCCESS); + + EXPECT_EQ(api_exists, SQL_TRUE); + + api_exists = SQL_FALSE; + } + + this->disconnect(); +} + +TYPED_TEST(FlightSQLODBCTestBase, TestSQLGetFunctionsUnsupportedSingleAPI) { + this->connect(); + + const std::vector unsupported_functions = { + SQL_API_SQLPUTDATA, SQL_API_SQLGETDESCFIELD, SQL_API_SQLGETDESCREC, + SQL_API_SQLCOPYDESC, SQL_API_SQLPARAMDATA, SQL_API_SQLENDTRAN, + SQL_API_SQLSETCURSORNAME, SQL_API_SQLSETDESCFIELD, SQL_API_SQLSETDESCREC, + SQL_API_SQLGETCURSORNAME, SQL_API_SQLSTATISTICS, SQL_API_SQLSPECIALCOLUMNS, + SQL_API_SQLBINDPARAMETER, SQL_API_SQLBROWSECONNECT, SQL_API_SQLNUMPARAMS, + SQL_API_SQLBULKOPERATIONS, SQL_API_SQLCOLUMNPRIVILEGES, SQL_API_SQLPROCEDURECOLUMNS, + SQL_API_SQLDESCRIBEPARAM, SQL_API_SQLPROCEDURES, SQL_API_SQLSETPOS, + SQL_API_SQLTABLEPRIVILEGES}; + SQLUSMALLINT api_exists; + for (SQLUSMALLINT api : unsupported_functions) { + SQLRETURN ret = SQLGetFunctions(this->conn, api, &api_exists); + + EXPECT_EQ(ret, SQL_SUCCESS); + + EXPECT_EQ(api_exists, SQL_FALSE); + + api_exists = SQL_TRUE; + } + + this->disconnect(); +} + +TYPED_TEST(FlightSQLODBCTestBase, TestSQLGetFunctionsSupportedSingleAPIODBCVer2) { + this->connect(SQL_OV_ODBC2); + + const std::vector supported_functions = { + SQL_API_SQLCONNECT, SQL_API_SQLGETINFO, + // SQL_API_SQLDESCRIBECOL, // -AL- todo enable once SQLDescribeCol is + // implemented. + SQL_API_SQLGETTYPEINFO, SQL_API_SQLDISCONNECT, SQL_API_SQLNUMRESULTCOLS, + SQL_API_SQLPREPARE, SQL_API_SQLEXECDIRECT, SQL_API_SQLEXECUTE, SQL_API_SQLROWCOUNT, + SQL_API_SQLFETCH, SQL_API_SQLFREESTMT, SQL_API_SQLGETDATA, SQL_API_SQLCOLUMNS, + SQL_API_SQLTABLES, SQL_API_SQLNATIVESQL, SQL_API_SQLDRIVERCONNECT, + SQL_API_SQLMORERESULTS, SQL_API_SQLSETSTMTOPTION, SQL_API_SQLGETSTMTOPTION, + SQL_API_SQLSETCONNECTOPTION, SQL_API_SQLGETCONNECTOPTION, SQL_API_SQLALLOCCONNECT, + SQL_API_SQLALLOCENV, SQL_API_SQLALLOCSTMT, SQL_API_SQLFREEENV, + SQL_API_SQLFREECONNECT, SQL_API_SQLPRIMARYKEYS, SQL_API_SQLFOREIGNKEYS, - EXPECT_EQ(sql_tables_exists, SQL_TRUE); + // Driver Manager APIs + SQL_API_SQLGETFUNCTIONS, SQL_API_SQLDRIVERS, SQL_API_SQLDATASOURCES}; + SQLUSMALLINT api_exists; + for (SQLUSMALLINT api : supported_functions) { + SQLRETURN ret = SQLGetFunctions(this->conn, api, &api_exists); + + EXPECT_EQ(ret, SQL_SUCCESS); + + EXPECT_EQ(api_exists, SQL_TRUE); + + api_exists = SQL_FALSE; + } + + this->disconnect(); +} + +TYPED_TEST(FlightSQLODBCTestBase, TestSQLGetFunctionsUnsupportedSingleAPIODBCVer2) { + this->connect(SQL_OV_ODBC2); + + const std::vector unsupported_functions = { + SQL_API_SQLPUTDATA, SQL_API_SQLPARAMDATA, SQL_API_SQLSETCURSORNAME, + SQL_API_SQLGETCURSORNAME, SQL_API_SQLSTATISTICS, SQL_API_SQLSPECIALCOLUMNS, + SQL_API_SQLBINDPARAMETER, SQL_API_SQLBROWSECONNECT, SQL_API_SQLNUMPARAMS, + SQL_API_SQLBULKOPERATIONS, SQL_API_SQLCOLUMNPRIVILEGES, SQL_API_SQLPROCEDURECOLUMNS, + SQL_API_SQLDESCRIBEPARAM, SQL_API_SQLPROCEDURES, SQL_API_SQLSETPOS, + SQL_API_SQLTABLEPRIVILEGES}; + SQLUSMALLINT api_exists; + for (SQLUSMALLINT api : unsupported_functions) { + SQLRETURN ret = SQLGetFunctions(this->conn, api, &api_exists); + + EXPECT_EQ(ret, SQL_SUCCESS); + + EXPECT_EQ(api_exists, SQL_FALSE); + + api_exists = SQL_TRUE; + } this->disconnect(); } From eeb231183b552c902aa229e5d1dfe34c859b042c Mon Sep 17 00:00:00 2001 From: "Alina (Xi) Li" Date: Thu, 7 Aug 2025 10:19:04 -0700 Subject: [PATCH 5/6] Update reset value --- cpp/src/arrow/flight/sql/odbc/tests/get_functions_test.cc | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/cpp/src/arrow/flight/sql/odbc/tests/get_functions_test.cc b/cpp/src/arrow/flight/sql/odbc/tests/get_functions_test.cc index e505f3fbf67..e6d19dd5aaa 100644 --- a/cpp/src/arrow/flight/sql/odbc/tests/get_functions_test.cc +++ b/cpp/src/arrow/flight/sql/odbc/tests/get_functions_test.cc @@ -154,7 +154,7 @@ TYPED_TEST(FlightSQLODBCTestBase, TestSQLGetFunctionsSupportedSingleAPI) { EXPECT_EQ(api_exists, SQL_TRUE); - api_exists = SQL_FALSE; + api_exists = -1; } this->disconnect(); @@ -180,7 +180,7 @@ TYPED_TEST(FlightSQLODBCTestBase, TestSQLGetFunctionsUnsupportedSingleAPI) { EXPECT_EQ(api_exists, SQL_FALSE); - api_exists = SQL_TRUE; + api_exists = -1; } this->disconnect(); @@ -212,7 +212,7 @@ TYPED_TEST(FlightSQLODBCTestBase, TestSQLGetFunctionsSupportedSingleAPIODBCVer2) EXPECT_EQ(api_exists, SQL_TRUE); - api_exists = SQL_FALSE; + api_exists = -1; } this->disconnect(); @@ -236,7 +236,7 @@ TYPED_TEST(FlightSQLODBCTestBase, TestSQLGetFunctionsUnsupportedSingleAPIODBCVer EXPECT_EQ(api_exists, SQL_FALSE); - api_exists = SQL_TRUE; + api_exists = -1; } this->disconnect(); From a6eb3203af34afd13d9d54dee158467c1edf91d3 Mon Sep 17 00:00:00 2001 From: "Alina (Xi) Li" Date: Fri, 8 Aug 2025 12:01:09 -0700 Subject: [PATCH 6/6] Add SQLDescribeCol function check --- .../flight/sql/odbc/tests/get_functions_test.cc | 13 ++++--------- 1 file changed, 4 insertions(+), 9 deletions(-) diff --git a/cpp/src/arrow/flight/sql/odbc/tests/get_functions_test.cc b/cpp/src/arrow/flight/sql/odbc/tests/get_functions_test.cc index e6d19dd5aaa..3eb54e49195 100644 --- a/cpp/src/arrow/flight/sql/odbc/tests/get_functions_test.cc +++ b/cpp/src/arrow/flight/sql/odbc/tests/get_functions_test.cc @@ -37,8 +37,7 @@ TYPED_TEST(FlightSQLODBCTestBase, TestSQLGetFunctionsAllFunctions) { SQL_API_SQLALLOCHANDLE, SQL_API_SQLBINDCOL, SQL_API_SQLGETDIAGFIELD, SQL_API_SQLCANCEL, SQL_API_SQLCLOSECURSOR, SQL_API_SQLGETDIAGREC, SQL_API_SQLCOLATTRIBUTE, SQL_API_SQLGETENVATTR, SQL_API_SQLCONNECT, - SQL_API_SQLGETINFO, SQL_API_SQLGETSTMTATTR, - // SQL_API_SQLDESCRIBECOL, // -AL- todo enable once SQLDescribeCol is implemented. + SQL_API_SQLGETINFO, SQL_API_SQLGETSTMTATTR, SQL_API_SQLDESCRIBECOL, SQL_API_SQLGETTYPEINFO, SQL_API_SQLDISCONNECT, SQL_API_SQLNUMRESULTCOLS, SQL_API_SQLPREPARE, SQL_API_SQLEXECDIRECT, SQL_API_SQLEXECUTE, SQL_API_SQLROWCOUNT, SQL_API_SQLFETCH, SQL_API_SQLSETCONNECTATTR, SQL_API_SQLFETCHSCROLL, @@ -86,8 +85,7 @@ TYPED_TEST(FlightSQLODBCTestBase, TestSQLGetFunctionsAllFunctionsODBCVer2) { // ODBC 2.0 SQLGetFunctions returns 100 elements according to spec SQLUSMALLINT api_exists[100]; const std::vector supported_functions = { - SQL_API_SQLCONNECT, SQL_API_SQLGETINFO, - // SQL_API_SQLDESCRIBECOL, // -AL- todo enable once SQLDescribeCol is implemented. + SQL_API_SQLCONNECT, SQL_API_SQLGETINFO, SQL_API_SQLDESCRIBECOL, SQL_API_SQLGETTYPEINFO, SQL_API_SQLDISCONNECT, SQL_API_SQLNUMRESULTCOLS, SQL_API_SQLPREPARE, SQL_API_SQLEXECDIRECT, SQL_API_SQLEXECUTE, SQL_API_SQLROWCOUNT, SQL_API_SQLFETCH, SQL_API_SQLFREESTMT, SQL_API_SQLGETDATA, SQL_API_SQLCOLUMNS, @@ -128,8 +126,7 @@ TYPED_TEST(FlightSQLODBCTestBase, TestSQLGetFunctionsSupportedSingleAPI) { SQL_API_SQLALLOCHANDLE, SQL_API_SQLBINDCOL, SQL_API_SQLGETDIAGFIELD, SQL_API_SQLCANCEL, SQL_API_SQLCLOSECURSOR, SQL_API_SQLGETDIAGREC, SQL_API_SQLCOLATTRIBUTE, SQL_API_SQLGETENVATTR, SQL_API_SQLCONNECT, - SQL_API_SQLGETINFO, SQL_API_SQLGETSTMTATTR, - // SQL_API_SQLDESCRIBECOL, // -AL- todo enable once SQLDescribeCol is implemented. + SQL_API_SQLGETINFO, SQL_API_SQLGETSTMTATTR, SQL_API_SQLDESCRIBECOL, SQL_API_SQLGETTYPEINFO, SQL_API_SQLDISCONNECT, SQL_API_SQLNUMRESULTCOLS, SQL_API_SQLPREPARE, SQL_API_SQLEXECDIRECT, SQL_API_SQLEXECUTE, SQL_API_SQLROWCOUNT, SQL_API_SQLFETCH, SQL_API_SQLSETCONNECTATTR, SQL_API_SQLFETCHSCROLL, @@ -190,9 +187,7 @@ TYPED_TEST(FlightSQLODBCTestBase, TestSQLGetFunctionsSupportedSingleAPIODBCVer2) this->connect(SQL_OV_ODBC2); const std::vector supported_functions = { - SQL_API_SQLCONNECT, SQL_API_SQLGETINFO, - // SQL_API_SQLDESCRIBECOL, // -AL- todo enable once SQLDescribeCol is - // implemented. + SQL_API_SQLCONNECT, SQL_API_SQLGETINFO, SQL_API_SQLDESCRIBECOL, SQL_API_SQLGETTYPEINFO, SQL_API_SQLDISCONNECT, SQL_API_SQLNUMRESULTCOLS, SQL_API_SQLPREPARE, SQL_API_SQLEXECDIRECT, SQL_API_SQLEXECUTE, SQL_API_SQLROWCOUNT, SQL_API_SQLFETCH, SQL_API_SQLFREESTMT, SQL_API_SQLGETDATA, SQL_API_SQLCOLUMNS,