diff --git a/contrib/postgres_fdw/postgres_fdw.c b/contrib/postgres_fdw/postgres_fdw.c index fbe01fdde85..42a704344b8 100644 --- a/contrib/postgres_fdw/postgres_fdw.c +++ b/contrib/postgres_fdw/postgres_fdw.c @@ -5832,11 +5832,10 @@ fetch_remote_statistics(Relation relation, } /* - * Get connection to the foreign server. Connection manager will - * establish new connection if necessary. - * - * Note that unlike the sampling case, we only query pg_class and - * pg_stats, so we do the remote access as the current user. + * Get the connection to use. We do the remote access as the table's + * owner. Note that unlike AnalyzeForeignTable(), the core code would + * already have switched us to the table's owner, before we are called + * from ImportForeignStatistics(). */ user = GetUserMapping(GetUserId(), table->serverid); conn = GetConnection(user, false, NULL); diff --git a/src/backend/commands/analyze.c b/src/backend/commands/analyze.c index c05f9f50e43..40b0e23ca2e 100644 --- a/src/backend/commands/analyze.c +++ b/src/backend/commands/analyze.c @@ -228,10 +228,32 @@ analyze_rel(Oid relid, RangeVar *relation, fdwroutine = GetFdwRoutineForRelation(onerel, false); - if (fdwroutine->ImportForeignStatistics != NULL && - fdwroutine->ImportForeignStatistics(onerel, va_cols, elevel)) - stats_imported = true; - else + if (fdwroutine->ImportForeignStatistics != NULL) + { + Oid save_userid; + int save_sec_context; + int save_nestlevel; + + /* + * Switch to the table owner's userid, as in the sampling method. + * Also lock down security-restricted operations and arrange to + * make GUC variable changes local to this command. + */ + GetUserIdAndSecContext(&save_userid, &save_sec_context); + SetUserIdAndSecContext(onerel->rd_rel->relowner, + save_sec_context | SECURITY_RESTRICTED_OPERATION); + save_nestlevel = NewGUCNestLevel(); + RestrictSearchPath(); + + stats_imported = fdwroutine->ImportForeignStatistics(onerel, + va_cols, + elevel); + + AtEOXact_GUC(false, save_nestlevel); + SetUserIdAndSecContext(save_userid, save_sec_context); + } + + if (!stats_imported) { bool ok = false;