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
12 changes: 12 additions & 0 deletions cpp/src/arrow/flight/sql/odbc/entry_points.cc
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,18 @@ SQLRETURN SQL_API SQLGetDiagRec(SQLSMALLINT handle_type, SQLHANDLE handle,
buffer_length, text_length_ptr);
}

#if defined(__APPLE__)
// macOS ODBC Driver Manager doesn't map SQLError to SQLGetDiagRec, so we need to
// implement SQLError for macOS.
// on Windows, SQLError mapping implemented by Driver Manager is preferred.
SQLRETURN SQL_API SQLError(SQLHENV env, SQLHDBC conn, SQLHSTMT stmt, SQLWCHAR* sql_state,
SQLINTEGER* native_error_ptr, SQLWCHAR* message_text,
SQLSMALLINT buffer_length, SQLSMALLINT* text_length_ptr) {
return arrow::flight::sql::odbc::SQLError(env, conn, stmt, sql_state, native_error_ptr,
message_text, buffer_length, text_length_ptr);
}
#endif // __APPLE__

SQLRETURN SQL_API SQLGetEnvAttr(SQLHENV env, SQLINTEGER attr, SQLPOINTER value_ptr,
SQLINTEGER buffer_len, SQLINTEGER* str_len_ptr) {
return arrow::flight::sql::odbc::SQLGetEnvAttr(env, attr, value_ptr, buffer_len,
Expand Down
51 changes: 50 additions & 1 deletion cpp/src/arrow/flight/sql/odbc/odbc_api.cc
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@lidavidm This draft PR is ready for review, please check the SQLError implementation. This PR needs #49220 to undraft since static ODBC changes iodbc behavior and impacts some of SQLError tests

Original file line number Diff line number Diff line change
Expand Up @@ -247,6 +247,56 @@ SQLRETURN SQLFreeStmt(SQLHSTMT handle, SQLUSMALLINT option) {
return SQL_ERROR;
}

#if defined(__APPLE__)
SQLRETURN SQLError(SQLHENV env, SQLHDBC conn, SQLHSTMT stmt, SQLWCHAR* sql_state,
SQLINTEGER* native_error_ptr, SQLWCHAR* message_text,
SQLSMALLINT buffer_length, SQLSMALLINT* text_length_ptr) {
ARROW_LOG(DEBUG) << "SQLError called with env: " << env << ", conn: " << conn
<< ", stmt: " << stmt
<< ", sql_state: " << static_cast<const void*>(sql_state)
<< ", native_error_ptr: " << static_cast<const void*>(native_error_ptr)
<< ", message_text: " << static_cast<const void*>(message_text)
<< ", buffer_length: " << buffer_length
<< ", text_length_ptr: " << static_cast<const void*>(text_length_ptr);

SQLSMALLINT handle_type;
SQLHANDLE handle;

if (env) {
handle_type = SQL_HANDLE_ENV;
handle = static_cast<SQLHANDLE>(env);
} else if (conn) {
handle_type = SQL_HANDLE_DBC;
handle = static_cast<SQLHANDLE>(conn);
} else if (stmt) {
handle_type = SQL_HANDLE_STMT;
handle = static_cast<SQLHANDLE>(stmt);
} else {
return static_cast<SQLRETURN>(SQL_INVALID_HANDLE);
}

// Use the last record
SQLINTEGER diag_number;
SQLSMALLINT diag_number_length;

SQLRETURN ret = arrow::flight::sql::odbc::SQLGetDiagField(
handle_type, handle, 0, SQL_DIAG_NUMBER, &diag_number, sizeof(SQLINTEGER), 0);
if (ret != SQL_SUCCESS) {
return ret;
}

if (diag_number == 0) {
return SQL_NO_DATA;
}

SQLSMALLINT rec_number = static_cast<SQLSMALLINT>(diag_number);

return arrow::flight::sql::odbc::SQLGetDiagRec(
handle_type, handle, rec_number, sql_state, native_error_ptr, message_text,
buffer_length, text_length_ptr);
}
#endif // __APPLE__

inline bool IsValidStringFieldArgs(SQLPOINTER diag_info_ptr, SQLSMALLINT buffer_length,
SQLSMALLINT* string_length_ptr, bool is_unicode) {
const SQLSMALLINT char_size = is_unicode ? GetSqlWCharSize() : sizeof(char);
Expand Down Expand Up @@ -736,7 +786,6 @@ SQLRETURN SQLGetConnectAttr(SQLHDBC conn, SQLINTEGER attribute, SQLPOINTER value
<< ", attribute: " << attribute << ", value_ptr: " << value_ptr
<< ", buffer_length: " << buffer_length << ", string_length_ptr: "
<< static_cast<const void*>(string_length_ptr);

using ODBC::ODBCConnection;

return ODBCConnection::ExecuteWithDiagnostics(conn, SQL_ERROR, [=]() {
Expand Down
6 changes: 6 additions & 0 deletions cpp/src/arrow/flight/sql/odbc/odbc_api_internal.h
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,12 @@ namespace arrow::flight::sql::odbc {
SQLHANDLE* result);
[[nodiscard]] SQLRETURN SQLFreeHandle(SQLSMALLINT type, SQLHANDLE handle);
[[nodiscard]] SQLRETURN SQLFreeStmt(SQLHSTMT stmt, SQLUSMALLINT option);
#if defined(__APPLE__)
[[nodiscard]] SQLRETURN SQLError(SQLHENV env, SQLHDBC conn, SQLHSTMT stmt,
SQLWCHAR* sql_state, SQLINTEGER* native_error_ptr,
SQLWCHAR* message_text, SQLSMALLINT buffer_length,
SQLSMALLINT* text_length_ptr);
#endif // __APPLE__
[[nodiscard]] SQLRETURN SQLGetDiagField(SQLSMALLINT handle_type, SQLHANDLE handle,
SQLSMALLINT rec_number,
SQLSMALLINT diag_identifier,
Expand Down
Loading
Loading