From 34c86514b262e808b7837f994c0da76acbf79a54 Mon Sep 17 00:00:00 2001 From: Rafia Sabih Date: Mon, 20 Jul 2026 14:44:32 +0530 Subject: [PATCH v7] Emit debug message for batch_size reduced In case batch_size is reduced to keep the parameter within limits of libpq, emit a debug message. Also emit a warning message when batch_size is set to a value over the limit. --- .../postgres_fdw/expected/postgres_fdw.out | 46 +++++++++++++++++++ contrib/postgres_fdw/option.c | 5 ++ contrib/postgres_fdw/postgres_fdw.c | 8 ++++ contrib/postgres_fdw/sql/postgres_fdw.sql | 46 +++++++++++++++++++ 4 files changed, 105 insertions(+) diff --git a/contrib/postgres_fdw/expected/postgres_fdw.out b/contrib/postgres_fdw/expected/postgres_fdw.out index 9303de98b62..237c26136ae 100644 --- a/contrib/postgres_fdw/expected/postgres_fdw.out +++ b/contrib/postgres_fdw/expected/postgres_fdw.out @@ -11684,6 +11684,52 @@ DROP TRIGGER ftable_rowcount_trigger ON ltable; DROP TABLE ltable; DROP TABLE parent; DROP FUNCTION ftable_rowcount_trigf; +-- Verify that DEBUG1 is emitted when batch_size is reduced to stay within +-- the libpq 65535-parameter limit. +SET client_min_messages = DEBUG1; +CREATE TABLE batch_table ( x int, y int ); +CREATE FOREIGN TABLE ftable ( x int, y int ) + SERVER loopback + OPTIONS (table_name 'batch_table', batch_size '33000'); +INSERT INTO ftable(x) VALUES (1); +DEBUG: batch_size reduced from 33000 to 32767 to stay within the libpq 65535-parameter limit +-- Clean up +DROP FOREIGN TABLE ftable; +DROP TABLE batch_table; +-- Verify that a WARNING is emitted when batch_size is set above the +-- libpq 65535-parameter limit. +CREATE TABLE batch_warn_table ( x int ); +CREATE FOREIGN TABLE ftable_warn ( x int ) + SERVER loopback + OPTIONS (table_name 'batch_warn_table', batch_size '65536'); +WARNING: batch_size of 65536 exceeds protocol limit of 65535 +DETAIL: The batch_size for a query will be reduced to protocol limit divided by the number of columns in the query. +INSERT INTO ftable_warn VALUES (1); +DEBUG: batch_size reduced from 65536 to 65535 to stay within the libpq 65535-parameter limit +-- Clean up +DROP FOREIGN TABLE ftable_warn; +DROP TABLE batch_warn_table; +-- Verify that no WARNING is emitted when batch_size is within the +-- libpq 65535-parameter limit. +-- check for single column +CREATE TABLE batch_nowarn_table ( x int ); +CREATE FOREIGN TABLE ftable_no_warn ( x int ) + SERVER loopback + OPTIONS (table_name 'batch_nowarn_table', batch_size '65535'); +INSERT INTO ftable_no_warn VALUES (1); +-- Clean up +DROP FOREIGN TABLE ftable_no_warn; +DROP TABLE batch_nowarn_table; +-- check for more than one columns +CREATE TABLE batch_table ( x int, y int ); +CREATE FOREIGN TABLE ftable ( x int, y int ) + SERVER loopback + OPTIONS (table_name 'batch_table', batch_size '32767'); +INSERT INTO ftable(x) VALUES (1); +RESET client_min_messages; +-- Clean up +DROP FOREIGN TABLE ftable; +DROP TABLE batch_table; -- =================================================================== -- test asynchronous execution -- =================================================================== diff --git a/contrib/postgres_fdw/option.c b/contrib/postgres_fdw/option.c index 79b16c3f318..b58300e6efe 100644 --- a/contrib/postgres_fdw/option.c +++ b/contrib/postgres_fdw/option.c @@ -179,6 +179,11 @@ postgres_fdw_validator(PG_FUNCTION_ARGS) (errcode(ERRCODE_INVALID_PARAMETER_VALUE), errmsg("\"%s\" must be an integer value greater than zero", def->defname))); + if (strcmp(def->defname, "batch_size") == 0 && + int_val > PQ_QUERY_PARAM_MAX_LIMIT) + ereport(WARNING, + errmsg("batch_size of %d exceeds protocol limit of %d", int_val, PQ_QUERY_PARAM_MAX_LIMIT), + errdetail("The batch_size for a query will be reduced to protocol limit divided by the number of columns in the query.")); } else if (strcmp(def->defname, "password_required") == 0) { diff --git a/contrib/postgres_fdw/postgres_fdw.c b/contrib/postgres_fdw/postgres_fdw.c index 8b660a6c02c..12b752629f3 100644 --- a/contrib/postgres_fdw/postgres_fdw.c +++ b/contrib/postgres_fdw/postgres_fdw.c @@ -2182,7 +2182,15 @@ postgresGetForeignModifyBatchSize(ResultRelInfo *resultRelInfo) * don't exceed this limit by using the maximum batch_size possible. */ if (fmstate && fmstate->p_nums > 0) + { + int configured = batch_size; + batch_size = Min(batch_size, PQ_QUERY_PARAM_MAX_LIMIT / fmstate->p_nums); + if (batch_size < configured) + elog(DEBUG1, "batch_size reduced from %d to %d " + "to stay within the libpq %d-parameter limit", + configured, batch_size, PQ_QUERY_PARAM_MAX_LIMIT); + } return batch_size; } diff --git a/contrib/postgres_fdw/sql/postgres_fdw.sql b/contrib/postgres_fdw/sql/postgres_fdw.sql index e7019952173..29f22f65e37 100644 --- a/contrib/postgres_fdw/sql/postgres_fdw.sql +++ b/contrib/postgres_fdw/sql/postgres_fdw.sql @@ -4027,6 +4027,52 @@ DROP TABLE ltable; DROP TABLE parent; DROP FUNCTION ftable_rowcount_trigf; +-- Verify that DEBUG1 is emitted when batch_size is reduced to stay within +-- the libpq 65535-parameter limit. +SET client_min_messages = DEBUG1; +CREATE TABLE batch_table ( x int, y int ); +CREATE FOREIGN TABLE ftable ( x int, y int ) + SERVER loopback + OPTIONS (table_name 'batch_table', batch_size '33000'); +INSERT INTO ftable(x) VALUES (1); + +-- Clean up +DROP FOREIGN TABLE ftable; +DROP TABLE batch_table; + +-- Verify that a WARNING is emitted when batch_size is set above the +-- libpq 65535-parameter limit. +CREATE TABLE batch_warn_table ( x int ); +CREATE FOREIGN TABLE ftable_warn ( x int ) + SERVER loopback + OPTIONS (table_name 'batch_warn_table', batch_size '65536'); +INSERT INTO ftable_warn VALUES (1); +-- Clean up +DROP FOREIGN TABLE ftable_warn; +DROP TABLE batch_warn_table; + +-- Verify that no WARNING is emitted when batch_size is within the +-- libpq 65535-parameter limit. +-- check for single column +CREATE TABLE batch_nowarn_table ( x int ); +CREATE FOREIGN TABLE ftable_no_warn ( x int ) + SERVER loopback + OPTIONS (table_name 'batch_nowarn_table', batch_size '65535'); +INSERT INTO ftable_no_warn VALUES (1); +-- Clean up +DROP FOREIGN TABLE ftable_no_warn; +DROP TABLE batch_nowarn_table; + +-- check for more than one columns +CREATE TABLE batch_table ( x int, y int ); +CREATE FOREIGN TABLE ftable ( x int, y int ) + SERVER loopback + OPTIONS (table_name 'batch_table', batch_size '32767'); +INSERT INTO ftable(x) VALUES (1); +RESET client_min_messages; +-- Clean up +DROP FOREIGN TABLE ftable; +DROP TABLE batch_table; -- =================================================================== -- test asynchronous execution -- =================================================================== -- 2.39.5 (Apple Git-154)