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
diff --git a/c/driver/postgresql/connection.cc b/c/driver/postgresql/connection.cc
index e7fa591..326d556 100644
--- a/c/driver/postgresql/connection.cc
+++ b/c/driver/postgresql/connection.cc
@@ -203,6 +203,11 @@
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 @@
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 @@
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 @@
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 39859e6..496bec0 100644
--- a/c/driver/postgresql/postgresql_test.cc
+++ b/c/driver/postgresql/postgresql_test.cc
@@ -86,7 +86,6 @@
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"; }