This is an automated email from the ASF dual-hosted git repository.
lidavidm pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/arrow-adbc.git
The following commit(s) were added to refs/heads/main by this push:
new fdf92e044 feat(c/driver/postgresql): add transaction isolation level
support (#3760)
fdf92e044 is described below
commit fdf92e0443f5000a1fe94ae08a30bca849fb0cc3
Author: Mandukhai Alimaa <[email protected]>
AuthorDate: Sun Nov 30 00:56:44 2025 -0600
feat(c/driver/postgresql): add transaction isolation level support (#3760)
---
c/driver/postgresql/connection.cc | 27 +++++++++++++++++++++++++++
c/driver/postgresql/postgresql_test.cc | 27 +++++++++++++++++++++++++++
2 files changed, 54 insertions(+)
diff --git a/c/driver/postgresql/connection.cc
b/c/driver/postgresql/connection.cc
index 6ac879e3b..ad4433b04 100644
--- a/c/driver/postgresql/connection.cc
+++ b/c/driver/postgresql/connection.cc
@@ -1213,6 +1213,33 @@ AdbcStatusCode PostgresConnection::SetOption(const char*
key, const char* value,
PqResultHelper result_helper{conn_, query};
RAISE_STATUS(error, result_helper.Execute());
return ADBC_STATUS_OK;
+ } else if (std::strcmp(key, ADBC_CONNECTION_OPTION_ISOLATION_LEVEL) == 0) {
+ if (!conn_) {
+ post_init_options_.emplace_back(key, value);
+ return ADBC_STATUS_OK;
+ }
+
+ std::string pg_level;
+ if (std::strcmp(value, ADBC_OPTION_ISOLATION_LEVEL_DEFAULT) == 0) {
+ pg_level = "READ COMMITTED"; // PostgreSQL default
+ } else if (std::strcmp(value,
ADBC_OPTION_ISOLATION_LEVEL_READ_UNCOMMITTED) == 0) {
+ pg_level = "READ UNCOMMITTED";
+ } else if (std::strcmp(value, ADBC_OPTION_ISOLATION_LEVEL_READ_COMMITTED)
== 0) {
+ pg_level = "READ COMMITTED";
+ } else if (std::strcmp(value, ADBC_OPTION_ISOLATION_LEVEL_REPEATABLE_READ)
== 0) {
+ pg_level = "REPEATABLE READ";
+ } else if (std::strcmp(value, ADBC_OPTION_ISOLATION_LEVEL_SERIALIZABLE) ==
0) {
+ pg_level = "SERIALIZABLE";
+ } else {
+ InternalAdbcSetError(error, "[libpq] Invalid isolation level: %s",
value);
+ return ADBC_STATUS_INVALID_ARGUMENT;
+ }
+
+ std::string query = fmt::format(
+ "SET SESSION CHARACTERISTICS AS TRANSACTION ISOLATION LEVEL {}",
pg_level);
+ PqResultHelper result_helper{conn_, query};
+ RAISE_STATUS(error, result_helper.Execute());
+ return ADBC_STATUS_OK;
}
InternalAdbcSetError(error, "%s%s", "[libpq] Unknown option ", key);
return ADBC_STATUS_NOT_IMPLEMENTED;
diff --git a/c/driver/postgresql/postgresql_test.cc
b/c/driver/postgresql/postgresql_test.cc
index 2a80f9287..b11be3df0 100644
--- a/c/driver/postgresql/postgresql_test.cc
+++ b/c/driver/postgresql/postgresql_test.cc
@@ -1082,6 +1082,33 @@ TEST_F(PostgresStatementTest, TransactionStatus) {
}
}
+TEST_F(PostgresStatementTest, IsolationLevels) {
+ ASSERT_THAT(AdbcConnectionSetOption(&connection,
ADBC_CONNECTION_OPTION_ISOLATION_LEVEL,
+
ADBC_OPTION_ISOLATION_LEVEL_SERIALIZABLE, &error),
+ IsOkStatus(&error));
+
+ ASSERT_THAT(AdbcConnectionSetOption(&connection,
ADBC_CONNECTION_OPTION_AUTOCOMMIT,
+ ADBC_OPTION_VALUE_DISABLED, &error),
+ IsOkStatus(&error));
+
+ ASSERT_THAT(AdbcStatementNew(&connection, &statement, &error),
IsOkStatus(&error));
+ ASSERT_THAT(AdbcStatementSetSqlQuery(
+ &statement, "SELECT
current_setting('transaction_isolation')", &error),
+ IsOkStatus(&error));
+
+ adbc_validation::StreamReader reader;
+ ASSERT_THAT(
+ AdbcStatementExecuteQuery(&statement, &reader.stream.value, nullptr,
&error),
+ IsOkStatus(&error));
+ ASSERT_NO_FATAL_FAILURE(reader.GetSchema());
+ ASSERT_NO_FATAL_FAILURE(reader.Next());
+
+ ASSERT_EQ(reader.array->length, 1);
+ ArrowStringView view =
ArrowArrayViewGetStringUnsafe(reader.array_view->children[0], 0);
+ std::string_view isolation_level(view.data,
static_cast<size_t>(view.size_bytes));
+ ASSERT_EQ(isolation_level, "serializable");
+}
+
TEST_F(PostgresStatementTest, SqlIngestSchema) {
const std::string schema_name = "testschema";