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 efe12aa1 ci: test multiple postgres versions (#1058)
efe12aa1 is described below

commit efe12aa1ff2b8e9acbb8cf381f26c3ad8aa5d1a4
Author: William Ayd <[email protected]>
AuthorDate: Fri Sep 15 14:24:25 2023 -0400

    ci: test multiple postgres versions (#1058)
    
    closes https://github.com/apache/arrow-adbc/issues/856
---
 .github/workflows/integration.yml      | 59 ++++++++++++++++++++++++++--------
 c/driver/postgresql/connection.cc      | 26 ++++++++++-----
 c/driver/postgresql/connection.h       |  5 +++
 c/driver/postgresql/postgresql_test.cc | 19 +++++++----
 c/validation/adbc_validation_util.cc   | 21 ++++++++++++
 c/validation/adbc_validation_util.h    |  3 ++
 docker-compose.yml                     |  7 +++-
 7 files changed, 110 insertions(+), 30 deletions(-)

diff --git a/.github/workflows/integration.yml 
b/.github/workflows/integration.yml
index f9fef8b2..710cd7a2 100644
--- a/.github/workflows/integration.yml
+++ b/.github/workflows/integration.yml
@@ -186,19 +186,6 @@ jobs:
   postgresql:
     name: "PostgreSQL Integration Tests"
     runs-on: ubuntu-latest
-    services:
-      postgres:
-        image: postgres
-        env:
-          POSTGRES_DB: tempdb
-          POSTGRES_PASSWORD: password
-        options: >-
-          --health-cmd pg_isready
-          --health-interval 10s
-          --health-timeout 5s
-          --health-retries 5
-        ports:
-          - 5432:5432
     steps:
       - uses: actions/checkout@v3
         with:
@@ -235,14 +222,56 @@ jobs:
           ADBC_USE_UBSAN: "OFF"
         run: |
           ./ci/scripts/cpp_build.sh "$(pwd)" "$(pwd)/build"
-      - name: Test PostgreSQL Driver
+      - name: Test PostgreSQL Driver - postgres 11
+        shell: bash -l {0}
+        env:
+          BUILD_ALL: "0"
+          BUILD_DRIVER_POSTGRESQL: "1"
+          ADBC_POSTGRESQL_TEST_URI: 
"postgresql://localhost:5432/postgres?user=postgres&password=password"
+        run: |
+          env POSTGRES_VERSION=11 docker compose up --wait --detach 
postgres-test
+          ./ci/scripts/cpp_test.sh "$(pwd)/build"
+          docker compose down
+      - name: Test PostgreSQL Driver - postgres 12
+        shell: bash -l {0}
+        env:
+          BUILD_ALL: "0"
+          BUILD_DRIVER_POSTGRESQL: "1"
+          ADBC_POSTGRESQL_TEST_URI: 
"postgresql://localhost:5432/postgres?user=postgres&password=password"
+        run: |
+          env POSTGRES_VERSION=12 docker compose up --wait --detach 
postgres-test
+          ./ci/scripts/cpp_test.sh "$(pwd)/build"
+          docker compose down
+      - name: Test PostgreSQL Driver - postgres 13
+        shell: bash -l {0}
+        env:
+          BUILD_ALL: "0"
+          BUILD_DRIVER_POSTGRESQL: "1"
+          ADBC_POSTGRESQL_TEST_URI: 
"postgresql://localhost:5432/postgres?user=postgres&password=password"
+        run: |
+          env POSTGRES_VERSION=13 docker compose up --wait --detach 
postgres-test
+          ./ci/scripts/cpp_test.sh "$(pwd)/build"
+          docker compose down
+      - name: Test PostgreSQL Driver - postgres 14
+        shell: bash -l {0}
+        env:
+          BUILD_ALL: "0"
+          BUILD_DRIVER_POSTGRESQL: "1"
+          ADBC_POSTGRESQL_TEST_URI: 
"postgresql://localhost:5432/postgres?user=postgres&password=password"
+        run: |
+          env POSTGRES_VERSION=14 docker compose up --wait --detach 
postgres-test
+          ./ci/scripts/cpp_test.sh "$(pwd)/build"
+          docker compose down
+      - name: Test PostgreSQL Driver - postgres 15
         shell: bash -l {0}
         env:
           BUILD_ALL: "0"
           BUILD_DRIVER_POSTGRESQL: "1"
           ADBC_POSTGRESQL_TEST_URI: 
"postgresql://localhost:5432/postgres?user=postgres&password=password"
         run: |
+          env POSTGRES_VERSION=15 docker compose up --wait --detach 
postgres-test
           ./ci/scripts/cpp_test.sh "$(pwd)/build"
+          docker compose down
 
       - name: Build Python PostgreSQL Driver
         shell: bash -l {0}
@@ -259,7 +288,9 @@ jobs:
           BUILD_DRIVER_POSTGRESQL: "1"
           ADBC_POSTGRESQL_TEST_URI: 
"postgresql://localhost:5432/postgres?user=postgres&password=password"
         run: |
+          docker compose up --wait --detach postgres-test
           ./ci/scripts/python_test.sh "$(pwd)" "$(pwd)/build"
+          docker compose down
 
   snowflake:
     name: "Snowflake Integration Tests"
diff --git a/c/driver/postgresql/connection.cc 
b/c/driver/postgresql/connection.cc
index 1e2f5c51..a9f74058 100644
--- a/c/driver/postgresql/connection.cc
+++ b/c/driver/postgresql/connection.cc
@@ -640,11 +640,9 @@ AdbcStatusCode PostgresConnection::Commit(struct 
AdbcError* error) {
   return ADBC_STATUS_OK;
 }
 
-AdbcStatusCode PostgresConnectionGetInfoImpl(const uint32_t* info_codes,
-                                             size_t info_codes_length,
-                                             struct ArrowSchema* schema,
-                                             struct ArrowArray* array,
-                                             struct AdbcError* error) {
+AdbcStatusCode PostgresConnection::PostgresConnectionGetInfoImpl(
+    const uint32_t* info_codes, size_t info_codes_length, struct ArrowSchema* 
schema,
+    struct ArrowArray* array, struct AdbcError* error) {
   RAISE_ADBC(AdbcInitConnectionGetInfoSchema(info_codes, info_codes_length, 
schema, array,
                                              error));
 
@@ -654,10 +652,22 @@ AdbcStatusCode PostgresConnectionGetInfoImpl(const 
uint32_t* info_codes,
         RAISE_ADBC(
             AdbcConnectionGetInfoAppendString(array, info_codes[i], 
"PostgreSQL", error));
         break;
-      case ADBC_INFO_VENDOR_VERSION:
-        RAISE_ADBC(AdbcConnectionGetInfoAppendString(
-            array, info_codes[i], std::to_string(PQlibVersion()).c_str(), 
error));
+      case ADBC_INFO_VENDOR_VERSION: {
+        const char* stmt = "SHOW server_version_num";
+        auto result_helper = PqResultHelper{conn_, std::string(stmt), error};
+        RAISE_ADBC(result_helper.Prepare());
+        RAISE_ADBC(result_helper.Execute());
+        auto it = result_helper.begin();
+        if (it == result_helper.end()) {
+          SetError(error, "[libpq] PostgreSQL returned no rows for '%s'", 
stmt);
+          return ADBC_STATUS_INTERNAL;
+        }
+        const char* server_version_num = (*it)[0].data;
+
+        RAISE_ADBC(AdbcConnectionGetInfoAppendString(array, info_codes[i],
+                                                     server_version_num, 
error));
         break;
+      }
       case ADBC_INFO_DRIVER_NAME:
         RAISE_ADBC(AdbcConnectionGetInfoAppendString(array, info_codes[i],
                                                      "ADBC PostgreSQL Driver", 
error));
diff --git a/c/driver/postgresql/connection.h b/c/driver/postgresql/connection.h
index 50d3ebe3..5e45e90b 100644
--- a/c/driver/postgresql/connection.h
+++ b/c/driver/postgresql/connection.h
@@ -75,6 +75,11 @@ class PostgresConnection {
   bool autocommit() const { return autocommit_; }
 
  private:
+  AdbcStatusCode PostgresConnectionGetInfoImpl(const uint32_t* info_codes,
+                                               size_t info_codes_length,
+                                               struct ArrowSchema* schema,
+                                               struct ArrowArray* array,
+                                               struct AdbcError* error);
   std::shared_ptr<PostgresDatabase> database_;
   std::shared_ptr<PostgresTypeResolver> type_resolver_;
   PGconn* conn_;
diff --git a/c/driver/postgresql/postgresql_test.cc 
b/c/driver/postgresql/postgresql_test.cc
index 24871e80..2afc4dbb 100644
--- a/c/driver/postgresql/postgresql_test.cc
+++ b/c/driver/postgresql/postgresql_test.cc
@@ -126,9 +126,6 @@ class PostgresQuirks : public adbc_validation::DriverQuirks 
{
         return "(unknown)";
       case ADBC_INFO_VENDOR_NAME:
         return "PostgreSQL";
-      case ADBC_INFO_VENDOR_VERSION:
-        // Strings are checked via substring match
-        return "15";
       default:
         return std::nullopt;
     }
@@ -432,11 +429,12 @@ TEST_F(PostgresConnectionTest, 
GetObjectsGetAllFindsForeignKey) {
       << "expected 1 constraint on adbc_fkey_test table, found: "
       << table->n_table_constraints;
 
+  const std::string version = 
adbc_validation::GetDriverVendorVersion(&connection);
+  const std::string search_name =
+      version < "120000" ? "adbc_fkey_test_fid1_fkey" : 
"adbc_fkey_test_fid1_fid2_fkey";
   struct AdbcGetObjectsConstraint* constraint = 
AdbcGetObjectsDataGetConstraintByName(
-      *get_objects_data, "postgres", "public", "adbc_fkey_test",
-      "adbc_fkey_test_fid1_fid2_fkey");
-  ASSERT_NE(constraint, nullptr)
-      << "could not find adbc_fkey_test_fid1_fid2_fkey constraint";
+      *get_objects_data, "postgres", "public", "adbc_fkey_test", 
search_name.c_str());
+  ASSERT_NE(constraint, nullptr) << "could not find " << search_name << " 
constraint";
 
   auto constraint_type = std::string(constraint->constraint_type.data,
                                      constraint->constraint_type.size_bytes);
@@ -1283,6 +1281,13 @@ class PostgresTypeTest : public 
::testing::TestWithParam<TypeTestCase> {
 };
 
 TEST_P(PostgresTypeTest, SelectValue) {
+  std::string value = GetParam().sql_literal;
+  if ((value == "'-inf'") || (value == "'inf'")) {
+    const std::string version = 
adbc_validation::GetDriverVendorVersion(&connection_);
+    if (version < "140000") {
+      GTEST_SKIP() << "-inf and inf not implemented until postgres 14";
+    }
+  }
   // create table
   std::string query = "CREATE TABLE foo (col ";
   query += GetParam().sql_type;
diff --git a/c/validation/adbc_validation_util.cc 
b/c/validation/adbc_validation_util.cc
index 7978947f..b3ca7d5e 100644
--- a/c/validation/adbc_validation_util.cc
+++ b/c/validation/adbc_validation_util.cc
@@ -242,4 +242,25 @@ void CompareSchema(
   }
 }
 
+std::string GetDriverVendorVersion(struct AdbcConnection* connection) {
+  const uint32_t info_code = ADBC_INFO_VENDOR_VERSION;
+  const uint32_t info[] = {info_code};
+
+  adbc_validation::StreamReader reader;
+  struct AdbcError error = ADBC_ERROR_INIT;
+  AdbcConnectionGetInfo(connection, info, 1, &reader.stream.value, &error);
+  reader.GetSchema();
+  if (error.release) {
+    error.release(&error);
+    throw std::runtime_error("error occured calling AdbcConnectionGetInfo!");
+  }
+
+  reader.Next();
+  const ArrowStringView raw_version =
+      
ArrowArrayViewGetStringUnsafe(reader.array_view->children[1]->children[0], 0);
+  const std::string version(raw_version.data, raw_version.size_bytes);
+
+  return version;
+}
+
 }  // namespace adbc_validation
diff --git a/c/validation/adbc_validation_util.h 
b/c/validation/adbc_validation_util.h
index 5c89fa25..b6376593 100644
--- a/c/validation/adbc_validation_util.h
+++ b/c/validation/adbc_validation_util.h
@@ -405,4 +405,7 @@ void CompareSchema(
     struct ArrowSchema* schema,
     const std::vector<std::tuple<std::optional<std::string>, ArrowType, 
bool>>& fields);
 
+/// \brief Helper method to get the vendor version of a driver
+std::string GetDriverVendorVersion(struct AdbcConnection* connection);
+
 }  // namespace adbc_validation
diff --git a/docker-compose.yml b/docker-compose.yml
index 34aed8bb..a25fb665 100644
--- a/docker-compose.yml
+++ b/docker-compose.yml
@@ -181,9 +181,14 @@ services:
 
   postgres-test:
     container_name: adbc_postgres_test
-    image: postgres:latest
+    image: postgres:${POSTGRES_VERSION:-latest}
     environment:
       POSTGRES_USER: postgres
       POSTGRES_PASSWORD: password
+    healthcheck:
+      test: ["CMD-SHELL", "pg_isready"]
+      interval: 10s
+      timeout: 5s
+      retries: 5
     ports:
       - "5432:5432"

Reply via email to