*** a/doc/src/sgml/func.sgml
--- b/doc/src/sgml/func.sgml
***************
*** 16484,16489 **** SELECT collation for ('foo' COLLATE "de_DE");
--- 16484,16502 ----
         <entry><type>text</type></entry>
         <entry>set parameter and return new value</entry>
        </row>
+ 	  <row>
+        <entry>
+         <indexterm>
+          <primary>pg_hba_lookup</primary>
+         </indexterm>
+         <literal><function>pg_hba_lookup(<parameter>database</> <type>text</>,
+ 							<parameter>user</> <type>text</>
+ 							[, <parameter>address</> <type>text</>]
+ 							[, <parameter>hostname</> <type>text</>)</function></literal>
+        </entry>
+        <entry><type>record</type></entry>
+        <entry>Returns all matching row entries of pg_hba.conf</entry>
+       </row>
       </tbody>
      </tgroup>
     </table>
***************
*** 16541,16546 **** SELECT set_config('log_statement_stats', 'off', false);
--- 16554,16575 ----
  </programlisting>
     </para>
  
+    <para>
+     <function>pg_hba_lookup</function> returns a set of records
+ 	containing the line number, type, database, user, address,
+ 	hostname, method and options that are satisfied with the given
+ 	input values. Typical usages include:
+ <programlisting>
+ SELECT pg_hba_lookup('test_database', 'test_user');
+ 
+ 					pg_hba_lookup
+ --------------------------------------------------------------
+  (84,local,"[""all""]","[""all""]",,,trust,{})
+  (86,local,"[""test_database""]","[""test_user""]",,,trust,{})
+ (1 row)
+ </programlisting>
+    </para>
+    
    </sect2>
  
    <sect2 id="functions-admin-signal">
*** a/src/backend/libpq/hba.c
--- b/src/backend/libpq/hba.c
***************
*** 25,39 ****
--- 25,45 ----
  #include <arpa/inet.h>
  #include <unistd.h>
  
+ #include "access/htup_details.h"
  #include "catalog/pg_collation.h"
+ #include "catalog/pg_type.h"
+ #include "funcapi.h"
  #include "libpq/ip.h"
  #include "libpq/libpq.h"
+ #include "miscadmin.h"
  #include "postmaster/postmaster.h"
  #include "regex/regex.h"
  #include "replication/walsender.h"
  #include "storage/fd.h"
  #include "utils/acl.h"
+ #include "utils/builtins.h"
  #include "utils/guc.h"
+ #include "utils/jsonb.h"
  #include "utils/lsyscache.h"
  #include "utils/memutils.h"
  
***************
*** 74,79 **** typedef struct HbaToken
--- 80,88 ----
  	bool		quoted;
  } HbaToken;
  
+ /* Flag to indicate the failure of reloading pg_hba.conf file */
+ bool		load_hba_failure = false;
+ 
  /*
   * pre-parsed content of HBA config file: list of HbaLine structs.
   * parsed_hba_context is the memory context where it lives.
***************
*** 100,105 **** static List *tokenize_inc_file(List *tokens, const char *outer_filename,
--- 109,119 ----
  static bool parse_hba_auth_opt(char *name, char *val, HbaLine *hbaline,
  				   int line_num);
  
+ static void hba_getvalues_for_line(HbaLine *hba, Datum *values, bool *nulls);
+ static bool pg_hba_match(HbaLine *hba, char *user, char *database, char *address, char *hostname);
+ static void pg_hba_lookup_internal(char	*user, char	*database, char	*address,
+ 					char *hostname, ReturnSetInfo *rsi);
+ 
  /*
   * isblank() exists in the ISO C99 spec, but it's not very portable yet,
   * so provide our own version.
***************
*** 2233,2235 **** hba_getauthmethod(hbaPort *port)
--- 2247,2822 ----
  {
  	check_hba(port);
  }
+ 
+ 
+ /* LDAP supports 10 currently, keep this well above the most any method needs */
+ #define MAX_OPTIONS 12
+ 
+ /*
+  * Fill in suitable values to build a tuple representing the
+  * HbaLine provided
+  */
+ static void
+ hba_getvalues_for_line(HbaLine *hba, Datum *values, bool *nulls)
+ {
+ 	ListCell   *dbcell;
+ 	char		buffer[NI_MAXHOST];
+ 	int			index = 0;
+ 	JsonbInState result;
+ 	JsonbValue	v;
+ 	char	   *str;
+ 	int			len;
+ 
+ 	/* line_number */
+ 	values[index] = Int32GetDatum(hba->linenumber);
+ 
+ 	/* type */
+ 	index++;
+  	switch (hba->conntype)
+  	{
+  		case ctLocal:
+  			values[index] = CStringGetTextDatum("local");
+  			break;
+  		case ctHost:
+  			values[index] = CStringGetTextDatum("host");
+  			break;
+  		case ctHostSSL:
+  			values[index] = CStringGetTextDatum("hostssl");
+  			break;
+  		case ctHostNoSSL:
+  			values[index] = CStringGetTextDatum("hostnossl");
+  			break;
+  		default:
+  			elog(ERROR, "unexpected connection type in parsed HBA entry");
+  			break;
+  	}
+ 
+ 	/* database */
+ 	index++;
+ 	memset(&result, 0, sizeof(JsonbInState));
+ 
+ 	result.res = pushJsonbValue(&result.parseState, WJB_BEGIN_ARRAY, NULL);
+ 
+ 	if (list_length(hba->databases) != 0)
+ 	{
+ 		HbaToken   *tok;
+ 
+ 		foreach(dbcell, hba->databases)
+ 		{
+ 			tok = lfirst(dbcell);
+ 			add_jsonb(CStringGetTextDatum(tok->string), false, &result, TEXTOID, false);
+ 		}
+ 	}
+ 
+ 	result.res = pushJsonbValue(&result.parseState, WJB_END_ARRAY, NULL);
+ 	values[index] = PointerGetDatum(JsonbValueToJsonb(result.res));
+ 
+ 	/* user */
+ 	index++;
+ 	memset(&result, 0, sizeof(JsonbInState));
+ 	result.res = pushJsonbValue(&result.parseState, WJB_BEGIN_ARRAY, NULL);
+ 
+ 	if (list_length(hba->roles) != 0)
+ 	{
+ 		HbaToken   *tok;
+ 
+ 		foreach(dbcell, hba->roles)
+ 		{
+ 			tok = lfirst(dbcell);
+ 			add_jsonb(CStringGetTextDatum(tok->string), false, &result, TEXTOID, false);
+ 		}
+ 	}
+ 
+ 	result.res = pushJsonbValue(&result.parseState, WJB_END_ARRAY, NULL);
+ 	values[index] = PointerGetDatum(JsonbValueToJsonb(result.res));
+ 
+ 	/* address */
+ 	index++;
+ 	if (pg_getnameinfo_all(&hba->addr, sizeof(struct sockaddr_storage),
+ 							buffer, sizeof(buffer),
+ 							NULL, 0,
+ 							NI_NUMERICHOST) == 0)
+ 	{
+ 		clean_ipv6_addr(hba->addr.ss_family, buffer);
+ 		values[index] = DirectFunctionCall1(inet_in, CStringGetDatum(buffer));
+ 	}
+ 	else
+ 		nulls[index] = true;
+ 
+ 	/* hostname */
+ 	index++;
+ 	if (hba->hostname)
+ 		values[index] = CStringGetTextDatum(hba->hostname);
+ 	else
+ 		nulls[index] = true;
+ 
+ 	/* method */
+  	index++;
+  	switch (hba->auth_method)
+  	{
+  		case uaReject:
+  			values[index] = CStringGetTextDatum("reject");
+  			break;
+  		case uaTrust:
+  			values[index] = CStringGetTextDatum("trust");
+  			break;
+  		case uaIdent:
+  			values[index] = CStringGetTextDatum("ident");
+  			break;
+  		case uaPassword:
+  			values[index] = CStringGetTextDatum("password");
+  			break;
+  		case uaMD5:
+  			values[index] = CStringGetTextDatum("md5");
+  			break;
+  		case uaGSS:
+  			values[index] = CStringGetTextDatum("gss");
+  			break;
+  		case uaSSPI:
+  			values[index] = CStringGetTextDatum("sspi");
+  			break;
+  		case uaPAM:
+  			values[index] = CStringGetTextDatum("pam");
+  			break;
+  		case uaLDAP:
+  			values[index] = CStringGetTextDatum("ldap");
+  			break;
+  		case uaCert:
+  			values[index] = CStringGetTextDatum("cert");
+  			break;
+  		case uaRADIUS:
+  			values[index] = CStringGetTextDatum("radius");
+  			break;
+  		case uaPeer:
+  			values[index] = CStringGetTextDatum("peer");
+  			break;
+  		default:
+  			elog(ERROR, "unexpected authentication method in parsed HBA entry");
+  			break;
+  	}
+ 
+ 	/* options */
+ 	index++;
+ 	memset(&result, 0, sizeof(JsonbInState));
+ 	result.res = pushJsonbValue(&result.parseState, WJB_BEGIN_OBJECT, NULL);
+ 
+ 	if (hba->auth_method == uaGSS || hba->auth_method == uaSSPI)
+ 	{
+ 		if (hba->include_realm)
+ 		{
+ 			str = pstrdup("include_realm");
+ 			len = strlen(str);
+ 
+ 			v.type = jbvString;
+ 
+ 			v.val.string.len = len;
+ 			v.val.string.val = str;
+ 
+ 			result.res = pushJsonbValue(&result.parseState, WJB_KEY, &v);
+ 			add_jsonb(BoolGetDatum(true), false, &result, BOOLOID, false);
+ 		}
+ 
+ 		if (hba->krb_realm)
+ 		{
+ 			str = pstrdup("krb_realm");
+ 			len = strlen(str);
+ 
+ 			v.type = jbvString;
+ 
+ 			v.val.string.len = len;
+ 			v.val.string.val = str;
+ 
+ 			result.res = pushJsonbValue(&result.parseState, WJB_KEY, &v);
+ 			add_jsonb(CStringGetTextDatum(hba->krb_realm), false, &result, TEXTOID, false);
+ 		}
+ 	}
+ 
+ 	if (hba->usermap)
+ 	{
+ 		str = pstrdup("map");
+ 		len = strlen(str);
+ 
+ 		v.type = jbvString;
+ 
+ 		v.val.string.len = len;
+ 		v.val.string.val = str;
+ 
+ 		result.res = pushJsonbValue(&result.parseState, WJB_KEY, &v);
+ 		add_jsonb(CStringGetTextDatum(hba->usermap), false, &result, TEXTOID, false);
+ 	}
+ 
+ 	if (hba->auth_method == uaLDAP)
+ 	{
+ 		if (hba->ldapserver)
+ 		{
+ 			str = pstrdup("ldapserver");
+ 			len = strlen(str);
+ 
+ 			v.type = jbvString;
+ 
+ 			v.val.string.len = len;
+ 			v.val.string.val = str;
+ 
+ 			result.res = pushJsonbValue(&result.parseState, WJB_KEY, &v);
+ 			add_jsonb(CStringGetTextDatum(hba->ldapserver), false, &result, TEXTOID, false);
+ 		}
+ 
+ 		if (hba->ldapport)
+ 		{
+ 			str = pstrdup("ldapport");
+ 			len = strlen(str);
+ 
+ 			v.type = jbvString;
+ 
+ 			v.val.string.len = len;
+ 			v.val.string.val = str;
+ 
+ 			result.res = pushJsonbValue(&result.parseState, WJB_KEY, &v);
+ 			add_jsonb(Int32GetDatum(hba->ldapport), false, &result, INT4OID, false);
+ 		}
+ 
+ 		if (hba->ldaptls)
+ 		{
+ 			str = pstrdup("ldaptls");
+ 			len = strlen(str);
+ 
+ 			v.type = jbvString;
+ 
+ 			v.val.string.len = len;
+ 			v.val.string.val = str;
+ 
+ 			result.res = pushJsonbValue(&result.parseState, WJB_KEY, &v);
+ 			add_jsonb(BoolGetDatum(true), false, &result, BOOLOID, false);
+ 		}
+ 
+ 		if (hba->ldapprefix)
+ 		{
+ 			str = pstrdup("ldapprefix");
+ 			len = strlen(str);
+ 
+ 			v.type = jbvString;
+ 
+ 			v.val.string.len = len;
+ 			v.val.string.val = str;
+ 
+ 			result.res = pushJsonbValue(&result.parseState, WJB_KEY, &v);
+ 			add_jsonb(CStringGetTextDatum(hba->ldapprefix), false, &result, TEXTOID, false);
+ 		}
+ 
+ 		if (hba->ldapsuffix)
+ 		{
+ 			str = pstrdup("ldapsuffix");
+ 			len = strlen(str);
+ 
+ 			v.type = jbvString;
+ 
+ 			v.val.string.len = len;
+ 			v.val.string.val = str;
+ 
+ 			result.res = pushJsonbValue(&result.parseState, WJB_KEY, &v);
+ 			add_jsonb(CStringGetTextDatum(hba->ldapsuffix), false, &result, TEXTOID, false);
+ 		}
+ 
+ 		if (hba->ldapbasedn)
+ 		{
+ 			str = pstrdup("ldapbasedn");
+ 			len = strlen(str);
+ 
+ 			v.type = jbvString;
+ 
+ 			v.val.string.len = len;
+ 			v.val.string.val = str;
+ 
+ 			result.res = pushJsonbValue(&result.parseState, WJB_KEY, &v);
+ 			add_jsonb(CStringGetTextDatum(hba->ldapbasedn), false, &result, TEXTOID, false);
+ 		}
+ 
+ 		if (hba->ldapbinddn)
+ 		{
+ 			str = pstrdup("ldapbinddn");
+ 			len = strlen(str);
+ 
+ 			v.type = jbvString;
+ 
+ 			v.val.string.len = len;
+ 			v.val.string.val = str;
+ 
+ 			result.res = pushJsonbValue(&result.parseState, WJB_KEY, &v);
+ 			add_jsonb(CStringGetTextDatum(hba->ldapbinddn), false, &result, TEXTOID, false);
+ 		}
+ 
+ 		if (hba->ldapbindpasswd)
+ 		{
+ 			str = pstrdup("ldapbindpasswd");
+ 			len = strlen(str);
+ 
+ 			v.type = jbvString;
+ 
+ 			v.val.string.len = len;
+ 			v.val.string.val = str;
+ 
+ 			result.res = pushJsonbValue(&result.parseState, WJB_KEY, &v);
+ 			add_jsonb(CStringGetTextDatum(hba->ldapbindpasswd), false, &result, TEXTOID, false);
+ 		}
+ 
+ 		if (hba->ldapsearchattribute)
+ 		{
+ 			str = pstrdup("ldapsearchattribute");
+ 			len = strlen(str);
+ 
+ 			v.type = jbvString;
+ 
+ 			v.val.string.len = len;
+ 			v.val.string.val = str;
+ 
+ 			result.res = pushJsonbValue(&result.parseState, WJB_KEY, &v);
+ 			add_jsonb(CStringGetTextDatum(hba->ldapsearchattribute), false, &result, TEXTOID, false);
+ 		}
+ 
+ 		if (hba->ldapscope)
+ 		{
+ 			str = pstrdup("ldapscope");
+ 			len = strlen(str);
+ 
+ 			v.type = jbvString;
+ 
+ 			v.val.string.len = len;
+ 			v.val.string.val = str;
+ 
+ 			result.res = pushJsonbValue(&result.parseState, WJB_KEY, &v);
+ 			add_jsonb(Int32GetDatum(hba->ldapscope), false, &result, INT4OID, false);
+ 		}
+ 	}
+ 
+ 	if (hba->auth_method == uaRADIUS)
+ 	{
+ 		if (hba->radiusserver)
+ 		{
+ 			str = pstrdup("radiusserver");
+ 			len = strlen(str);
+ 
+ 			v.type = jbvString;
+ 
+ 			v.val.string.len = len;
+ 			v.val.string.val = str;
+ 
+ 			result.res = pushJsonbValue(&result.parseState, WJB_KEY, &v);
+ 			add_jsonb(CStringGetTextDatum(hba->radiusserver), false, &result, TEXTOID, false);
+ 		}
+ 
+ 		if (hba->radiussecret)
+ 		{
+ 			str = pstrdup("radiussecret");
+ 			len = strlen(str);
+ 
+ 			v.type = jbvString;
+ 
+ 			v.val.string.len = len;
+ 			v.val.string.val = str;
+ 
+ 			result.res = pushJsonbValue(&result.parseState, WJB_KEY, &v);
+ 			add_jsonb(CStringGetTextDatum(hba->radiussecret), false, &result, TEXTOID, false);
+ 		}
+ 
+ 		if (hba->radiusidentifier)
+ 		{
+ 			str = pstrdup("radiusidentifier");
+ 			len = strlen(str);
+ 
+ 			v.type = jbvString;
+ 
+ 			v.val.string.len = len;
+ 			v.val.string.val = str;
+ 
+ 			result.res = pushJsonbValue(&result.parseState, WJB_KEY, &v);
+ 			add_jsonb(CStringGetTextDatum(hba->radiusidentifier), false, &result, TEXTOID, false);
+ 		}
+ 
+ 		if (hba->radiusport)
+ 		{
+ 			str = pstrdup("radiusport");
+ 			len = strlen(str);
+ 
+ 			v.type = jbvString;
+ 
+ 			v.val.string.len = len;
+ 			v.val.string.val = str;
+ 
+ 			result.res = pushJsonbValue(&result.parseState, WJB_KEY, &v);
+ 			add_jsonb(Int32GetDatum(hba->radiusport), false, &result, INT4OID, false);
+ 		}
+ 	}
+ 
+ 	result.res = pushJsonbValue(&result.parseState, WJB_END_OBJECT, NULL);
+ 	values[index] = PointerGetDatum(JsonbValueToJsonb(result.res));
+ }
+ 
+ static bool
+ pg_hba_match(HbaLine *hba, char *user, char *database, char *address, char *hostname)
+ {
+ 	Oid			roleid;
+ 
+ 	/* Get the target role's OID.  Note we do not error out for bad role. */
+ 	roleid = get_role_oid(user, true);
+ 
+ 	if (!check_db(database, user, roleid, hba->databases))
+ 		return false;
+ 
+ 	if (!check_role(user, roleid, hba->roles))
+ 		return false;
+ 
+ 	return true;
+ }
+ 
+ #define NUM_PG_HBA_CONF_ATTS   8
+ 
+ static void
+ pg_hba_lookup_internal(char	*user, char	*database, char	*address,
+ 			char *hostname, ReturnSetInfo *rsi)
+ {
+ 	Tuplestorestate *tuple_store;
+ 	TupleDesc	tupdesc;
+ 	ListCell   *line;
+ 	MemoryContext old_cxt;
+ 
+ 	/*
+ 	* Create the tupledesc and tuplestore in the per_query context as
+ 	* required for SFRM_Materialize.
+ 	*/
+ 	old_cxt = MemoryContextSwitchTo(rsi->econtext->ecxt_per_query_memory);
+ 
+ 	tupdesc = CreateTemplateTupleDesc(NUM_PG_HBA_CONF_ATTS, false);
+ 	TupleDescInitEntry(tupdesc, (AttrNumber)1, "line_number",
+ 		INT4OID, -1, 0);
+ 	TupleDescInitEntry(tupdesc, (AttrNumber)2, "type",
+ 		TEXTOID, -1, 0);
+ 	TupleDescInitEntry(tupdesc, (AttrNumber)3, "database",
+ 		JSONBOID, -1, 0);
+ 	TupleDescInitEntry(tupdesc, (AttrNumber)4, "user",
+ 		JSONBOID, -1, 0);
+ 	TupleDescInitEntry(tupdesc, (AttrNumber)5, "address",
+ 		INETOID, -1, 0);
+ 	TupleDescInitEntry(tupdesc, (AttrNumber)6, "hostname",
+ 		TEXTOID, -1, 0);
+ 	TupleDescInitEntry(tupdesc, (AttrNumber)7, "method",
+ 		TEXTOID, -1, 0);
+ 	TupleDescInitEntry(tupdesc, (AttrNumber)8, "options",
+ 		JSONBOID, -1, 0);
+ 	BlessTupleDesc(tupdesc);
+ 
+ 	tuple_store =
+ 		tuplestore_begin_heap(rsi->allowedModes & SFRM_Materialize_Random,
+ 		false, work_mem);
+ 
+ 	MemoryContextSwitchTo(old_cxt);
+ 
+ 	/*
+ 	* Loop through the list and deparse each entry as it comes, storing it in
+ 	* the tuplestore. Any temporary memory allocations here live only for the
+ 	* function call lifetime.
+ 	*/
+ 	foreach(line, parsed_hba_lines)
+ 	{
+ 		HbaLine    *hba = (HbaLine *)lfirst(line);
+ 		Datum		values[NUM_PG_HBA_CONF_ATTS];
+ 		bool		nulls[NUM_PG_HBA_CONF_ATTS];
+ 		HeapTuple	tuple;
+ 
+ 		MemSet(values, 0, sizeof(values));
+ 		MemSet(nulls, 0, sizeof(nulls));
+ 
+ 		CHECK_FOR_INTERRUPTS();
+ 
+ 		if (pg_hba_match(hba, user, database, address, hostname))
+ 		{
+ 			/* Get the next parsed hba line values */
+ 			hba_getvalues_for_line(hba, values, nulls);
+ 
+ 			/* build a tuple */
+ 			tuple = heap_form_tuple(tupdesc, values, nulls);
+ 			tuplestore_puttuple(tuple_store, tuple);
+ 		}
+ 	}
+ 
+ 	rsi->setDesc = tupdesc;
+ 	rsi->setResult = tuple_store;
+ 	return;
+ }
+ 
+ /*
+ * SQL-accessible SRF to return all the settings from the pg_hba.conf
+ * file.
+ */
+ Datum
+ pg_hba_lookup_2args(PG_FUNCTION_ARGS)
+ {
+ 	return pg_hba_lookup(fcinfo);
+ }
+ 
+ /*
+  * SQL-accessible SRF to return all the settings from the pg_hba.conf
+  * file. 
+  */
+ Datum
+ pg_hba_lookup(PG_FUNCTION_ARGS)
+ {
+ 	char	*user;
+ 	char	*database;
+ 	char	*address;
+ 	char    *hostname;
+ 
+ 	/*
+ 	* We must use the Materialize mode to be safe against HBA file reloads
+ 	* while the cursor is open. It's also more efficient than having to look
+ 	* up our current position in the parsed list every time.
+ 	*/
+ 	ReturnSetInfo *rsi = (ReturnSetInfo *)fcinfo->resultinfo;
+ 
+ 	if (!superuser())
+ 		ereport(ERROR,
+ 				(errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
+ 				 (errmsg("only superuser can view pg_hba.conf settings"))));
+ 
+ 	if (!rsi || !IsA(rsi, ReturnSetInfo) ||
+ 		(rsi->allowedModes & SFRM_Materialize) == 0)
+ 		ereport(ERROR,
+ 				(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
+ 				errmsg("set-valued function called in context that "
+ 						"cannot accept a set")));
+ 
+ 	if (PG_ARGISNULL(0))
+ 		ereport(ERROR,
+ 				(errcode(ERRCODE_NULL_VALUE_NOT_ALLOWED),
+ 				(errmsg("user name is required to match pg_hba configuration entry"))));
+ 	else
+ 		user = TextDatumGetCString(PG_GETARG_DATUM(0));
+ 
+ 	if (PG_ARGISNULL(1))
+ 		ereport(ERROR,
+ 				(errcode(ERRCODE_NULL_VALUE_NOT_ALLOWED),
+ 				(errmsg("database name is required to match pg_hba configuration entry"))));
+ 	else
+ 		database = TextDatumGetCString(PG_GETARG_DATUM(1));
+ 
+ 	if (PG_NARGS() != 2)
+ 	{
+ 		if (!PG_ARGISNULL(2))
+ 			address = TextDatumGetCString(PG_GETARG_DATUM(2));
+ 
+ 		if (!PG_ARGISNULL(3))
+ 			hostname = TextDatumGetCString(PG_GETARG_DATUM(3));
+ 	}
+ 
+ 	if (load_hba_failure)
+ 		ereport(WARNING,
+ 		(errmsg("There was some failure in reloading pg_hba.conf file. "
+ 		"The pg_hba.conf settings data may contains stale information")));
+ 
+ 	rsi->returnMode = SFRM_Materialize;
+ 
+ 	pg_hba_lookup_internal(user, database, address, hostname, rsi);
+ 
+ 	PG_RETURN_NULL();
+ }
+ 
+ 
*** a/src/backend/tcop/postgres.c
--- b/src/backend/tcop/postgres.c
***************
*** 3998,4003 **** PostgresMain(int argc, char *argv[],
--- 3998,4016 ----
  		{
  			got_SIGHUP = false;
  			ProcessConfigFile(PGC_SIGHUP);
+ 			
+ 			/* 
+ 			 * Reload authentication config files too to refresh 
+ 			 * pg_hba_conf view data.
+ 			 */
+ 			if (!load_hba())
+ 			{
+ 				ereport(DEBUG1,
+ 					(errmsg("Falure in reloading pg_hba.conf, pg_hba_conf view may show stale information")));
+ 				load_hba_failure = true;
+ 			}
+ 			
+ 			load_hba_failure = false;
  		}
  
  		/*
*** a/src/backend/utils/adt/jsonb.c
--- b/src/backend/utils/adt/jsonb.c
***************
*** 36,47 ****
  
  #define DT_INFINITY "infinity"
  
- typedef struct JsonbInState
- {
- 	JsonbParseState *parseState;
- 	JsonbValue *res;
- } JsonbInState;
- 
  /* unlike with json categories, we need to treat json and jsonb differently */
  typedef enum					/* type categories for datum_to_jsonb */
  {
--- 36,41 ----
***************
*** 82,88 **** static void jsonb_categorize_type(Oid typoid,
  static void datum_to_jsonb(Datum val, bool is_null, JsonbInState *result,
  			   JsonbTypeCategory tcategory, Oid outfuncoid,
  			   bool key_scalar);
! static void add_jsonb(Datum val, bool is_null, JsonbInState *result,
  		  Oid val_type, bool key_scalar);
  static JsonbParseState *clone_parse_state(JsonbParseState *state);
  static char *JsonbToCStringWorker(StringInfo out, JsonbContainer *in, int estimated_len, bool indent);
--- 76,82 ----
  static void datum_to_jsonb(Datum val, bool is_null, JsonbInState *result,
  			   JsonbTypeCategory tcategory, Oid outfuncoid,
  			   bool key_scalar);
! void add_jsonb(Datum val, bool is_null, JsonbInState *result,
  		  Oid val_type, bool key_scalar);
  static JsonbParseState *clone_parse_state(JsonbParseState *state);
  static char *JsonbToCStringWorker(StringInfo out, JsonbContainer *in, int estimated_len, bool indent);
***************
*** 1119,1125 **** composite_to_jsonb(Datum composite, JsonbInState *result)
   * lookups only once.
   */
  
! static void
  add_jsonb(Datum val, bool is_null, JsonbInState *result,
  		  Oid val_type, bool key_scalar)
  {
--- 1113,1119 ----
   * lookups only once.
   */
  
! void
  add_jsonb(Datum val, bool is_null, JsonbInState *result,
  		  Oid val_type, bool key_scalar)
  {
*** a/src/include/catalog/pg_proc.h
--- b/src/include/catalog/pg_proc.h
***************
*** 3075,3080 **** DATA(insert OID = 2084 (  pg_show_all_settings	PGNSP PGUID 12 1 1000 0 0 f f f f
--- 3075,3084 ----
  DESCR("SHOW ALL as a function");
  DATA(insert OID = 3329 (  pg_show_all_file_settings PGNSP PGUID 12 1 1000 0 0 f f f f t t v 0 0 2249 "" "{25,23,23,25,25,16,25}" "{o,o,o,o,o,o,o}" "{sourcefile,sourceline,seqno,name,setting,applied,error}" _null_ _null_ show_all_file_settings _null_ _null_ _null_ ));
  DESCR("show config file settings");
+ DATA(insert OID = 3997 (pg_hba_lookup PGNSP PGUID 12 1 1000 0 0 f f f f t t v 2 0 2249 "25 25" "{25,25,23,25,3802,3802,869,25,25,3802}" "{i,i,o,o,o,o,o,o,o,o}" "{database,user,line_number,type,database,user,address,hostname,method,options}" _null_ _null_ pg_hba_lookup_2args _null_ _null_ _null_));
+ DESCR("view client authentication settings");
+ DATA(insert OID = 3998 (pg_hba_lookup PGNSP PGUID 12 1 1000 0 0 f f f f t t v 4 0 2249 "25 25 25 25" "{25,25,25,25,23,25,3802,3802,869,25,25,3802}" "{i,i,i,i,o,o,o,o,o,o,o,o}" "{database,user,address,hostname,line_number,type,database,user,address,hostname,method,options}" _null_ _null_ pg_hba_lookup _null_ _null_ _null_));
+ DESCR("view client authentication settings");
  DATA(insert OID = 1371 (  pg_lock_status   PGNSP PGUID 12 1 1000 0 0 f f f f t t v 0 0 2249 "" "{25,26,26,23,21,25,28,26,26,21,25,23,25,16,16}" "{o,o,o,o,o,o,o,o,o,o,o,o,o,o,o}" "{locktype,database,relation,page,tuple,virtualxid,transactionid,classid,objid,objsubid,virtualtransaction,pid,mode,granted,fastpath}" _null_ _null_ pg_lock_status _null_ _null_ _null_ ));
  DESCR("view system lock information");
  DATA(insert OID = 1065 (  pg_prepared_xact PGNSP PGUID 12 1 1000 0 0 f f f f t t v 0 0 2249 "" "{28,25,1184,26,26}" "{o,o,o,o,o}" "{transaction,gid,prepared,ownerid,dbid}" _null_ _null_ pg_prepared_xact _null_ _null_ _null_ ));
*** a/src/include/libpq/hba.h
--- b/src/include/libpq/hba.h
***************
*** 96,101 **** typedef struct IdentLine
--- 96,103 ----
  /* kluge to avoid including libpq/libpq-be.h here */
  typedef struct Port hbaPort;
  
+ extern bool load_hba_failure;
+ 
  extern bool load_hba(void);
  extern bool load_ident(void);
  extern void hba_getauthmethod(hbaPort *port);
*** a/src/include/utils/builtins.h
--- b/src/include/utils/builtins.h
***************
*** 1118,1123 **** extern Datum show_config_by_name_missing_ok(PG_FUNCTION_ARGS);
--- 1118,1125 ----
  extern Datum set_config_by_name(PG_FUNCTION_ARGS);
  extern Datum show_all_settings(PG_FUNCTION_ARGS);
  extern Datum show_all_file_settings(PG_FUNCTION_ARGS);
+ extern Datum pg_hba_lookup_2args(PG_FUNCTION_ARGS);
+ extern Datum pg_hba_lookup(PG_FUNCTION_ARGS);
  
  /* lockfuncs.c */
  extern Datum pg_lock_status(PG_FUNCTION_ARGS);
*** a/src/include/utils/json.h
--- b/src/include/utils/json.h
***************
*** 43,49 **** extern Datum json_object(PG_FUNCTION_ARGS);
  extern Datum json_object_two_arg(PG_FUNCTION_ARGS);
  
  extern void escape_json(StringInfo buf, const char *str);
- 
  extern Datum json_typeof(PG_FUNCTION_ARGS);
  
  /* functions in jsonfuncs.c */
--- 43,48 ----
*** a/src/include/utils/jsonb.h
--- b/src/include/utils/jsonb.h
***************
*** 343,348 **** typedef struct JsonbIterator
--- 343,354 ----
  	struct JsonbIterator *parent;
  } JsonbIterator;
  
+ typedef struct JsonbInState
+ {
+ 	JsonbParseState *parseState;
+ 	JsonbValue *res;
+ } JsonbInState;
+ 
  /* I/O routines */
  extern Datum jsonb_in(PG_FUNCTION_ARGS);
  extern Datum jsonb_out(PG_FUNCTION_ARGS);
***************
*** 428,433 **** extern bool JsonbDeepContains(JsonbIterator **val,
--- 434,441 ----
  extern void JsonbHashScalarValue(const JsonbValue *scalarVal, uint32 *hash);
  
  /* jsonb.c support functions */
+ void add_jsonb(Datum val, bool is_null, JsonbInState *result,
+ 	Oid val_type, bool key_scalar);
  extern char *JsonbToCString(StringInfo out, JsonbContainer *in,
  			   int estimated_len);
  extern char *JsonbToCStringIndent(StringInfo out, JsonbContainer *in,
*** a/src/test/regress/expected/rules.out
--- b/src/test/regress/expected/rules.out
***************
*** 1327,1332 **** pg_group| SELECT pg_authid.rolname AS groname,
--- 1327,1344 ----
            WHERE (pg_auth_members.roleid = pg_authid.oid)) AS grolist
     FROM pg_authid
    WHERE (NOT pg_authid.rolcanlogin);
+ pg_hba_conf| SELECT a.line_number,
+     a.type,
+     a.keyword_databases,
+     a.databases,
+     a.keyword_users,
+     a.users,
+     a.address,
+     a.compare_method,
+     a.hostname,
+     a.method,
+     a.options
+    FROM pg_hba_conf() a(line_number, type, keyword_databases, databases, keyword_users, users, address, compare_method, hostname, method, options);
  pg_indexes| SELECT n.nspname AS schemaname,
      c.relname AS tablename,
      i.relname AS indexname,
