mirror of
https://github.com/postgres/postgres.git
synced 2025-07-28 23:42:10 +03:00
Adjust postgres_fdw's search path handling.
Set the remote session's search path to exactly "pg_catalog" at session start, then schema-qualify only names that aren't in that schema. This greatly reduces clutter in the generated SQL commands, as seen in the regression test changes. Per discussion. Also, rethink use of FirstNormalObjectId as the "built-in object" cutoff --- FirstBootstrapObjectId is safer, since the former will accept objects in information_schema for instance.
This commit is contained in:
@ -63,6 +63,7 @@ static bool xact_got_connection = false;
|
||||
/* prototypes of private functions */
|
||||
static PGconn *connect_pg_server(ForeignServer *server, UserMapping *user);
|
||||
static void check_conn_params(const char **keywords, const char **values);
|
||||
static void configure_remote_session(PGconn *conn);
|
||||
static void begin_remote_xact(ConnCacheEntry *entry);
|
||||
static void pgfdw_xact_callback(XactEvent event, void *arg);
|
||||
static void pgfdw_subxact_callback(SubXactEvent event,
|
||||
@ -237,6 +238,9 @@ connect_pg_server(ForeignServer *server, UserMapping *user)
|
||||
errdetail("Non-superuser cannot connect if the server does not request a password."),
|
||||
errhint("Target server's authentication method must be changed.")));
|
||||
|
||||
/* Prepare new session for use */
|
||||
configure_remote_session(conn);
|
||||
|
||||
pfree(keywords);
|
||||
pfree(values);
|
||||
}
|
||||
@ -281,6 +285,31 @@ check_conn_params(const char **keywords, const char **values)
|
||||
errdetail("Non-superusers must provide a password in the user mapping.")));
|
||||
}
|
||||
|
||||
/*
|
||||
* Issue SET commands to make sure remote session is configured properly.
|
||||
*
|
||||
* We do this just once at connection, assuming nothing will change the
|
||||
* values later. Since we'll never send volatile function calls to the
|
||||
* remote, there shouldn't be any way to break this assumption from our end.
|
||||
* It's possible to think of ways to break it at the remote end, eg making
|
||||
* a foreign table point to a view that includes a set_config call ---
|
||||
* but once you admit the possibility of a malicious view definition,
|
||||
* there are any number of ways to break things.
|
||||
*/
|
||||
static void
|
||||
configure_remote_session(PGconn *conn)
|
||||
{
|
||||
const char *sql;
|
||||
PGresult *res;
|
||||
|
||||
/* Force the search path to contain only pg_catalog (see deparse.c) */
|
||||
sql = "SET search_path = pg_catalog";
|
||||
res = PQexec(conn, sql);
|
||||
if (PQresultStatus(res) != PGRES_COMMAND_OK)
|
||||
pgfdw_report_error(ERROR, res, true, sql);
|
||||
PQclear(res);
|
||||
}
|
||||
|
||||
/*
|
||||
* Start remote transaction or subtransaction, if needed.
|
||||
*
|
||||
|
Reference in New Issue
Block a user