Skip to content

Commit f8e40da

Browse files
authored
GH-47713: [C++][FlightRPC] ODBC SQLMoreResults implementation (#48035)
### Rationale for this change Implement SQLMoreResults for fetching more results. Arrow protocol doesn't support multiple result sets, so `no data` is returned by default in SQLMoreResults. ### What changes are included in this PR? - SQLMoreResults & tests ### Are these changes tested? Tested on local MSVC ### Are there any user-facing changes? N/A * GitHub Issue: #47713 Authored-by: Alina (Xi) Li <[email protected]> Signed-off-by: David Li <[email protected]>
1 parent cd848bc commit f8e40da

File tree

4 files changed

+37
-2
lines changed

4 files changed

+37
-2
lines changed

cpp/src/arrow/flight/sql/odbc/odbc_api.cc

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1142,8 +1142,14 @@ SQLRETURN SQLGetData(SQLHSTMT stmt, SQLUSMALLINT record_number, SQLSMALLINT c_ty
11421142

11431143
SQLRETURN SQLMoreResults(SQLHSTMT stmt) {
11441144
ARROW_LOG(DEBUG) << "SQLMoreResults called with stmt: " << stmt;
1145-
// GH-47713 TODO: Implement SQLMoreResults
1146-
return SQL_INVALID_HANDLE;
1145+
1146+
using ODBC::ODBCStatement;
1147+
// Multiple result sets are not supported by Arrow protocol. Return SQL_NO_DATA by
1148+
// default to indicate no data is available.
1149+
return ODBCStatement::ExecuteWithDiagnostics(stmt, SQL_ERROR, [=]() {
1150+
ODBCStatement* statement = reinterpret_cast<ODBCStatement*>(stmt);
1151+
return statement->GetMoreResults();
1152+
});
11471153
}
11481154

11491155
SQLRETURN SQLNumResultCols(SQLHSTMT stmt, SQLSMALLINT* column_count_ptr) {

cpp/src/arrow/flight/sql/odbc/odbc_impl/odbc_statement.cc

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -761,6 +761,15 @@ SQLRETURN ODBCStatement::GetData(SQLSMALLINT record_number, SQLSMALLINT c_type,
761761
data_ptr, buffer_length, indicator_ptr);
762762
}
763763

764+
SQLRETURN ODBCStatement::GetMoreResults() {
765+
// Multiple result sets are not supported by Arrow protocol.
766+
if (current_result_) {
767+
return SQL_NO_DATA;
768+
} else {
769+
throw DriverException("Function sequence error", "HY010");
770+
}
771+
}
772+
764773
void ODBCStatement::GetColumnCount(SQLSMALLINT* column_count_ptr) {
765774
if (!column_count_ptr) {
766775
// column count pointer is not valid, do nothing as ODBC spec does not mention this as

cpp/src/arrow/flight/sql/odbc/odbc_impl/odbc_statement.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,8 @@ class ODBCStatement : public ODBCHandle<ODBCStatement> {
8181
SQLRETURN GetData(SQLSMALLINT record_number, SQLSMALLINT c_type, SQLPOINTER data_ptr,
8282
SQLLEN buffer_length, SQLLEN* indicator_ptr);
8383

84+
SQLRETURN GetMoreResults();
85+
8486
/// \brief Return number of columns from data set
8587
void GetColumnCount(SQLSMALLINT* column_count_ptr);
8688

cpp/src/arrow/flight/sql/odbc/tests/statement_test.cc

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1722,6 +1722,24 @@ TYPED_TEST(StatementTest, TestSQLBindColIndicatorOnlySQLUnbind) {
17221722
// EXPECT_EQ(1, char_val_ind);
17231723
}
17241724

1725+
TYPED_TEST(StatementTest, TestSQLMoreResultsNoData) {
1726+
// Verify SQLMoreResults returns SQL_NO_DATA by default.
1727+
std::wstring wsql = L"SELECT 1;";
1728+
std::vector<SQLWCHAR> sql0(wsql.begin(), wsql.end());
1729+
1730+
ASSERT_EQ(SQL_SUCCESS,
1731+
SQLExecDirect(this->stmt, &sql0[0], static_cast<SQLINTEGER>(sql0.size())));
1732+
1733+
ASSERT_EQ(SQL_NO_DATA, SQLMoreResults(this->stmt));
1734+
}
1735+
1736+
TYPED_TEST(StatementTest, TestSQLMoreResultsInvalidFunctionSequence) {
1737+
// Verify function sequence error state is reported when SQLMoreResults is called
1738+
// without executing any queries
1739+
ASSERT_EQ(SQL_ERROR, SQLMoreResults(this->stmt));
1740+
VerifyOdbcErrorState(SQL_HANDLE_STMT, this->stmt, kErrorStateHY010);
1741+
}
1742+
17251743
TYPED_TEST(StatementTest, TestSQLNativeSqlReturnsInputString) {
17261744
SQLWCHAR buf[1024];
17271745
SQLINTEGER buf_char_len = sizeof(buf) / GetSqlWCharSize();

0 commit comments

Comments
 (0)