Skip to content

Commit df4ff90

Browse files
GH-47789: [C++][FlightRPC] SQLGetFunctions Tests (#48031)
### Rationale for this change Add SQLGetFunctions Tests to make sure the ODBC driver manager's implementation SQLGetFunctions is same as expected. The ODBC driver manager interacts with the Flight SQL ODBC driver and determines the return values of SQLGetFunctions based on that. ### What changes are included in this PR? - SQLGetFunctions tests ### Are these changes tested? - Tested in CI ### Are there any user-facing changes? No * GitHub Issue: #47789 Lead-authored-by: Alina (Xi) Li <alina.li@improving.com> Co-authored-by: justing-bq <justin.gossett@improving.com> Signed-off-by: David Li <li.davidm96@gmail.com>
1 parent 16de220 commit df4ff90

File tree

2 files changed

+221
-0
lines changed

2 files changed

+221
-0
lines changed

cpp/src/arrow/flight/sql/odbc/tests/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@ add_arrow_test(flight_sql_odbc_test
3939
connection_info_test.cc
4040
connection_test.cc
4141
errors_test.cc
42+
get_functions_test.cc
4243
statement_attr_test.cc
4344
statement_test.cc
4445
tables_test.cc
Lines changed: 220 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,220 @@
1+
// Licensed to the Apache Software Foundation (ASF) under one
2+
// or more contributor license agreements. See the NOTICE file
3+
// distributed with this work for additional information
4+
// regarding copyright ownership. The ASF licenses this file
5+
// to you under the Apache License, Version 2.0 (the
6+
// "License"); you may not use this file except in compliance
7+
// with the License. You may obtain a copy of the License at
8+
//
9+
// http://www.apache.org/licenses/LICENSE-2.0
10+
//
11+
// Unless required by applicable law or agreed to in writing,
12+
// software distributed under the License is distributed on an
13+
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
14+
// KIND, either express or implied. See the License for the
15+
// specific language governing permissions and limitations
16+
// under the License.
17+
#include "arrow/flight/sql/odbc/tests/odbc_test_suite.h"
18+
19+
#include "arrow/flight/sql/odbc/odbc_impl/platform.h"
20+
21+
#include <sql.h>
22+
#include <sqltypes.h>
23+
#include <sqlucode.h>
24+
25+
#include <gtest/gtest.h>
26+
27+
namespace arrow::flight::sql::odbc {
28+
29+
template <typename T>
30+
class GetFunctionsTest : public T {};
31+
32+
using TestTypes =
33+
::testing::Types<FlightSQLODBCMockTestBase, FlightSQLODBCRemoteTestBase>;
34+
TYPED_TEST_SUITE(GetFunctionsTest, TestTypes);
35+
36+
template <typename T>
37+
class GetFunctionsOdbcV2Test : public T {};
38+
39+
using TestTypesOdbcV2 =
40+
::testing::Types<FlightSQLOdbcV2MockTestBase, FlightSQLOdbcV2RemoteTestBase>;
41+
TYPED_TEST_SUITE(GetFunctionsOdbcV2Test, TestTypesOdbcV2);
42+
43+
TYPED_TEST(GetFunctionsTest, TestSQLGetFunctionsAllFunctions) {
44+
// Verify driver manager return values for SQLGetFunctions
45+
46+
SQLUSMALLINT api_exists[SQL_API_ODBC3_ALL_FUNCTIONS_SIZE];
47+
const std::vector<int> supported_functions = {
48+
SQL_API_SQLALLOCHANDLE, SQL_API_SQLBINDCOL, SQL_API_SQLGETDIAGFIELD,
49+
SQL_API_SQLCANCEL, SQL_API_SQLCLOSECURSOR, SQL_API_SQLGETDIAGREC,
50+
SQL_API_SQLCOLATTRIBUTE, SQL_API_SQLGETENVATTR, SQL_API_SQLCONNECT,
51+
SQL_API_SQLGETINFO, SQL_API_SQLGETSTMTATTR, SQL_API_SQLDESCRIBECOL,
52+
SQL_API_SQLGETTYPEINFO, SQL_API_SQLDISCONNECT, SQL_API_SQLNUMRESULTCOLS,
53+
SQL_API_SQLPREPARE, SQL_API_SQLEXECDIRECT, SQL_API_SQLEXECUTE, SQL_API_SQLROWCOUNT,
54+
SQL_API_SQLFETCH, SQL_API_SQLSETCONNECTATTR, SQL_API_SQLFETCHSCROLL,
55+
SQL_API_SQLFREEHANDLE, SQL_API_SQLFREESTMT, SQL_API_SQLGETCONNECTATTR,
56+
SQL_API_SQLSETENVATTR, SQL_API_SQLSETSTMTATTR, SQL_API_SQLGETDATA,
57+
SQL_API_SQLCOLUMNS, SQL_API_SQLTABLES, SQL_API_SQLNATIVESQL,
58+
SQL_API_SQLDRIVERCONNECT, SQL_API_SQLMORERESULTS, SQL_API_SQLPRIMARYKEYS,
59+
SQL_API_SQLFOREIGNKEYS,
60+
61+
// ODBC 2.0 APIs
62+
SQL_API_SQLSETSTMTOPTION, SQL_API_SQLGETSTMTOPTION, SQL_API_SQLSETCONNECTOPTION,
63+
SQL_API_SQLGETCONNECTOPTION, SQL_API_SQLALLOCCONNECT, SQL_API_SQLALLOCENV,
64+
SQL_API_SQLALLOCSTMT, SQL_API_SQLFREEENV, SQL_API_SQLFREECONNECT,
65+
66+
// Driver Manager APIs
67+
SQL_API_SQLGETFUNCTIONS, SQL_API_SQLDRIVERS, SQL_API_SQLDATASOURCES};
68+
const std::vector<int> unsupported_functions = {
69+
SQL_API_SQLPUTDATA, SQL_API_SQLGETDESCFIELD, SQL_API_SQLGETDESCREC,
70+
SQL_API_SQLCOPYDESC, SQL_API_SQLPARAMDATA, SQL_API_SQLENDTRAN,
71+
SQL_API_SQLSETCURSORNAME, SQL_API_SQLSETDESCFIELD, SQL_API_SQLSETDESCREC,
72+
SQL_API_SQLGETCURSORNAME, SQL_API_SQLSTATISTICS, SQL_API_SQLSPECIALCOLUMNS,
73+
SQL_API_SQLBINDPARAMETER, SQL_API_SQLBROWSECONNECT, SQL_API_SQLNUMPARAMS,
74+
SQL_API_SQLBULKOPERATIONS, SQL_API_SQLCOLUMNPRIVILEGES, SQL_API_SQLPROCEDURECOLUMNS,
75+
SQL_API_SQLDESCRIBEPARAM, SQL_API_SQLPROCEDURES, SQL_API_SQLSETPOS,
76+
SQL_API_SQLTABLEPRIVILEGES};
77+
78+
ASSERT_EQ(SQL_SUCCESS,
79+
SQLGetFunctions(this->conn, SQL_API_ODBC3_ALL_FUNCTIONS, api_exists));
80+
81+
for (int api : supported_functions) {
82+
EXPECT_EQ(SQL_TRUE, SQL_FUNC_EXISTS(api_exists, api));
83+
}
84+
85+
for (int api : unsupported_functions) {
86+
EXPECT_EQ(SQL_FALSE, SQL_FUNC_EXISTS(api_exists, api));
87+
}
88+
}
89+
90+
TYPED_TEST(GetFunctionsOdbcV2Test, TestSQLGetFunctionsAllFunctionsODBCVer2) {
91+
// Verify driver manager return values for SQLGetFunctions
92+
93+
// ODBC 2.0 SQLGetFunctions returns 100 elements according to spec
94+
SQLUSMALLINT api_exists[100];
95+
const std::vector<int> supported_functions = {
96+
SQL_API_SQLCONNECT, SQL_API_SQLGETINFO, SQL_API_SQLDESCRIBECOL,
97+
SQL_API_SQLGETTYPEINFO, SQL_API_SQLDISCONNECT, SQL_API_SQLNUMRESULTCOLS,
98+
SQL_API_SQLPREPARE, SQL_API_SQLEXECDIRECT, SQL_API_SQLEXECUTE, SQL_API_SQLROWCOUNT,
99+
SQL_API_SQLFETCH, SQL_API_SQLFREESTMT, SQL_API_SQLGETDATA, SQL_API_SQLCOLUMNS,
100+
SQL_API_SQLTABLES, SQL_API_SQLNATIVESQL, SQL_API_SQLDRIVERCONNECT,
101+
SQL_API_SQLMORERESULTS, SQL_API_SQLSETSTMTOPTION, SQL_API_SQLGETSTMTOPTION,
102+
SQL_API_SQLSETCONNECTOPTION, SQL_API_SQLGETCONNECTOPTION, SQL_API_SQLALLOCCONNECT,
103+
SQL_API_SQLALLOCENV, SQL_API_SQLALLOCSTMT, SQL_API_SQLFREEENV,
104+
SQL_API_SQLFREECONNECT, SQL_API_SQLPRIMARYKEYS, SQL_API_SQLFOREIGNKEYS,
105+
106+
// Driver Manager APIs
107+
SQL_API_SQLGETFUNCTIONS, SQL_API_SQLDRIVERS, SQL_API_SQLDATASOURCES};
108+
const std::vector<int> unsupported_functions = {
109+
SQL_API_SQLPUTDATA, SQL_API_SQLPARAMDATA, SQL_API_SQLSETCURSORNAME,
110+
SQL_API_SQLGETCURSORNAME, SQL_API_SQLSTATISTICS, SQL_API_SQLSPECIALCOLUMNS,
111+
SQL_API_SQLBINDPARAMETER, SQL_API_SQLBROWSECONNECT, SQL_API_SQLNUMPARAMS,
112+
SQL_API_SQLBULKOPERATIONS, SQL_API_SQLCOLUMNPRIVILEGES, SQL_API_SQLPROCEDURECOLUMNS,
113+
SQL_API_SQLDESCRIBEPARAM, SQL_API_SQLPROCEDURES, SQL_API_SQLSETPOS,
114+
SQL_API_SQLTABLEPRIVILEGES};
115+
ASSERT_EQ(SQL_SUCCESS, SQLGetFunctions(this->conn, SQL_API_ALL_FUNCTIONS, api_exists));
116+
117+
for (int api : supported_functions) {
118+
EXPECT_EQ(SQL_TRUE, api_exists[api]);
119+
}
120+
121+
for (int api : unsupported_functions) {
122+
EXPECT_EQ(SQL_FALSE, api_exists[api]);
123+
}
124+
}
125+
126+
TYPED_TEST(GetFunctionsTest, TestSQLGetFunctionsSupportedSingleAPI) {
127+
const std::vector<SQLUSMALLINT> supported_functions = {
128+
SQL_API_SQLALLOCHANDLE, SQL_API_SQLBINDCOL, SQL_API_SQLGETDIAGFIELD,
129+
SQL_API_SQLCANCEL, SQL_API_SQLCLOSECURSOR, SQL_API_SQLGETDIAGREC,
130+
SQL_API_SQLCOLATTRIBUTE, SQL_API_SQLGETENVATTR, SQL_API_SQLCONNECT,
131+
SQL_API_SQLGETINFO, SQL_API_SQLGETSTMTATTR, SQL_API_SQLDESCRIBECOL,
132+
SQL_API_SQLGETTYPEINFO, SQL_API_SQLDISCONNECT, SQL_API_SQLNUMRESULTCOLS,
133+
SQL_API_SQLPREPARE, SQL_API_SQLEXECDIRECT, SQL_API_SQLEXECUTE, SQL_API_SQLROWCOUNT,
134+
SQL_API_SQLFETCH, SQL_API_SQLSETCONNECTATTR, SQL_API_SQLFETCHSCROLL,
135+
SQL_API_SQLFREEHANDLE, SQL_API_SQLFREESTMT, SQL_API_SQLGETCONNECTATTR,
136+
SQL_API_SQLSETENVATTR, SQL_API_SQLSETSTMTATTR, SQL_API_SQLGETDATA,
137+
SQL_API_SQLCOLUMNS, SQL_API_SQLTABLES, SQL_API_SQLNATIVESQL,
138+
SQL_API_SQLDRIVERCONNECT, SQL_API_SQLMORERESULTS, SQL_API_SQLPRIMARYKEYS,
139+
SQL_API_SQLFOREIGNKEYS,
140+
141+
// ODBC 2.0 APIs
142+
SQL_API_SQLSETSTMTOPTION, SQL_API_SQLGETSTMTOPTION, SQL_API_SQLSETCONNECTOPTION,
143+
SQL_API_SQLGETCONNECTOPTION, SQL_API_SQLALLOCCONNECT, SQL_API_SQLALLOCENV,
144+
SQL_API_SQLALLOCSTMT, SQL_API_SQLFREEENV, SQL_API_SQLFREECONNECT,
145+
146+
// Driver Manager APIs
147+
SQL_API_SQLGETFUNCTIONS, SQL_API_SQLDRIVERS, SQL_API_SQLDATASOURCES};
148+
SQLUSMALLINT api_exists;
149+
for (SQLUSMALLINT api : supported_functions) {
150+
ASSERT_EQ(SQL_SUCCESS, SQLGetFunctions(this->conn, api, &api_exists));
151+
152+
EXPECT_EQ(SQL_TRUE, api_exists);
153+
154+
api_exists = -1;
155+
}
156+
}
157+
158+
TYPED_TEST(GetFunctionsTest, TestSQLGetFunctionsUnsupportedSingleAPI) {
159+
const std::vector<SQLUSMALLINT> unsupported_functions = {
160+
SQL_API_SQLPUTDATA, SQL_API_SQLGETDESCFIELD, SQL_API_SQLGETDESCREC,
161+
SQL_API_SQLCOPYDESC, SQL_API_SQLPARAMDATA, SQL_API_SQLENDTRAN,
162+
SQL_API_SQLSETCURSORNAME, SQL_API_SQLSETDESCFIELD, SQL_API_SQLSETDESCREC,
163+
SQL_API_SQLGETCURSORNAME, SQL_API_SQLSTATISTICS, SQL_API_SQLSPECIALCOLUMNS,
164+
SQL_API_SQLBINDPARAMETER, SQL_API_SQLBROWSECONNECT, SQL_API_SQLNUMPARAMS,
165+
SQL_API_SQLBULKOPERATIONS, SQL_API_SQLCOLUMNPRIVILEGES, SQL_API_SQLPROCEDURECOLUMNS,
166+
SQL_API_SQLDESCRIBEPARAM, SQL_API_SQLPROCEDURES, SQL_API_SQLSETPOS,
167+
SQL_API_SQLTABLEPRIVILEGES};
168+
SQLUSMALLINT api_exists;
169+
for (SQLUSMALLINT api : unsupported_functions) {
170+
ASSERT_EQ(SQL_SUCCESS, SQLGetFunctions(this->conn, api, &api_exists));
171+
172+
EXPECT_EQ(SQL_FALSE, api_exists);
173+
174+
api_exists = -1;
175+
}
176+
}
177+
178+
TYPED_TEST(GetFunctionsOdbcV2Test, TestSQLGetFunctionsSupportedSingleAPIODBCVer2) {
179+
const std::vector<SQLUSMALLINT> supported_functions = {
180+
SQL_API_SQLCONNECT, SQL_API_SQLGETINFO, SQL_API_SQLDESCRIBECOL,
181+
SQL_API_SQLGETTYPEINFO, SQL_API_SQLDISCONNECT, SQL_API_SQLNUMRESULTCOLS,
182+
SQL_API_SQLPREPARE, SQL_API_SQLEXECDIRECT, SQL_API_SQLEXECUTE, SQL_API_SQLROWCOUNT,
183+
SQL_API_SQLFETCH, SQL_API_SQLFREESTMT, SQL_API_SQLGETDATA, SQL_API_SQLCOLUMNS,
184+
SQL_API_SQLTABLES, SQL_API_SQLNATIVESQL, SQL_API_SQLDRIVERCONNECT,
185+
SQL_API_SQLMORERESULTS, SQL_API_SQLSETSTMTOPTION, SQL_API_SQLGETSTMTOPTION,
186+
SQL_API_SQLSETCONNECTOPTION, SQL_API_SQLGETCONNECTOPTION, SQL_API_SQLALLOCCONNECT,
187+
SQL_API_SQLALLOCENV, SQL_API_SQLALLOCSTMT, SQL_API_SQLFREEENV,
188+
SQL_API_SQLFREECONNECT, SQL_API_SQLPRIMARYKEYS, SQL_API_SQLFOREIGNKEYS,
189+
190+
// Driver Manager APIs
191+
SQL_API_SQLGETFUNCTIONS, SQL_API_SQLDRIVERS, SQL_API_SQLDATASOURCES};
192+
SQLUSMALLINT api_exists;
193+
for (SQLUSMALLINT api : supported_functions) {
194+
ASSERT_EQ(SQL_SUCCESS, SQLGetFunctions(this->conn, api, &api_exists));
195+
196+
EXPECT_EQ(SQL_TRUE, api_exists);
197+
198+
api_exists = -1;
199+
}
200+
}
201+
202+
TYPED_TEST(GetFunctionsOdbcV2Test, TestSQLGetFunctionsUnsupportedSingleAPIODBCVer2) {
203+
const std::vector<SQLUSMALLINT> unsupported_functions = {
204+
SQL_API_SQLPUTDATA, SQL_API_SQLPARAMDATA, SQL_API_SQLSETCURSORNAME,
205+
SQL_API_SQLGETCURSORNAME, SQL_API_SQLSTATISTICS, SQL_API_SQLSPECIALCOLUMNS,
206+
SQL_API_SQLBINDPARAMETER, SQL_API_SQLBROWSECONNECT, SQL_API_SQLNUMPARAMS,
207+
SQL_API_SQLBULKOPERATIONS, SQL_API_SQLCOLUMNPRIVILEGES, SQL_API_SQLPROCEDURECOLUMNS,
208+
SQL_API_SQLDESCRIBEPARAM, SQL_API_SQLPROCEDURES, SQL_API_SQLSETPOS,
209+
SQL_API_SQLTABLEPRIVILEGES};
210+
SQLUSMALLINT api_exists;
211+
for (SQLUSMALLINT api : unsupported_functions) {
212+
ASSERT_EQ(SQL_SUCCESS, SQLGetFunctions(this->conn, api, &api_exists));
213+
214+
EXPECT_EQ(SQL_FALSE, api_exists);
215+
216+
api_exists = -1;
217+
}
218+
}
219+
220+
} // namespace arrow::flight::sql::odbc

0 commit comments

Comments
 (0)