Changed-lines coverage: PR changed C/C++ lines covered by tests: 75.78% (97/128) Uncovered changed code (with context): ================================================================================ src/Storages/PostgreSQL/PostgreSQLReplicationHandler.cpp ================================================================================ --- uncovered block 365-373 --- 363 | throw; 364 | >> 365 | LOG_ERROR(log, "Unable to set up connection. Reconnection attempt will continue. Error message: {}", pqxx_error.what()); >> 366 | startup_task->scheduleAfter(milliseconds_to_wait); 367 | } 368 | catch (const Exception & e) 369 | { >> 370 | tryLogCurrentException(log); 371 | >> 372 | if (!is_attach) >> 373 | throw; 374 | 375 | /// On attach the startup task must keep retrying on any error so replication starts on its own once --- uncovered block 385-402 --- 383 | /// persists, so no re-snapshot can happen in the meantime. This mirrors the database-engine path, 384 | /// which retries via DatabaseMaterializedPostgreSQL::tryStartSynchronization. >> 385 | if (e.code() == ErrorCodes::POSTGRESQL_REPLICATION_INTERNAL_ERROR) >> 386 | LOG_ERROR(log, "Replication cannot start yet. Retry attempt will continue. Error message: {}", e.message()); 387 | else >> 388 | LOG_ERROR(log, "Failed to start replication, retry attempt will continue. Error message: {}", e.message()); >> 389 | startup_task->scheduleAfter(milliseconds_to_wait); 390 | } 391 | catch (...) 392 | { >> 393 | tryLogCurrentException(log); 394 | >> 395 | if (!is_attach) >> 396 | throw; 397 | 398 | /// A non-Exception failure on attach (e.g. a pqxx::sql_error such as "replication slot is active for 399 | /// PID N" when a just-released connection still holds the slot) is transient too - keep retrying so 400 | /// replication resumes on its own, matching the Exception branch above and the database-engine path. >> 401 | LOG_ERROR(log, "Failed to start replication, retry attempt will continue. Error message: {}", getCurrentExceptionMessage(false)); >> 402 | startup_task->scheduleAfter(milliseconds_to_wait); 403 | } 404 | } --- uncovered block 485-486 --- 483 | /// The slot name does not depend on the schema, so the publication is the only renamed object 484 | /// and carries the evidence instead. >> 485 | if (publication_exists(publication_name) || !publication_exists(legacy_publication_name)) >> 486 | return; 487 | } 488 | --- uncovered block 504-516 --- 502 | String ownership_conflict; 503 | if (!publication_exists(legacy_publication_name)) >> 504 | ownership_conflict = fmt::format( >> 505 | "the legacy publication {} does not exist, so the schema-blind legacy replication slot cannot be " >> 506 | "proven to belong to this engine's schema '{}'", >> 507 | doubleQuoteString(legacy_publication_name), postgres_schema); 508 | else 509 | { 510 | pqxx::result result{tx.exec(fmt::format( 511 | "SELECT DISTINCT schemaname FROM pg_publication_tables WHERE pubname = '{}'", legacy_publication_name))}; 512 | if (result.empty()) >> 513 | ownership_conflict = fmt::format( >> 514 | "the legacy publication {} publishes no tables, so the schema-blind legacy replication slot " >> 515 | "cannot be proven to belong to this engine's schema '{}'", >> 516 | doubleQuoteString(legacy_publication_name), postgres_schema); 517 | for (const auto & row : result) 518 | { --- uncovered block 939-945 --- 937 | /// and a slot caught mid-creation becomes ready by the next attempt. 938 | if (result[0][1].is_null() || result[0][2].is_null()) >> 939 | throw Exception( >> 940 | ErrorCodes::POSTGRESQL_REPLICATION_INTERNAL_ERROR, >> 941 | "Replication slot {} exists, but it is not ready: restart_lsn is {}, confirmed_flush_lsn is {}. " >> 942 | "It is either still being created, or it is not a logical replication slot", >> 943 | slot_name, >> 944 | result[0][1].is_null() ? "NULL" : result[0][1].as(), >> 945 | result[0][2].is_null() ? "NULL" : result[0][2].as()); 946 | 947 | start_lsn = result[0][2].as(); WARNING: Failed to get start time for [Print Uncovered Code] - start time and duration won't be set --- Coverage counts --- Lines : baseline 886,440/1,031,738 -> current 885,776/1,031,863 (delta -664 / +125) Functions : baseline 950,231/1,025,473 -> current 950,214/1,025,480 (delta -17 / +7) Branches : baseline 286,635/367,008 -> current 286,320/367,062 (delta -315 / +54)