Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
30 changes: 26 additions & 4 deletions cpp/src/arrow/flight/sql/odbc/odbc_api.cc
Original file line number Diff line number Diff line change
Expand Up @@ -823,8 +823,24 @@ SQLRETURN SQLExecute(SQLHSTMT stmt) {

SQLRETURN SQLFetch(SQLHSTMT stmt) {
ARROW_LOG(DEBUG) << "SQLFetch called with stmt: " << stmt;
// GH-47713 TODO: Implement SQLFetch
return SQL_INVALID_HANDLE;

using ODBC::ODBCDescriptor;
using ODBC::ODBCStatement;
return ODBCStatement::ExecuteWithDiagnostics(stmt, SQL_ERROR, [=]() {
ODBCStatement* statement = reinterpret_cast<ODBCStatement*>(stmt);

// The SQL_ATTR_ROW_ARRAY_SIZE statement attribute specifies the number of rows in the
// rowset. Retrieve it with GetArraySize.
ODBCDescriptor* ard = statement->GetARD();
size_t rows = static_cast<size_t>(ard->GetArraySize());

if (statement->Fetch(rows)) {
return SQL_SUCCESS;
} else {
// Reached the end of rowset
return SQL_NO_DATA;
}
});
}

SQLRETURN SQLExtendedFetch(SQLHSTMT stmt, SQLUSMALLINT fetch_orientation,
Expand Down Expand Up @@ -876,8 +892,14 @@ SQLRETURN SQLGetData(SQLHSTMT stmt, SQLUSMALLINT record_number, SQLSMALLINT c_ty
<< ", record_number: " << record_number << ", c_type: " << c_type
<< ", data_ptr: " << data_ptr << ", buffer_length: " << buffer_length
<< ", indicator_ptr: " << static_cast<const void*>(indicator_ptr);
// GH-47713 TODO: Implement SQLGetData
return SQL_INVALID_HANDLE;

using ODBC::ODBCStatement;

return ODBCStatement::ExecuteWithDiagnostics(stmt, SQL_ERROR, [=]() {
ODBCStatement* statement = reinterpret_cast<ODBCStatement*>(stmt);
return statement->GetData(record_number, c_type, data_ptr, buffer_length,
indicator_ptr);
});
}

SQLRETURN SQLMoreResults(SQLHSTMT stmt) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@

#include "arrow/flight/sql/odbc/odbc_impl/flight_sql_result_set.h"

#include <sql.h>

#include <utility>
#include "arrow/flight/types.h"
#include "arrow/scalar.h"
Expand Down Expand Up @@ -212,14 +214,14 @@ void FlightSqlResultSet::Cancel() {
current_chunk_.data = nullptr;
}

bool FlightSqlResultSet::GetData(int column_n, int16_t target_type, int precision,
int scale, void* buffer, size_t buffer_length,
ssize_t* str_len_buffer) {
SQLRETURN FlightSqlResultSet::GetData(int column_n, int16_t target_type, int precision,
int scale, void* buffer, size_t buffer_length,
ssize_t* str_len_buffer) {
reset_get_data_ = true;
// Check if the offset is already at the end.
int64_t& value_offset = get_data_offsets_[column_n - 1];
if (value_offset == -1) {
return false;
return SQL_NO_DATA;
}

ColumnBinding binding(util::ConvertCDataTypeFromV2ToV3(target_type), precision, scale,
Expand All @@ -235,7 +237,11 @@ bool FlightSqlResultSet::GetData(int column_n, int16_t target_type, int precisio
diagnostics_, nullptr);

// If there was truncation, the converter would have reported it to the diagnostics.
return diagnostics_.HasWarning();
if (diagnostics_.HasWarning()) {
return SQL_SUCCESS_WITH_INFO;
} else {
return SQL_SUCCESS;
}
}

std::shared_ptr<ResultSetMetadata> FlightSqlResultSet::GetMetadata() { return metadata_; }
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -60,8 +60,8 @@ class FlightSqlResultSet : public ResultSet {

void Cancel() override;

bool GetData(int column_n, int16_t target_type, int precision, int scale, void* buffer,
size_t buffer_length, ssize_t* str_len_buffer) override;
SQLRETURN GetData(int column_n, int16_t target_type, int precision, int scale,
void* buffer, size_t buffer_length, ssize_t* str_len_buffer) override;

size_t Move(size_t rows, size_t bind_offset, size_t bind_type,
uint16_t* row_status_array) override;
Expand Down
70 changes: 40 additions & 30 deletions cpp/src/arrow/flight/sql/odbc/odbc_impl/odbc_statement.cc
Original file line number Diff line number Diff line change
Expand Up @@ -129,6 +129,9 @@ SQLSMALLINT getc_typeForSQLType(const DescriptorRecord& record) {
case SQL_WLONGVARCHAR:
return SQL_C_WCHAR;

case SQL_BIT:
return SQL_C_BIT;

case SQL_BINARY:
case SQL_VARBINARY:
case SQL_LONGVARBINARY:
Expand All @@ -146,13 +149,20 @@ SQLSMALLINT getc_typeForSQLType(const DescriptorRecord& record) {
case SQL_BIGINT:
return record.is_unsigned ? SQL_C_UBIGINT : SQL_C_SBIGINT;

case SQL_NUMERIC:
case SQL_DECIMAL:
return SQL_C_NUMERIC;

case SQL_FLOAT:
case SQL_REAL:
return SQL_C_FLOAT;

case SQL_FLOAT:
case SQL_DOUBLE:
return SQL_C_DOUBLE;

case SQL_GUID:
return SQL_C_GUID;

case SQL_DATE:
case SQL_TYPE_DATE:
return SQL_C_TYPE_DATE;
Expand All @@ -165,32 +175,32 @@ SQLSMALLINT getc_typeForSQLType(const DescriptorRecord& record) {
case SQL_TYPE_TIMESTAMP:
return SQL_C_TYPE_TIMESTAMP;

case SQL_C_INTERVAL_DAY:
return SQL_INTERVAL_DAY;
case SQL_C_INTERVAL_DAY_TO_HOUR:
return SQL_INTERVAL_DAY_TO_HOUR;
case SQL_C_INTERVAL_DAY_TO_MINUTE:
return SQL_INTERVAL_DAY_TO_MINUTE;
case SQL_C_INTERVAL_DAY_TO_SECOND:
return SQL_INTERVAL_DAY_TO_SECOND;
case SQL_C_INTERVAL_HOUR:
return SQL_INTERVAL_HOUR;
case SQL_C_INTERVAL_HOUR_TO_MINUTE:
return SQL_INTERVAL_HOUR_TO_MINUTE;
case SQL_C_INTERVAL_HOUR_TO_SECOND:
return SQL_INTERVAL_HOUR_TO_SECOND;
case SQL_C_INTERVAL_MINUTE:
return SQL_INTERVAL_MINUTE;
case SQL_C_INTERVAL_MINUTE_TO_SECOND:
return SQL_INTERVAL_MINUTE_TO_SECOND;
case SQL_C_INTERVAL_SECOND:
return SQL_INTERVAL_SECOND;
case SQL_C_INTERVAL_YEAR:
return SQL_INTERVAL_YEAR;
case SQL_C_INTERVAL_YEAR_TO_MONTH:
return SQL_INTERVAL_YEAR_TO_MONTH;
case SQL_C_INTERVAL_MONTH:
return SQL_INTERVAL_MONTH;
case SQL_INTERVAL_DAY:
return SQL_C_INTERVAL_DAY;
case SQL_INTERVAL_DAY_TO_HOUR:
return SQL_C_INTERVAL_DAY_TO_HOUR;
case SQL_INTERVAL_DAY_TO_MINUTE:
return SQL_C_INTERVAL_DAY_TO_MINUTE;
case SQL_INTERVAL_DAY_TO_SECOND:
return SQL_C_INTERVAL_DAY_TO_SECOND;
case SQL_INTERVAL_HOUR:
return SQL_C_INTERVAL_HOUR;
case SQL_INTERVAL_HOUR_TO_MINUTE:
return SQL_C_INTERVAL_HOUR_TO_MINUTE;
case SQL_INTERVAL_HOUR_TO_SECOND:
return SQL_C_INTERVAL_HOUR_TO_SECOND;
case SQL_INTERVAL_MINUTE:
return SQL_C_INTERVAL_MINUTE;
case SQL_INTERVAL_MINUTE_TO_SECOND:
return SQL_C_INTERVAL_MINUTE_TO_SECOND;
case SQL_INTERVAL_SECOND:
return SQL_C_INTERVAL_SECOND;
case SQL_INTERVAL_YEAR:
return SQL_C_INTERVAL_YEAR;
case SQL_INTERVAL_YEAR_TO_MONTH:
return SQL_C_INTERVAL_YEAR_TO_MONTH;
case SQL_INTERVAL_MONTH:
return SQL_C_INTERVAL_MONTH;

default:
throw DriverException("Unknown SQL type: " + std::to_string(record.concise_type),
Expand Down Expand Up @@ -691,9 +701,9 @@ void ODBCStatement::CloseCursor(bool suppress_errors) {
has_reached_end_of_result_ = false;
}

bool ODBCStatement::GetData(SQLSMALLINT record_number, SQLSMALLINT c_type,
SQLPOINTER data_ptr, SQLLEN buffer_length,
SQLLEN* indicator_ptr) {
SQLRETURN ODBCStatement::GetData(SQLSMALLINT record_number, SQLSMALLINT c_type,
SQLPOINTER data_ptr, SQLLEN buffer_length,
SQLLEN* indicator_ptr) {
if (record_number == 0) {
throw DriverException("Bookmarks are not supported", "07009");
} else if (record_number > ird_->GetRecords().size()) {
Expand Down
8 changes: 3 additions & 5 deletions cpp/src/arrow/flight/sql/odbc/odbc_impl/odbc_statement.h
Original file line number Diff line number Diff line change
Expand Up @@ -58,9 +58,7 @@ class ODBCStatement : public ODBCHandle<ODBCStatement> {
void ExecutePrepared();
void ExecuteDirect(const std::string& query);

/**
* @brief Returns true if the number of rows fetch was greater than zero.
*/
/// \brief Return true if the number of rows fetch was greater than zero.
bool Fetch(size_t rows);
bool IsPrepared() const;

Expand All @@ -77,8 +75,8 @@ class ODBCStatement : public ODBCHandle<ODBCStatement> {

inline SQLULEN GetRowsetSize() { return rowset_size_; }

bool GetData(SQLSMALLINT record_number, SQLSMALLINT c_type, SQLPOINTER data_ptr,
SQLLEN buffer_length, SQLLEN* indicator_ptr);
SQLRETURN GetData(SQLSMALLINT record_number, SQLSMALLINT c_type, SQLPOINTER data_ptr,
SQLLEN buffer_length, SQLLEN* indicator_ptr);

/**
* @brief Closes the cursor. This does _not_ un-prepare the statement or change
Expand Down
10 changes: 6 additions & 4 deletions cpp/src/arrow/flight/sql/odbc/odbc_impl/spi/result_set.h
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,8 @@

#include "arrow/flight/sql/odbc/odbc_impl/types.h"

#include <sqltypes.h>

namespace arrow::flight::sql::odbc {

class ResultSetMetadata;
Expand Down Expand Up @@ -87,10 +89,10 @@ class ResultSet {
/// \param buffer Target buffer to be populated.
/// \param buffer_length Target buffer length.
/// \param strlen_buffer Buffer that holds the length of value being fetched.
/// \returns true if there is more data to fetch from the current cell;
/// false if the whole value was already fetched.
virtual bool GetData(int column, int16_t target_type, int precision, int scale,
void* buffer, size_t buffer_length, ssize_t* strlen_buffer) = 0;
/// \return SQLRETURN for SQLGetData.
virtual SQLRETURN GetData(int column, int16_t target_type, int precision, int scale,
void* buffer, size_t buffer_length,
ssize_t* strlen_buffer) = 0;
};

} // namespace arrow::flight::sql::odbc
1 change: 1 addition & 0 deletions cpp/src/arrow/flight/sql/odbc/tests/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ add_arrow_test(flight_sql_odbc_test
odbc_test_suite.cc
odbc_test_suite.h
connection_test.cc
statement_test.cc
# Enable Protobuf cleanup after test execution
# GH-46889: move protobuf_test_util to a more common location
../../../../engine/substrait/protobuf_test_util.cc
Expand Down
Loading
Loading