From 1fa123ee5c0a535d56eb0d12ea769a0409c0322a Mon Sep 17 00:00:00 2001 From: kssenii Date: Sat, 23 Oct 2021 01:33:17 +0300 Subject: [PATCH] Properly done --- .../PostgreSQL/DatabasePostgreSQL.cpp | 21 +++++++++++++------ .../fetchPostgreSQLTableStructure.cpp | 12 +++++++++-- .../PostgreSQLReplicationHandler.cpp | 14 ++++++++++++- 3 files changed, 38 insertions(+), 9 deletions(-) diff --git a/src/Databases/PostgreSQL/DatabasePostgreSQL.cpp b/src/Databases/PostgreSQL/DatabasePostgreSQL.cpp index d671a2b87d7..5d3493d0c82 100644 --- a/src/Databases/PostgreSQL/DatabasePostgreSQL.cpp +++ b/src/Databases/PostgreSQL/DatabasePostgreSQL.cpp @@ -90,14 +90,23 @@ bool DatabasePostgreSQL::empty() const DatabaseTablesIteratorPtr DatabasePostgreSQL::getTablesIterator(ContextPtr local_context, const FilterByNameFunction & /* filter_by_table_name */) const { std::lock_guard lock(mutex); - Tables tables; - auto connection_holder = pool->get(); - auto table_names = fetchPostgreSQLTablesList(connection_holder->get(), configuration.schema); - for (const auto & table_name : table_names) - if (!detached_or_dropped.count(table_name)) - tables[table_name] = fetchTable(table_name, local_context, true); + /// Do not allow to throw here, because this might be, for example, a query to system.tables. + /// It must not fail on case of some postgres error. + try + { + auto connection_holder = pool->get(); + auto table_names = fetchPostgreSQLTablesList(connection_holder->get(), configuration.schema); + + for (const auto & table_name : table_names) + if (!detached_or_dropped.count(table_name)) + tables[table_name] = fetchTable(table_name, local_context, true); + } + catch (...) + { + tryLogCurrentException(__PRETTY_FUNCTION__); + } return std::make_unique(tables, database_name); } diff --git a/src/Databases/PostgreSQL/fetchPostgreSQLTableStructure.cpp b/src/Databases/PostgreSQL/fetchPostgreSQLTableStructure.cpp index fd6b69e39f9..feb472fa152 100644 --- a/src/Databases/PostgreSQL/fetchPostgreSQLTableStructure.cpp +++ b/src/Databases/PostgreSQL/fetchPostgreSQLTableStructure.cpp @@ -191,7 +191,10 @@ std::shared_ptr readNamesAndTypesList( columns[i] = NameAndTypePair(name_and_type.name, type); } } - + catch (const pqxx::syntax_error & e) + { + throw Exception(ErrorCodes::BAD_ARGUMENTS, "Error: {} (in query: {})", e.what(), query); + } catch (const pqxx::undefined_table &) { throw Exception(ErrorCodes::UNKNOWN_TABLE, "PostgreSQL table {} does not exist", postgres_table); @@ -213,7 +216,9 @@ PostgreSQLTableStructure fetchPostgreSQLTableStructure( PostgreSQLTableStructure table; auto where = fmt::format("relname = {}", quoteString(postgres_table)); - if (!postgres_schema.empty()) + if (postgres_schema.empty()) + where += " AND relnamespace = (SELECT oid FROM pg_namespace WHERE nspname = 'public')"; + else where += fmt::format(" AND relnamespace = (SELECT oid FROM pg_namespace WHERE nspname = {})", quoteString(postgres_schema)); std::string query = fmt::format( @@ -225,6 +230,9 @@ PostgreSQLTableStructure fetchPostgreSQLTableStructure( table.columns = readNamesAndTypesList(tx, postgres_table, query, use_nulls, false); + if (!table.columns) + throw Exception(ErrorCodes::UNKNOWN_TABLE, "PostgreSQL table {} does not exist", postgres_table); + if (with_primary_key) { /// wiki.postgresql.org/wiki/Retrieve_primary_key_columns diff --git a/src/Storages/PostgreSQL/PostgreSQLReplicationHandler.cpp b/src/Storages/PostgreSQL/PostgreSQLReplicationHandler.cpp index 3262a302f9f..670148e9baa 100644 --- a/src/Storages/PostgreSQL/PostgreSQLReplicationHandler.cpp +++ b/src/Storages/PostgreSQL/PostgreSQLReplicationHandler.cpp @@ -230,6 +230,8 @@ ASTPtr PostgreSQLReplicationHandler::getCreateNestedTableQuery(StorageMaterializ postgres::Connection connection(connection_info); pqxx::nontransaction tx(connection.getRef()); auto table_structure = std::make_unique(fetchPostgreSQLTableStructure(tx, table_name, postgres_schema, true, true, true)); + if (!table_structure) + throw Exception(ErrorCodes::LOGICAL_ERROR, "Failed to get PostgreSQL table structure"); return storage->getCreateNestedTableQuery(std::move(table_structure)); } @@ -649,7 +651,17 @@ PostgreSQLTableStructurePtr PostgreSQLReplicationHandler::fetchTableStructure( if (!is_materialized_postgresql_database) return nullptr; - return std::make_unique(fetchPostgreSQLTableStructure(tx, table_name, postgres_schema, true, true, true)); + PostgreSQLTableStructure structure; + try + { + structure = fetchPostgreSQLTableStructure(tx, table_name, postgres_schema, true, true, true); + } + catch (...) + { + tryLogCurrentException(__PRETTY_FUNCTION__); + } + + return std::make_unique(std::move(structure)); }