Step-by-step manual test scenarios for validating all pgclone functionalities on real infrastructure with two PostgreSQL instances.
Replace connection details with your actual servers.
| Parameter | Server 1 (Source) | Server 2 (Target) |
|---|---|---|
| IP Address | 172.17.0.2 |
172.17.0.3 |
| Port | 5432 |
5433 |
| Database | db1 |
db2 |
| User / Pass | postgres / 123654 |
postgres / 123654 |
| pgclone | Installed + preloaded | Installed + preloaded |
| Auth | scram-sha-256 |
scram-sha-256 |
Connection string used throughout:
host=172.17.0.2 port=5432 dbname=db1 user=postgres password=123654
All SQL commands run on Server 2 (Target) unless stated otherwise.
Connect to Server 1 and load the project seed file:
psql -h 172.17.0.2 -p 5432 -U postgres -d db1 -f test/fixtures/seed.sqlThis creates test_schema with tables (customers, orders, order_items, employees), indexes, constraints, triggers, views, materialized views, functions, sequences, roles (test_reader, test_writer, test_admin), and sample data.
psql -h 172.17.0.3 -p 5433 -U postgres -d db2
CREATE EXTENSION IF NOT EXISTS pgclone;
SELECT pgclone.version();
-- Expected: pgclone 3.6.0SELECT pgclone.version();Expected: pgclone 3.6.0
SELECT * FROM pg_extension WHERE extname = 'pgclone';Expected: One row with extname = 'pgclone'
SELECT pgclone.table(
'host=172.17.0.2 port=5432 dbname=db1 user=postgres password=123654',
'test_schema', 'customers', true
);Expected: OK: cloned test_schema.customers (10 rows)
SELECT COUNT(*) FROM test_schema.customers;Expected: 10
SELECT pgclone.table(
'host=172.17.0.2 port=5432 dbname=db1 user=postgres password=123654',
'test_schema', 'orders', false
);SELECT COUNT(*) FROM test_schema.orders;Expected: 0 (table exists but empty)
SELECT pgclone.table(
'host=172.17.0.2 port=5432 dbname=db1 user=postgres password=123654',
'test_schema', 'customers', true,
'customers_backup'
);SELECT COUNT(*) FROM test_schema.customers_backup;Expected: 10
SELECT pgclone.table(
'host=172.17.0.2 port=5432 dbname=db1 user=postgres password=123654',
'test_schema', 'customers', true,
'customers_lite',
'{"columns": ["id", "name", "email"]}'
);SELECT column_name FROM information_schema.columns
WHERE table_schema = 'test_schema' AND table_name = 'customers_lite'
ORDER BY ordinal_position;Expected: Only 3 columns: id, name, email
SELECT pgclone.table(
'host=172.17.0.2 port=5432 dbname=db1 user=postgres password=123654',
'test_schema', 'customers', true,
'active_customers_copy',
'{"where": "status = ''active''"}'
);SELECT COUNT(*) FROM test_schema.active_customers_copy;
SELECT DISTINCT status FROM test_schema.active_customers_copy;Expected: 7 rows, all with status = 'active'
SELECT pgclone.table(
'host=172.17.0.2 port=5432 dbname=db1 user=postgres password=123654',
'test_schema', 'customers', true,
'high_scorers',
'{"columns": ["id", "name", "score"], "where": "score >= 80"}'
);SELECT * FROM test_schema.high_scorers ORDER BY score DESC;Expected: Only rows with score >= 80, only 3 columns
DROP TABLE IF EXISTS test_schema.customers CASCADE;
SELECT pgclone.table(
'host=172.17.0.2 port=5432 dbname=db1 user=postgres password=123654',
'test_schema', 'customers', true,
'customers',
'{"indexes": false}'
);SELECT indexname FROM pg_indexes
WHERE schemaname = 'test_schema' AND tablename = 'customers';Expected: Only PK index (customers_pkey). No idx_customers_status or idx_customers_name_lower.
DROP TABLE IF EXISTS test_schema.order_items CASCADE;
DROP TABLE IF EXISTS test_schema.orders CASCADE;
SELECT pgclone.table(
'host=172.17.0.2 port=5432 dbname=db1 user=postgres password=123654',
'test_schema', 'orders', true,
'orders',
'{"constraints": false}'
);SELECT conname, contype FROM pg_constraint
WHERE conrelid = 'test_schema.orders'::regclass;Expected: No FK or CHECK constraints (only PK remains)
DROP TABLE IF EXISTS test_schema.orders CASCADE;
SELECT pgclone.table(
'host=172.17.0.2 port=5432 dbname=db1 user=postgres password=123654',
'test_schema', 'orders', true,
'orders',
'{"triggers": false}'
);SELECT tgname FROM pg_trigger
WHERE tgrelid = 'test_schema.orders'::regclass AND NOT tgisinternal;Expected: No triggers
DROP TABLE IF EXISTS test_schema.orders CASCADE;
SELECT pgclone.table_ex(
'host=172.17.0.2 port=5432 dbname=db1 user=postgres password=123654',
'test_schema', 'orders', true, 'orders',
false, -- skip indexes
true, -- include constraints
false -- skip triggers
);SELECT conname FROM pg_constraint WHERE conrelid = 'test_schema.orders'::regclass;
SELECT indexname FROM pg_indexes WHERE schemaname = 'test_schema' AND tablename = 'orders';
SELECT tgname FROM pg_trigger WHERE tgrelid = 'test_schema.orders'::regclass AND NOT tgisinternal;Expected: Constraints present (PK + FK). Only PK index. No triggers.
-- Table already exists from previous tests
SELECT pgclone.table(
'host=172.17.0.2 port=5432 dbname=db1 user=postgres password=123654',
'test_schema', 'customers', true
);Expected: ERROR — table already exists
SELECT pgclone.table(
'host=172.17.0.2 port=5432 dbname=db1 user=postgres password=123654',
'test_schema', 'customers', true,
'customers',
'{"conflict": "skip"}'
);Expected: Message indicating table was skipped
SELECT pgclone.table(
'host=172.17.0.2 port=5432 dbname=db1 user=postgres password=123654',
'test_schema', 'customers', true,
'customers',
'{"conflict": "replace"}'
);SELECT COUNT(*) FROM test_schema.customers;Expected: 10 (fresh clone after drop + re-create)
SELECT pgclone.table(
'host=172.17.0.2 port=5432 dbname=db1 user=postgres password=123654',
'test_schema', 'customers', true,
'customers',
'{"conflict": "rename"}'
);SELECT tablename FROM pg_tables
WHERE schemaname = 'test_schema' AND tablename LIKE 'customers%'
ORDER BY tablename;Expected: Both customers (new) and customers_old (renamed original)
DROP SCHEMA IF EXISTS test_schema CASCADE;
SELECT pgclone.schema(
'host=172.17.0.2 port=5432 dbname=db1 user=postgres password=123654',
'test_schema', true
);Verify all object types:
-- Tables
SELECT tablename FROM pg_tables WHERE schemaname = 'test_schema' ORDER BY tablename;
-- Row counts
SELECT 'customers' AS tbl, COUNT(*) FROM test_schema.customers
UNION ALL SELECT 'orders', COUNT(*) FROM test_schema.orders
UNION ALL SELECT 'order_items', COUNT(*) FROM test_schema.order_items
UNION ALL SELECT 'employees', COUNT(*) FROM test_schema.employees;
-- Views
SELECT viewname FROM pg_views WHERE schemaname = 'test_schema';
-- Materialized views
SELECT matviewname FROM pg_matviews WHERE schemaname = 'test_schema';
-- Functions
SELECT routine_name FROM information_schema.routines
WHERE routine_schema = 'test_schema' ORDER BY routine_name;
-- Sequences
SELECT sequencename FROM pg_sequences WHERE schemaname = 'test_schema';
-- Triggers
SELECT tgname FROM pg_trigger t
JOIN pg_class c ON t.tgrelid = c.oid
JOIN pg_namespace n ON c.relnamespace = n.oid
WHERE n.nspname = 'test_schema' AND NOT t.tgisinternal;
-- Indexes
SELECT indexname FROM pg_indexes WHERE schemaname = 'test_schema' ORDER BY indexname;Expected: All tables, views, materialized views, functions, sequences, triggers, and indexes present with correct data.
DROP SCHEMA IF EXISTS test_schema CASCADE;
SELECT pgclone.schema(
'host=172.17.0.2 port=5432 dbname=db1 user=postgres password=123654',
'test_schema', false
);SELECT 'customers' AS tbl, COUNT(*) FROM test_schema.customers
UNION ALL SELECT 'orders', COUNT(*) FROM test_schema.orders;Expected: All counts = 0
DROP SCHEMA IF EXISTS test_schema CASCADE;
SELECT pgclone.schema(
'host=172.17.0.2 port=5432 dbname=db1 user=postgres password=123654',
'test_schema', true,
'{"triggers": false, "indexes": false}'
);SELECT COUNT(*) FROM pg_trigger t
JOIN pg_class c ON t.tgrelid = c.oid
JOIN pg_namespace n ON c.relnamespace = n.oid
WHERE n.nspname = 'test_schema' AND NOT t.tgisinternal;Expected: Trigger count = 0. Only PK indexes present.
DROP SCHEMA IF EXISTS test_schema CASCADE;
SELECT pgclone.schema_ex(
'host=172.17.0.2 port=5432 dbname=db1 user=postgres password=123654',
'test_schema', true,
true, -- include indexes
false, -- skip constraints
true -- include triggers
);Expected: Indexes and triggers present. No FK/CHECK constraints (except PK).
DROP SCHEMA IF EXISTS test_schema CASCADE;
CREATE SCHEMA test_schema;
SELECT pgclone.functions(
'host=172.17.0.2 port=5432 dbname=db1 user=postgres password=123654',
'test_schema'
);SELECT routine_name, routine_type FROM information_schema.routines
WHERE routine_schema = 'test_schema' ORDER BY routine_name;Expected: Functions: get_customer_orders, log_order_change, update_timestamp
DROP SCHEMA IF EXISTS test_schema CASCADE;
DROP TABLE IF EXISTS public.simple_test CASCADE;
SELECT pgclone.database(
'host=172.17.0.2 port=5432 dbname=db1 user=postgres password=123654',
true
);SELECT schemaname, COUNT(*) AS table_count
FROM pg_tables
WHERE schemaname NOT IN ('pg_catalog', 'information_schema')
GROUP BY schemaname ORDER BY schemaname;Expected: Both public and test_schema tables cloned with data.
DROP SCHEMA IF EXISTS test_schema CASCADE;
DROP TABLE IF EXISTS public.simple_test CASCADE;
SELECT pgclone.database(
'host=172.17.0.2 port=5432 dbname=db1 user=postgres password=123654',
true,
'{"triggers": false}'
);Expected: All data cloned, no triggers on any table.
Run from the
postgresdatabase on Server 2, notdb2.
psql -h 172.17.0.3 -p 5433 -U postgres -d postgres
CREATE EXTENSION IF NOT EXISTS pgclone;
SELECT pgclone.database_create(
'host=172.17.0.2 port=5432 dbname=db1 user=postgres password=123654',
'db1_clone',
true
);\c db1_clone
SELECT schemaname, COUNT(*) AS table_count
FROM pg_tables
WHERE schemaname NOT IN ('pg_catalog', 'information_schema')
GROUP BY schemaname;Expected: New database db1_clone created with all schemas and data from source.
Masking is applied server-side during COPY — source data never stored unmasked on target.
SELECT pgclone.table(
'host=172.17.0.2 port=5432 dbname=db1 user=postgres password=123654',
'test_schema', 'employees', true,
'emp_email_masked',
'{"mask": {"email": "email"}}'
);
SELECT id, full_name, email FROM test_schema.emp_email_masked ORDER BY id;Expected: alice@example.com → a***@example.com
SELECT pgclone.table(
'host=172.17.0.2 port=5432 dbname=db1 user=postgres password=123654',
'test_schema', 'employees', true,
'emp_name_masked',
'{"mask": {"full_name": "name"}}'
);
SELECT id, full_name FROM test_schema.emp_name_masked ORDER BY id;Expected: All full_name = XXXX
SELECT pgclone.table(
'host=172.17.0.2 port=5432 dbname=db1 user=postgres password=123654',
'test_schema', 'employees', true,
'emp_phone_masked',
'{"mask": {"phone": "phone"}}'
);
SELECT id, phone FROM test_schema.emp_phone_masked ORDER BY id;Expected: +1-555-123-4567 → ***-4567. Eve's NULL phone stays NULL.
SELECT pgclone.table(
'host=172.17.0.2 port=5432 dbname=db1 user=postgres password=123654',
'test_schema', 'employees', true,
'emp_hash_masked',
'{"mask": {"email": "hash"}}'
);
SELECT id, email FROM test_schema.emp_hash_masked ORDER BY id;Expected: Emails are 32-character hex MD5 hashes. Same input → same hash (deterministic).
SELECT pgclone.table(
'host=172.17.0.2 port=5432 dbname=db1 user=postgres password=123654',
'test_schema', 'employees', true,
'emp_null_masked',
'{"mask": {"ssn": "null"}}'
);
SELECT id, ssn FROM test_schema.emp_null_masked ORDER BY id;Expected: All SSN values are NULL.
SELECT pgclone.table(
'host=172.17.0.2 port=5432 dbname=db1 user=postgres password=123654',
'test_schema', 'employees', true,
'emp_partial_masked',
'{"mask": {"full_name": {"type": "partial", "prefix": 2, "suffix": 3}}}'
);
SELECT id, full_name FROM test_schema.emp_partial_masked ORDER BY id;Expected: Alice Johnson → Al***son
SELECT pgclone.table(
'host=172.17.0.2 port=5432 dbname=db1 user=postgres password=123654',
'test_schema', 'employees', true,
'emp_rand_masked',
'{"mask": {"salary": {"type": "random_int", "min": 30000, "max": 150000}}}'
);
SELECT id, salary FROM test_schema.emp_rand_masked ORDER BY id;Expected: Salaries are random integers between 30000 and 150000.
SELECT pgclone.table(
'host=172.17.0.2 port=5432 dbname=db1 user=postgres password=123654',
'test_schema', 'employees', true,
'emp_const_masked',
'{"mask": {"notes": {"type": "constant", "value": "REDACTED"}}}'
);
SELECT id, notes FROM test_schema.emp_const_masked ORDER BY id;Expected: All notes = REDACTED (including previously NULL values).
SELECT pgclone.table(
'host=172.17.0.2 port=5432 dbname=db1 user=postgres password=123654',
'test_schema', 'employees', true,
'emp_full_masked',
'{"mask": {"email": "email", "full_name": "name", "phone": "phone", "ssn": "null", "salary": {"type": "random_int", "min": 40000, "max": 200000}, "notes": {"type": "constant", "value": "REDACTED"}}}'
);
SELECT * FROM test_schema.emp_full_masked ORDER BY id;Expected: All sensitive columns masked. id and created_at pass through unchanged.
SELECT pgclone.discover_sensitive(
'host=172.17.0.2 port=5432 dbname=db1 user=postgres password=123654',
'test_schema'
);Expected: JSON output with detected sensitive columns grouped by table, e.g.:
{"employees": {"email": "email", "full_name": "name", "phone": "phone", "salary": "random_int", "ssn": "null"}}The output can be used directly as the "mask" option in a clone call.
Apply masking to an already-existing local table.
DROP TABLE IF EXISTS test_schema.emp_for_static_mask;
SELECT pgclone.table(
'host=172.17.0.2 port=5432 dbname=db1 user=postgres password=123654',
'test_schema', 'employees', true,
'emp_for_static_mask'
);
-- Verify unmasked data
SELECT full_name, email, ssn FROM test_schema.emp_for_static_mask ORDER BY id;Expected: Original data visible.
SELECT pgclone.mask_in_place(
'test_schema', 'emp_for_static_mask',
'{"email": "email", "full_name": "name", "ssn": "null"}'
);Expected: OK: masked 5 rows in test_schema.emp_for_static_mask (3 columns)
SELECT full_name, email, ssn FROM test_schema.emp_for_static_mask ORDER BY id;Expected: full_name = XXXX, email masked, ssn = NULL
Role-based masking policies that preserve original data.
DROP TABLE IF EXISTS test_schema.employees CASCADE;
SELECT pgclone.table(
'host=172.17.0.2 port=5432 dbname=db1 user=postgres password=123654',
'test_schema', 'employees', true
);
DO $$
BEGIN
IF NOT EXISTS (SELECT 1 FROM pg_roles WHERE rolname = 'data_admin') THEN
CREATE ROLE data_admin WITH LOGIN PASSWORD 'admin123';
END IF;
END $$;SELECT pgclone.create_masking_policy(
'test_schema', 'employees',
'{"email": "email", "full_name": "name", "ssn": "null", "salary": {"type": "random_int", "min": 40000, "max": 200000}}',
'data_admin'
);Expected: OK. Creates test_schema.employees_masked view.
SELECT * FROM test_schema.employees_masked ORDER BY id;Expected: Masked data — XXXX names, masked emails, NULL ssn, random salaries.
SELECT full_name, email, ssn, salary FROM test_schema.employees ORDER BY id;Expected: Original data unchanged (Alice Johnson, alice@example.com, 123-45-6789, 95000).
SET ROLE data_admin;
SELECT full_name, email, ssn FROM test_schema.employees ORDER BY id;
RESET ROLE;Expected: data_admin can see original unmasked data via the base table.
SELECT pgclone.drop_masking_policy('test_schema', 'employees');
SELECT viewname FROM pg_views
WHERE schemaname = 'test_schema' AND viewname = 'employees_masked';Expected: No rows — view dropped, base table access restored to PUBLIC.
SELECT pgclone.clone_roles(
'host=172.17.0.2 port=5432 dbname=db1 user=postgres password=123654'
);Expected: OK: N roles created, N roles updated, N grants applied
SELECT rolname, rolcanlogin, rolcreatedb FROM pg_roles
WHERE rolname IN ('test_reader', 'test_writer', 'test_admin')
ORDER BY rolname;Expected: All three roles exist with correct attributes.
DROP ROLE IF EXISTS test_reader;
DROP ROLE IF EXISTS test_writer;
SELECT pgclone.clone_roles(
'host=172.17.0.2 port=5432 dbname=db1 user=postgres password=123654',
'test_reader, test_writer'
);SELECT rolname FROM pg_roles WHERE rolname IN ('test_reader', 'test_writer') ORDER BY rolname;Expected: test_reader and test_writer exist.
SELECT grantee, table_schema, table_name, privilege_type
FROM information_schema.table_privileges
WHERE grantee = 'test_reader' AND table_schema = 'test_schema'
ORDER BY table_name, privilege_type;Expected: test_reader has SELECT on all test_schema tables.
SELECT pgclone.clone_roles(
'host=172.17.0.2 port=5432 dbname=db1 user=postgres password=123654',
'test_admin'
);Expected: Returns with N roles updated. Attributes and password synced.
DROP SCHEMA IF EXISTS test_schema CASCADE;
SELECT pgclone.schema(
'host=172.17.0.2 port=5432 dbname=db1 user=postgres password=123654',
'test_schema', true
);SELECT * FROM pgclone.verify(
'host=172.17.0.2 port=5432 dbname=db1 user=postgres password=123654',
'test_schema'
);Expected: All tables show ✓ (matching row counts).
SELECT * FROM pgclone.verify(
'host=172.17.0.2 port=5432 dbname=db1 user=postgres password=123654'
);Expected: Rows for all tables across all user schemas.
DELETE FROM test_schema.customers WHERE id > 5;
ANALYZE test_schema.customers;
SELECT * FROM pgclone.verify(
'host=172.17.0.2 port=5432 dbname=db1 user=postgres password=123654',
'test_schema'
);Expected: customers shows ✗ — source_rows=10, target_rows=5.
SELECT * FROM pgclone.masking_report('test_schema');Expected: Lists sensitive columns with sensitivity categories (Email, PII - Name, Phone, Financial, National ID), mask_status = UNMASKED, and recommended strategies.
SELECT pgclone.create_masking_policy(
'test_schema', 'employees',
'{"email": "email", "full_name": "name", "ssn": "null"}',
'data_admin'
);
SELECT * FROM pgclone.masking_report('test_schema');Expected: Employee columns now show mask_status = MASKED (view).
-- Cleanup
SELECT pgclone.drop_masking_policy('test_schema', 'employees');Requires
shared_preload_libraries = 'pgclone'(already configured).
DROP TABLE IF EXISTS test_schema.customers CASCADE;
SELECT pgclone.table_async(
'host=172.17.0.2 port=5432 dbname=db1 user=postgres password=123654',
'test_schema', 'customers', true
);Expected: Returns a job_id (integer).
SELECT pgclone.progress(1);
SELECT * FROM pgclone.jobs_view;Expected: Shows status (pending/running/completed), rows_copied, progress_bar, elapsed_time.
DROP SCHEMA IF EXISTS test_schema CASCADE;
SELECT pgclone.schema_async(
'host=172.17.0.2 port=5432 dbname=db1 user=postgres password=123654',
'test_schema', true
);
SELECT job_id, status, schema_name, progress_bar FROM pgclone.jobs_view;Expected: Schema clone progress with table-level tracking.
SELECT pgclone.jobs();Expected: JSON array of all jobs.
SELECT pgclone.table_async(
'host=172.17.0.2 port=5432 dbname=db1 user=postgres password=123654',
'test_schema', 'customers', true,
'customers',
'{"conflict": "replace"}'
);Expected: Job starts, replaces existing table.
-- Start a clone and cancel it (use the returned job_id)
SELECT pgclone.schema_async(
'host=172.17.0.2 port=5432 dbname=db1 user=postgres password=123654',
'test_schema', true,
'{"conflict": "replace"}'
);
SELECT pgclone.cancel(3); -- use actual job_id
SELECT status FROM pgclone.jobs_view WHERE job_id = 3;Expected: status = 'cancelled'
SELECT pgclone.clear_jobs();
SELECT * FROM pgclone.jobs_view;Expected: Returns count of cleared jobs. Only running/pending jobs remain.
DROP SCHEMA IF EXISTS test_schema CASCADE;
SELECT pgclone.schema_async(
'host=172.17.0.2 port=5432 dbname=db1 user=postgres password=123654',
'test_schema', true,
'{"parallel": 4}'
);
SELECT job_id, status, op_type, table_name, progress_bar
FROM pgclone.jobs_view ORDER BY job_id;Expected: Parent job + up to 4 pool worker jobs visible.
-- After completion, verify
SELECT * FROM pgclone.verify(
'host=172.17.0.2 port=5432 dbname=db1 user=postgres password=123654',
'test_schema'
);Expected: All tables match source row counts.
DROP SCHEMA IF EXISTS test_schema CASCADE;
SELECT pgclone.schema_async(
'host=172.17.0.2 port=5432 dbname=db1 user=postgres password=123654',
'test_schema', true,
'{"parallel": 4, "conflict": "replace", "triggers": false}'
);Expected: Parallel clone completes without triggers.
SELECT pgclone.schema_async(
'host=172.17.0.2 port=5432 dbname=db1 user=postgres password=123654',
'test_schema', true,
'{"conflict": "replace"}'
);
-- Detailed progress function
SELECT * FROM pgclone.progress_detail();
-- Convenience view
SELECT job_id, status, schema_name, table_name,
pct_complete, progress_bar, elapsed_time
FROM pgclone.jobs_view;
-- Filter by status
SELECT job_id, status, elapsed_time FROM pgclone.jobs_view WHERE status = 'running';
SELECT job_id, error_message FROM pgclone.jobs_view WHERE status = 'failed';Expected: All columns visible — job_id, status, op_type, schema_name, table_name, current_phase, tables_total, tables_completed, rows_copied, bytes_copied, elapsed_ms, start_time, end_time, pct_complete, progress_bar, elapsed_time.
SELECT pgclone.table(
'host=192.168.99.99 dbname=nonexistent user=postgres password=wrong',
'public', 'test', true
);Expected: ERROR — connection failure.
SELECT pgclone.table(
'host=172.17.0.2 port=5432 dbname=db1 user=postgres password=123654',
'test_schema', 'this_table_does_not_exist', true
);Expected: ERROR — table not found.
SELECT pgclone.schema(
'host=172.17.0.2 port=5432 dbname=db1 user=postgres password=123654',
'nonexistent_schema', true
);Expected: ERROR — schema not found.
SELECT pgclone.table(
'host=172.17.0.2 port=5432 dbname=db1 user=postgres password=123654',
'test_schema', 'customers', true,
'injection_test',
'{"where": "1=1; DROP TABLE test_schema.customers; --"}'
);Expected: ERROR — DDL/DML keywords or semicolons rejected.
SELECT pgclone.table(
'host=172.17.0.2 port=5432 dbname=db1 user=postgres password=123654',
'test_schema', 'employees', true,
'emp_bad_mask',
'{"mask": {"email": "nonexistent_strategy"}}'
);Expected: ERROR — unknown mask strategy.
SELECT pgclone.table(
'host=172.17.0.2 port=5432 dbname=db1 user=postgres password=123654',
'test_schema', 'customers', true,
'json_test',
'{"invalid json'
);Expected: ERROR — invalid JSON.
-- On Server 2 (target), connected to db2
DROP SCHEMA IF EXISTS test_schema CASCADE;
DROP TABLE IF EXISTS public.simple_test CASCADE;
DROP ROLE IF EXISTS test_reader;
DROP ROLE IF EXISTS test_writer;
DROP ROLE IF EXISTS test_admin;
DROP ROLE IF EXISTS data_admin;
SELECT pgclone.clear_jobs();
-- To drop the cloned database (connect to postgres db first):
-- \c postgres
-- DROP DATABASE IF EXISTS db1_clone;