contrib/postgres_fdw/connection.c
static PGconn *
connect_pg_server(ForeignServer *server, UserMapping *user)
{
	PGconn	   *volatile conn = NULL;

	/*
	 * Use PG_TRY block to ensure closing connection on error.
	 */
	PG_TRY();
	{
		const char **keywords;
		const char **values;
		int			n;

		/*
		 * Construct connection params from generic options of ForeignServer
		 * and UserMapping.  (Some of them might not be libpq options, in
		 * which case we'll just waste a few array slots.)  Add 3 extra slots
		 * for fallback_application_name, client_encoding, end marker.
		 */
		n = list_length(server->options) + list_length(user->options) + 3;
		keywords = (const char **) palloc(n * sizeof(char *));
		values = (const char **) palloc(n * sizeof(char *));

		n = 0;
		n += ExtractConnectionOptions(server->options,
									  keywords + n, values + n);
		n += ExtractConnectionOptions(user->options,
									  keywords + n, values + n);

		/* Use "postgres_fdw" as fallback_application_name. */
		keywords[n] = "fallback_application_name";
		values[n] = "postgres_fdw";
		n++;

		/* Set client_encoding so that libpq can convert encoding properly. */
		keywords[n] = "client_encoding";
		values[n] = GetDatabaseEncodingName();
		n++;

		keywords[n] = values[n] = NULL;

		/* verify connection parameters and make connection */
		check_conn_params(keywords, values);

		conn = PQconnectdbParams(keywords, values, false);
		if (!conn || PQstatus(conn) != CONNECTION_OK)
		{
			char	   *connmessage;
			int			msglen;

			/* libpq typically appends a newline, strip that */
			connmessage = pstrdup(PQerrorMessage(conn));
			msglen = strlen(connmessage);
			if (msglen > 0 && connmessage[msglen - 1] == '\n')
				connmessage[msglen - 1] = '\0';
			ereport(ERROR,
			   (errcode(ERRCODE_SQLCLIENT_UNABLE_TO_ESTABLISH_SQLCONNECTION),
				errmsg("could not connect to server \"%s\"",
					   server->servername),
				errdetail_internal("%s", connmessage)));
		}

		/*
		 * Check that non-superuser has used password to establish connection;
		 * otherwise, he's piggybacking on the postgres server's user
		 * identity. See also dblink_security_check() in contrib/dblink.
		 */
		if (!superuser() && !PQconnectionUsedPassword(conn))
			ereport(ERROR,
				  (errcode(ERRCODE_S_R_E_PROHIBITED_SQL_STATEMENT_ATTEMPTED),
				   errmsg("password is required"),
				   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);
	}
	PG_CATCH();
	{
		/* Release PGconn data structure if we managed to create one */
		if (conn)
			PQfinish(conn);
		PG_RE_THROW();
	}
	PG_END_TRY();

	return conn;
}
/*
 * Connect to remote server using specified server and user mapping properties.
 */
Connect to remote server using specified server and user mapping properties.
Connect to remote server using specified server and user mapping properties .
static PGconn *
connect_pg_server(ForeignServer *server, UserMapping *user)
{
	PGconn	   *volatile conn = NULL;
	PG_TRY();
	{
		const char **keywords;
		const char **values;
		int			n;
		n = list_length(server->options) + list_length(user->options) + 3;
		keywords = (const char **) palloc(n * sizeof(char *));
		values = (const char **) palloc(n * sizeof(char *));
		n = 0;
		n += ExtractConnectionOptions(server->options,
									  keywords + n, values + n);
		n += ExtractConnectionOptions(user->options,
									  keywords + n, values + n);
		keywords[n] = "fallback_application_name";
		values[n] = "postgres_fdw";
		n++;
		keywords[n] = "client_encoding";
		values[n] = GetDatabaseEncodingName();
		n++;
		keywords[n] = values[n] = NULL;
		check_conn_params(keywords, values);
		conn = PQconnectdbParams(keywords, values, false);
		if (!conn || PQstatus(conn) != CONNECTION_OK)
		{
			char	   *connmessage;
			int			msglen;
			connmessage = pstrdup(PQerrorMessage(conn));
			msglen = strlen(connmessage);
			if (msglen > 0 && connmessage[msglen - 1] == '\n')
				connmessage[msglen - 1] = '\0';
			ereport(ERROR,
			   (errcode(ERRCODE_SQLCLIENT_UNABLE_TO_ESTABLISH_SQLCONNECTION),
				errmsg("could not connect to server \"%s\"",
					   server->servername),
				errdetail_internal("%s", connmessage)));
		}
		if (!superuser() && !PQconnectionUsedPassword(conn))
			ereport(ERROR,
				  (errcode(ERRCODE_S_R_E_PROHIBITED_SQL_STATEMENT_ATTEMPTED),
				   errmsg("password is required"),
				   errdetail("Non-superuser cannot connect if the server does not request a password."),
				   errhint("Target server's authentication method must be changed.")));
		configure_remote_session(conn);
		pfree(keywords);
		pfree(values);
	}
	PG_CATCH();
	{
		if (conn)
			PQfinish(conn);
		PG_RE_THROW();
	}
	PG_END_TRY();
	return conn;
}
static PGconn * connect_pg_server ( ForeignServer * server , UserMapping * user ) { PGconn * volatile conn = NULL ; PG_TRY ( ) ; { const char * * keywords ; const char * * values ; int n ; n = list_length ( server -> options ) + list_length ( user -> options ) + 3 ; keywords = ( const char * * ) palloc ( n * sizeof ( char * ) ) ; values = ( const char * * ) palloc ( n * sizeof ( char * ) ) ; n = 0 ; n += ExtractConnectionOptions ( server -> options , keywords + n , values + n ) ; n += ExtractConnectionOptions ( user -> options , keywords + n , values + n ) ; keywords [ n ] = " " ; values [ n ] = " " ; n ++ ; keywords [ n ] = " " ; values [ n ] = GetDatabaseEncodingName ( ) ; n ++ ; keywords [ n ] = values [ n ] = NULL ; check_conn_params ( keywords , values ) ; conn = PQconnectdbParams ( keywords , values , false ) ; if ( ! conn || PQstatus ( conn ) != CONNECTION_OK ) { char * connmessage ; int msglen ; connmessage = pstrdup ( PQerrorMessage ( conn ) ) ; msglen = strlen ( connmessage ) ; if ( msglen > 0 && connmessage [ msglen - 1 ] == ' \n ' ) connmessage [ msglen - 1 ] = ' \0 ' ; ereport ( ERROR , ( errcode ( ERRCODE_SQLCLIENT_UNABLE_TO_ESTABLISH_SQLCONNECTION ) , errmsg ( " \" \" " , server -> servername ) , errdetail_internal ( " " , connmessage ) ) ) ; } if ( ! superuser ( ) && ! PQconnectionUsedPassword ( conn ) ) ereport ( ERROR , ( errcode ( ERRCODE_S_R_E_PROHIBITED_SQL_STATEMENT_ATTEMPTED ) , errmsg ( " " ) , errdetail ( " " ) , errhint ( " " ) ) ) ; configure_remote_session ( conn ) ; pfree ( keywords ) ; pfree ( values ) ; } PG_CATCH ( ) ; { if ( conn ) PQfinish ( conn ) ; PG_RE_THROW ( ) ; } PG_END_TRY ( ) ; return conn ; }
Connect to remote server using specified server and user mapping properties.
Connect to remote server using specified server and user mapping properties .
/*
	 * Use PG_TRY block to ensure closing connection on error.
	 */ /*
		 * Construct connection params from generic options of ForeignServer
		 * and UserMapping.  (Some of them might not be libpq options, in
		 * which case we'll just waste a few array slots.)  Add 3 extra slots
		 * for fallback_application_name, client_encoding, end marker.
		 */ /* Use "postgres_fdw" as fallback_application_name. */ /* Set client_encoding so that libpq can convert encoding properly. */ /* verify connection parameters and make connection */ /* libpq typically appends a newline, strip that */ /*
		 * Check that non-superuser has used password to establish connection;
		 * otherwise, he's piggybacking on the postgres server's user
		 * identity. See also dblink_security_check() in contrib/dblink.
		 */ /* Prepare new session for use */ /* Release PGconn data structure if we managed to create one */