From 9388407fe911435bc9b473f522233a4c3526466f Mon Sep 17 00:00:00 2001
From: AyoubKAZ <kazarayoub2004@gmail.com>
Date: Thu, 5 Nov 2026 00:43:21 +0100
Subject: [PATCH] file_fdw: Enforce REJECT_LIMIT during ANALYZE

When a file_fdw foreign table has on_error 'ignore' and reject_limit
specified, fileIterateForeignScan() aborts with an error once the number
of skipped rows exceeds reject_limit. However, file_acquire_sample_rows()
failed to check reject_limit when encountering soft errors, allowing
ANALYZE to ignore unlimited erroneous rows without error.

Fix by checking reject_limit after resetting error_occurred in
file_acquire_sample_rows(), just like we already do in fileIterateForeignScan() and
CopyFrom().
---
 contrib/file_fdw/expected/file_fdw.out | 3 +++
 contrib/file_fdw/file_fdw.c            | 7 +++++++
 contrib/file_fdw/sql/file_fdw.sql      | 1 +
 3 files changed, 11 insertions(+)

diff --git a/contrib/file_fdw/expected/file_fdw.out b/contrib/file_fdw/expected/file_fdw.out
index 640986528ae..548961ee4cc 100644
--- a/contrib/file_fdw/expected/file_fdw.out
+++ b/contrib/file_fdw/expected/file_fdw.out
@@ -277,6 +277,9 @@ ALTER FOREIGN TABLE agg_bad OPTIONS (ADD reject_limit '1'); -- ERROR
 SELECT * FROM agg_bad;
 ERROR:  skipped more than REJECT_LIMIT (1) rows due to data type incompatibility
 CONTEXT:  COPY agg_bad, line 5, column b: "bbb"
+ANALYZE agg_bad;
+ERROR:  skipped more than REJECT_LIMIT (1) rows due to data type incompatibility
+CONTEXT:  COPY agg_bad, line 5, column b: "bbb"
 ALTER FOREIGN TABLE agg_bad OPTIONS (SET reject_limit '2');
 SELECT * FROM agg_bad;
   a  |   b    
diff --git a/contrib/file_fdw/file_fdw.c b/contrib/file_fdw/file_fdw.c
index 7d9dc3baf74..b4e7b286a08 100644
--- a/contrib/file_fdw/file_fdw.c
+++ b/contrib/file_fdw/file_fdw.c
@@ -1264,6 +1264,13 @@ file_acquire_sample_rows(Relation onerel, int elevel,
 			 */
 			cstate->escontext->error_occurred = false;
 
+			if (cstate->opts.reject_limit > 0 &&
+				cstate->num_errors > cstate->opts.reject_limit)
+				ereport(ERROR,
+						(errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
+						 errmsg("skipped more than REJECT_LIMIT (%" PRId64 ") rows due to data type incompatibility",
+								cstate->opts.reject_limit)));
+
 			/* Repeat NextCopyFrom() until no soft error occurs */
 			continue;
 		}
diff --git a/contrib/file_fdw/sql/file_fdw.sql b/contrib/file_fdw/sql/file_fdw.sql
index 56bfc926c00..3ebc9af1448 100644
--- a/contrib/file_fdw/sql/file_fdw.sql
+++ b/contrib/file_fdw/sql/file_fdw.sql
@@ -179,6 +179,7 @@ ALTER FOREIGN TABLE agg_bad OPTIONS (ADD log_verbosity 'silent');
 SELECT * FROM agg_bad;
 ALTER FOREIGN TABLE agg_bad OPTIONS (ADD reject_limit '1'); -- ERROR
 SELECT * FROM agg_bad;
+ANALYZE agg_bad;
 ALTER FOREIGN TABLE agg_bad OPTIONS (SET reject_limit '2');
 SELECT * FROM agg_bad;
 ANALYZE agg_bad;
-- 
2.34.1

