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 f3ef53d8 feat(c/driver/postgresql): Implement GetObjects for tables 
(#712)
f3ef53d8 is described below

commit f3ef53d8f2c02a6fdc96cccf582a70b0adb5a855
Author: William Ayd <[email protected]>
AuthorDate: Wed May 31 07:48:49 2023 -0700

    feat(c/driver/postgresql): Implement GetObjects for tables (#712)
    
    You've mentioned a few other times that we need to start using a
    prepared statement instead of string appends for handling queries. Think
    we've hit that point with this PR.
    
    Current plan is to make that prepared statement usage part of the
    `PqResultHelper` in a pre-cursor to this, but I think the overall
    structure of this is still reviewable
---
 c/driver/postgresql/connection.cc      | 70 +++++++++++++++++++++++++++++++++-
 c/driver/postgresql/postgresql_test.cc |  1 -
 2 files changed, 69 insertions(+), 2 deletions(-)

diff --git a/c/driver/postgresql/connection.cc 
b/c/driver/postgresql/connection.cc
index e7fa5911..326d5561 100644
--- a/c/driver/postgresql/connection.cc
+++ b/c/driver/postgresql/connection.cc
@@ -203,6 +203,11 @@ class PqGetObjectsHelper {
     catalog_db_schemas_items_ = catalog_db_schemas_col_->children[0];
     db_schema_name_col_ = catalog_db_schemas_items_->children[0];
     db_schema_tables_col_ = catalog_db_schemas_items_->children[1];
+    schema_table_items_ = db_schema_tables_col_->children[0];
+    table_name_col_ = schema_table_items_->children[0];
+    table_type_col_ = schema_table_items_->children[1];
+    table_columns_col_ = schema_table_items_->children[2];
+    table_constraints_col_ = schema_table_items_->children[3];
 
     RAISE_ADBC(AppendCatalogs());
     RAISE_ADBC(FinishArrowArray());
@@ -259,7 +264,7 @@ class PqGetObjectsHelper {
                  ArrowArrayAppendString(db_schema_name_col_, 
ArrowCharView(schema_name)),
                  error_);
         if (depth_ >= ADBC_OBJECT_DEPTH_TABLES) {
-          return ADBC_STATUS_NOT_IMPLEMENTED;
+          RAISE_ADBC(AppendTables(std::string(schema_name)));
         } else {
           CHECK_NA(INTERNAL, ArrowArrayAppendNull(db_schema_tables_col_, 1), 
error_);
         }
@@ -310,6 +315,64 @@ class PqGetObjectsHelper {
     return ADBC_STATUS_OK;
   }
 
+  AdbcStatusCode AppendTables(std::string schema_name) {
+    struct StringBuilder query = {0};
+    if (StringBuilderInit(&query, /*initial_size*/ 512)) {
+      return ADBC_STATUS_INTERNAL;
+    }
+
+    std::vector<std::string> params = {schema_name};
+    const char* stmt =
+        "SELECT c.relname, CASE c.relkind WHEN 'r' THEN 'table' WHEN 'v' THEN 
'view' "
+        "WHEN 'm' THEN 'materialized view' WHEN 't' THEN 'TOAST table' "
+        "WHEN 'f' THEN 'foreign table' WHEN 'p' THEN 'partitioned table' END "
+        "AS reltype FROM pg_catalog.pg_class c "
+        "LEFT JOIN pg_catalog.pg_namespace n ON n.oid = c.relnamespace "
+        "WHERE c.relkind IN ('r','v','m','t','f','p') "
+        "AND pg_catalog.pg_table_is_visible(c.oid) AND n.nspname = $1";
+
+    if (StringBuilderAppend(&query, "%s", stmt)) {
+      StringBuilderReset(&query);
+      return ADBC_STATUS_INTERNAL;
+    }
+
+    if (table_name_ != NULL) {
+      if (StringBuilderAppend(&query, "%s", " AND c.relname LIKE $2")) {
+        StringBuilderReset(&query);
+        return ADBC_STATUS_INTERNAL;
+      }
+
+      params.push_back(std::string(table_name_));
+    }
+
+    auto result_helper = PqResultHelper{conn_, query.buffer, params, error_};
+    StringBuilderReset(&query);
+
+    RAISE_ADBC(result_helper.Prepare());
+    RAISE_ADBC(result_helper.Execute());
+    for (PqResultRow row : result_helper) {
+      const char* table_name = row[0].data;
+      const char* table_type = row[1].data;
+
+      if (depth_ > ADBC_OBJECT_DEPTH_TABLES) {
+        return ADBC_STATUS_NOT_IMPLEMENTED;
+      } else {
+        CHECK_NA(INTERNAL,
+                 ArrowArrayAppendString(table_name_col_, 
ArrowCharView(table_name)),
+                 error_);
+        CHECK_NA(INTERNAL,
+                 ArrowArrayAppendString(table_type_col_, 
ArrowCharView(table_type)),
+                 error_);
+        CHECK_NA(INTERNAL, ArrowArrayAppendNull(table_columns_col_, 1), 
error_);
+        CHECK_NA(INTERNAL, ArrowArrayAppendNull(table_constraints_col_, 1), 
error_);
+      }
+      CHECK_NA(INTERNAL, ArrowArrayFinishElement(schema_table_items_), error_);
+    }
+
+    CHECK_NA(INTERNAL, ArrowArrayFinishElement(db_schema_tables_col_), error_);
+    return ADBC_STATUS_OK;
+  }
+
   AdbcStatusCode FinishArrowArray() {
     CHECK_NA_DETAIL(INTERNAL, ArrowArrayFinishBuildingDefault(array_, 
&na_error_),
                     &na_error_, error_);
@@ -334,6 +397,11 @@ class PqGetObjectsHelper {
   struct ArrowArray* catalog_db_schemas_items_;
   struct ArrowArray* db_schema_name_col_;
   struct ArrowArray* db_schema_tables_col_;
+  struct ArrowArray* schema_table_items_;
+  struct ArrowArray* table_name_col_;
+  struct ArrowArray* table_type_col_;
+  struct ArrowArray* table_columns_col_;
+  struct ArrowArray* table_constraints_col_;
 };
 
 }  // namespace
diff --git a/c/driver/postgresql/postgresql_test.cc 
b/c/driver/postgresql/postgresql_test.cc
index 39859e68..496bec01 100644
--- a/c/driver/postgresql/postgresql_test.cc
+++ b/c/driver/postgresql/postgresql_test.cc
@@ -86,7 +86,6 @@ class PostgresConnectionTest : public ::testing::Test,
   void SetUp() override { ASSERT_NO_FATAL_FAILURE(SetUpTest()); }
   void TearDown() override { ASSERT_NO_FATAL_FAILURE(TearDownTest()); }
 
-  void TestMetadataGetObjectsTables() { GTEST_SKIP() << "Not yet implemented"; 
}
   void TestMetadataGetObjectsTablesTypes() { GTEST_SKIP() << "Not yet 
implemented"; }
   void TestMetadataGetObjectsColumns() { GTEST_SKIP() << "Not yet 
implemented"; }
 

Reply via email to