-- 087_fdw_server_options.sql -- Issue #769 Part B (finding #13) — FDW server performance options. -- -- Context: -- SERVER gendesign_remote was created by 060_postgres_fdw_extension.sql. -- The current options are: host, dbname, port, extensions, connect_timeout. -- Two planning options are missing: -- fetch_size — rows fetched per round-trip (default 100, raise to 10000 -- for bulk cursor-based pagination in import_rosreestr_dkp). -- use_remote_estimate — let planner query ANALYZE stats from the remote server -- to produce accurate cost estimates for the 6.8M-row -- rosreestr_deals foreign table and quarter_price_index MV. -- -- Idempotency: -- ALTER SERVER ... OPTIONS (ADD ...) raises ERROR if the option already exists. -- ALTER SERVER ... OPTIONS (SET ...) raises ERROR if the option does not exist yet. -- Therefore a DO $$ block checks pg_foreign_server.srvoptions for each option: -- - If present → SET (update the value in case it was previously set differently). -- - If absent → ADD (insert for the first time). -- This is safe to run repeatedly regardless of prior state. -- -- Dependencies: -- 060_postgres_fdw_extension.sql (gendesign_remote server must exist). -- -- Deploy order: -- Apply after 060_postgres_fdw_extension.sql. No FDW USER MAPPING changes required. -- Effect is immediate — next FDW query uses the new planner options. BEGIN; DO $$ DECLARE v_opts text[]; BEGIN -- Read current srvoptions array for gendesign_remote. SELECT COALESCE(srvoptions, ARRAY[]::text[]) INTO v_opts FROM pg_foreign_server WHERE srvname = 'gendesign_remote'; IF NOT FOUND THEN RAISE EXCEPTION 'FDW server gendesign_remote not found — apply 060_postgres_fdw_extension.sql first'; END IF; -- fetch_size: rows per FDW cursor round-trip (default 100 → 10000) IF v_opts @> ARRAY['fetch_size=10000'] THEN NULL; -- already correct value, no-op ELSIF EXISTS ( SELECT 1 FROM unnest(v_opts) AS opt WHERE opt LIKE 'fetch_size=%' ) THEN ALTER SERVER gendesign_remote OPTIONS (SET fetch_size '10000'); ELSE ALTER SERVER gendesign_remote OPTIONS (ADD fetch_size '10000'); END IF; -- use_remote_estimate: push ANALYZE stats collection to remote for better plans IF v_opts @> ARRAY['use_remote_estimate=true'] THEN NULL; -- already correct value, no-op ELSIF EXISTS ( SELECT 1 FROM unnest(v_opts) AS opt WHERE opt LIKE 'use_remote_estimate=%' ) THEN ALTER SERVER gendesign_remote OPTIONS (SET use_remote_estimate 'true'); ELSE ALTER SERVER gendesign_remote OPTIONS (ADD use_remote_estimate 'true'); END IF; END $$; COMMIT;