alinaliBQ commented on code in PR #47763:
URL: https://github.com/apache/arrow/pull/47763#discussion_r2453305130


##########
cpp/src/arrow/flight/sql/odbc/odbc_api.cc:
##########
@@ -91,8 +356,84 @@ SQLRETURN SQLGetDiagRec(SQLSMALLINT handle_type, SQLHANDLE 
handle, SQLSMALLINT r
                    << ", message_text: " << static_cast<const 
void*>(message_text)
                    << ", buffer_length: " << buffer_length
                    << ", text_length_ptr: " << static_cast<const 
void*>(text_length_ptr);
-  // GH-46575 TODO: Implement SQLGetDiagRec
-  return SQL_INVALID_HANDLE;
+  // GH-46575 TODO: Add tests for SQLGetDiagRec
+  using arrow::flight::sql::odbc::Diagnostics;
+  using ODBC::GetStringAttribute;
+  using ODBC::ODBCConnection;
+  using ODBC::ODBCDescriptor;
+  using ODBC::ODBCEnvironment;
+  using ODBC::ODBCStatement;
+
+  if (!handle) {
+    return SQL_INVALID_HANDLE;
+  }
+
+  // Record number must be greater or equal to 1
+  if (rec_number < 1 || buffer_length < 0) {
+    return SQL_ERROR;
+  }
+
+  // Set character type to be Unicode by default
+  const bool is_unicode = true;
+  Diagnostics* diagnostics = nullptr;
+
+  switch (handle_type) {
+    case SQL_HANDLE_ENV: {
+      auto* environment = ODBCEnvironment::Of(handle);
+      diagnostics = &environment->GetDiagnostics();
+      break;
+    }
+
+    case SQL_HANDLE_DBC: {
+      auto* connection = ODBCConnection::Of(handle);
+      diagnostics = &connection->GetDiagnostics();
+      break;
+    }
+
+    case SQL_HANDLE_DESC: {
+      auto* descriptor = ODBCDescriptor::Of(handle);
+      diagnostics = &descriptor->GetDiagnostics();
+      break;
+    }
+
+    case SQL_HANDLE_STMT: {
+      auto* statement = ODBCStatement::Of(handle);
+      diagnostics = &statement->GetDiagnostics();
+      break;
+    }
+
+    default:
+      return SQL_INVALID_HANDLE;
+  }
+
+  if (!diagnostics) {
+    return SQL_ERROR;
+  }
+
+  // Convert from ODBC 1 based record number to internal diagnostics 0 indexed 
storage
+  const size_t record_index = static_cast<size_t>(rec_number - 1);
+  if (!diagnostics->HasRecord(record_index)) {
+    return SQL_NO_DATA;
+  }
+
+  if (sql_state) {
+    // The length of the sql state is always 5 characters plus null
+    SQLSMALLINT size = 6;
+    const std::string& state = diagnostics->GetSQLState(record_index);
+    GetStringAttribute(is_unicode, state, false, sql_state, size, &size, 
*diagnostics);

Review Comment:
   Sure, added `ARROW_UNUSED` here.
   
   Regarding `[[nodiscard]]`, we can add it in this PR for ODBC API internal 
headers (odbc_api_internal.h). 
   On the other hand, since BI applications (and ODBC tests) will use the ODBC 
API definition headers at `sql.h` which doesn't have `[[nodiscard]]`, I think 
we could skip adding `[[nodiscard]]` to `entry_points.cc` as it won't make any 
impact. 



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]

Reply via email to