in c/driver/postgresql/connection.cc [334:432]
AdbcStatusCode AppendTables(std::string schema_name) {
struct StringBuilder query;
std::memset(&query, 0, sizeof(query));
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_ != nullptr) {
if (StringBuilderAppend(&query, "%s", " AND c.relname LIKE $2")) {
StringBuilderReset(&query);
return ADBC_STATUS_INTERNAL;
}
params.push_back(std::string(table_name_));
}
if (table_types_ != nullptr) {
std::vector<std::string> table_type_filter;
const char** table_types = table_types_;
while (*table_types != NULL) {
auto table_type_str = std::string(*table_types);
auto search = kPgTableTypes.find(table_type_str);
if (search != kPgTableTypes.end()) {
table_type_filter.push_back(search->second);
}
table_types++;
}
if (!table_type_filter.empty()) {
std::ostringstream oss;
bool first = true;
oss << "(";
for (const auto& str : table_type_filter) {
if (!first) {
oss << ", ";
}
oss << "'" << str << "'";
first = false;
}
oss << ")";
if (StringBuilderAppend(&query, "%s%s", " AND c.relkind IN ",
oss.str().c_str())) {
StringBuilderReset(&query);
return ADBC_STATUS_INTERNAL;
}
} else {
// no matching table type means no records should come back
if (StringBuilderAppend(&query, "%s", " AND false")) {
StringBuilderReset(&query);
return ADBC_STATUS_INTERNAL;
}
}
}
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;
CHECK_NA(INTERNAL,
ArrowArrayAppendString(table_name_col_, ArrowCharView(table_name)),
error_);
CHECK_NA(INTERNAL,
ArrowArrayAppendString(table_type_col_, ArrowCharView(table_type)),
error_);
if (depth_ == ADBC_OBJECT_DEPTH_TABLES) {
CHECK_NA(INTERNAL, ArrowArrayAppendNull(table_columns_col_, 1), error_);
CHECK_NA(INTERNAL, ArrowArrayAppendNull(table_constraints_col_, 1), error_);
} else {
auto table_name_s = std::string(table_name);
RAISE_ADBC(AppendColumns(schema_name, table_name_s));
RAISE_ADBC(AppendConstraints(schema_name, table_name_s));
}
CHECK_NA(INTERNAL, ArrowArrayFinishElement(schema_table_items_), error_);
}
CHECK_NA(INTERNAL, ArrowArrayFinishElement(db_schema_tables_col_), error_);
return ADBC_STATUS_OK;
}