diff --git a/src/backend/nodes/outfuncs.c b/src/backend/nodes/outfuncs.c
index 5ba31580ae7bc0bdbb4e69eea6fec257efd1c1d6..646ac6daabf63b7f03e574f31506b3ba89880aa6 100644
--- a/src/backend/nodes/outfuncs.c
+++ b/src/backend/nodes/outfuncs.c
@@ -8,7 +8,7 @@
  *
  *
  * IDENTIFICATION
- *	  $PostgreSQL: pgsql/src/backend/nodes/outfuncs.c,v 1.263 2005/11/26 22:14:56 tgl Exp $
+ *	  $PostgreSQL: pgsql/src/backend/nodes/outfuncs.c,v 1.264 2005/11/28 04:35:30 tgl Exp $
  *
  * NOTES
  *	  Every node type that can appear in stored rules' parsetrees *must*
@@ -1597,6 +1597,10 @@ _outAExpr(StringInfo str, A_Expr *node)
 			appendStringInfo(str, " OF ");
 			WRITE_NODE_FIELD(name);
 			break;
+		case AEXPR_IN:
+			appendStringInfo(str, " IN ");
+			WRITE_NODE_FIELD(name);
+			break;
 		default:
 			appendStringInfo(str, " ??");
 			break;
@@ -1658,6 +1662,7 @@ _outAConst(StringInfo str, A_Const *node)
 {
 	WRITE_NODE_TYPE("A_CONST");
 
+	appendStringInfo(str, " :val ");
 	_outValue(str, &(node->val));
 	WRITE_NODE_FIELD(typename);
 }
diff --git a/src/backend/parser/gram.y b/src/backend/parser/gram.y
index 90c0fd3d544d9c20fc383481cd88807c09d38345..876e8b53ff5ae9e171d6f6b92d4cbc1c7dedc33b 100644
--- a/src/backend/parser/gram.y
+++ b/src/backend/parser/gram.y
@@ -11,7 +11,7 @@
  *
  *
  * IDENTIFICATION
- *	  $PostgreSQL: pgsql/src/backend/parser/gram.y,v 2.515 2005/11/22 15:24:17 adunstan Exp $
+ *	  $PostgreSQL: pgsql/src/backend/parser/gram.y,v 2.516 2005/11/28 04:35:31 tgl Exp $
  *
  * HISTORY
  *	  AUTHOR			DATE			MAJOR EVENT
@@ -6721,7 +6721,7 @@ a_expr:		c_expr									{ $$ = $1; }
 				}
 			| a_expr IS NOT OF '(' type_list ')'		%prec IS
 				{
-					$$ = (Node *) makeSimpleA_Expr(AEXPR_OF, "!=", $1, (Node *) $6);
+					$$ = (Node *) makeSimpleA_Expr(AEXPR_OF, "<>", $1, (Node *) $6);
 				}
 			| a_expr BETWEEN opt_asymmetric b_expr AND b_expr		%prec BETWEEN
 				{
@@ -6760,29 +6760,20 @@ a_expr:		c_expr									{ $$ = $1; }
 					/* in_expr returns a SubLink or a list of a_exprs */
 					if (IsA($3, SubLink))
 					{
-							SubLink *n = (SubLink *)$3;
-							n->subLinkType = ANY_SUBLINK;
-							if (IsA($1, RowExpr))
-								n->lefthand = ((RowExpr *) $1)->args;
-							else
-								n->lefthand = list_make1($1);
-							n->operName = list_make1(makeString("="));
-							$$ = (Node *)n;
+						/* generate foo = ANY (subquery) */
+						SubLink *n = (SubLink *) $3;
+						n->subLinkType = ANY_SUBLINK;
+						if (IsA($1, RowExpr))
+							n->lefthand = ((RowExpr *) $1)->args;
+						else
+							n->lefthand = list_make1($1);
+						n->operName = list_make1(makeString("="));
+						$$ = (Node *)n;
 					}
 					else
 					{
-						Node *n = NULL;
-						ListCell *l;
-						foreach(l, (List *) $3)
-						{
-							Node *cmp;
-							cmp = (Node *) makeSimpleA_Expr(AEXPR_OP, "=", $1, lfirst(l));
-							if (n == NULL)
-								n = cmp;
-							else
-								n = (Node *) makeA_Expr(AEXPR_OR, NIL, n, cmp);
-						}
-						$$ = n;
+						/* generate scalar IN expression */
+						$$ = (Node *) makeSimpleA_Expr(AEXPR_IN, "=", $1, $3);
 					}
 				}
 			| a_expr NOT IN_P in_expr
@@ -6790,8 +6781,9 @@ a_expr:		c_expr									{ $$ = $1; }
 					/* in_expr returns a SubLink or a list of a_exprs */
 					if (IsA($4, SubLink))
 					{
-						/* Make an IN node */
-						SubLink *n = (SubLink *)$4;
+						/* generate NOT (foo = ANY (subquery)) */
+						/* Make an = ANY node */
+						SubLink *n = (SubLink *) $4;
 						n->subLinkType = ANY_SUBLINK;
 						if (IsA($1, RowExpr))
 							n->lefthand = ((RowExpr *) $1)->args;
@@ -6803,18 +6795,8 @@ a_expr:		c_expr									{ $$ = $1; }
 					}
 					else
 					{
-						Node *n = NULL;
-						ListCell *l;
-						foreach(l, (List *) $4)
-						{
-							Node *cmp;
-							cmp = (Node *) makeSimpleA_Expr(AEXPR_OP, "<>", $1, lfirst(l));
-							if (n == NULL)
-								n = cmp;
-							else
-								n = (Node *) makeA_Expr(AEXPR_AND, NIL, n, cmp);
-						}
-						$$ = n;
+						/* generate scalar NOT IN expression */
+						$$ = (Node *) makeSimpleA_Expr(AEXPR_IN, "<>", $1, $4);
 					}
 				}
 			| a_expr subquery_Op sub_type select_with_parens %prec Op
@@ -6904,7 +6886,7 @@ b_expr:		c_expr
 				}
 			| b_expr IS NOT OF '(' type_list ')'	%prec IS
 				{
-					$$ = (Node *) makeSimpleA_Expr(AEXPR_OF, "!=", $1, (Node *) $6);
+					$$ = (Node *) makeSimpleA_Expr(AEXPR_OF, "<>", $1, (Node *) $6);
 				}
 		;
 
diff --git a/src/backend/parser/parse_expr.c b/src/backend/parser/parse_expr.c
index cf520d53369c91f12d31724fd4128e639d1b70e1..ece78b21820aa95ed25125b685a4ae983d0698ab 100644
--- a/src/backend/parser/parse_expr.c
+++ b/src/backend/parser/parse_expr.c
@@ -8,7 +8,7 @@
  *
  *
  * IDENTIFICATION
- *	  $PostgreSQL: pgsql/src/backend/parser/parse_expr.c,v 1.187 2005/11/22 18:17:16 momjian Exp $
+ *	  $PostgreSQL: pgsql/src/backend/parser/parse_expr.c,v 1.188 2005/11/28 04:35:31 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -47,6 +47,7 @@ static Node *transformAExprOpAll(ParseState *pstate, A_Expr *a);
 static Node *transformAExprDistinct(ParseState *pstate, A_Expr *a);
 static Node *transformAExprNullIf(ParseState *pstate, A_Expr *a);
 static Node *transformAExprOf(ParseState *pstate, A_Expr *a);
+static Node *transformAExprIn(ParseState *pstate, A_Expr *a);
 static Node *transformFuncCall(ParseState *pstate, FuncCall *fn);
 static Node *transformCaseExpr(ParseState *pstate, CaseExpr *c);
 static Node *transformSubLink(ParseState *pstate, SubLink *sublink);
@@ -64,9 +65,9 @@ static Node *transformIndirection(ParseState *pstate, Node *basenode,
 static Node *typecast_expression(ParseState *pstate, Node *expr,
 					TypeName *typename);
 static Node *make_row_op(ParseState *pstate, List *opname,
-			Node *ltree, Node *rtree);
+			RowExpr *lrow, RowExpr *rrow);
 static Node *make_row_distinct_op(ParseState *pstate, List *opname,
-					 Node *ltree, Node *rtree);
+					 RowExpr *lrow, RowExpr *rrow);
 static Expr *make_distinct_op(ParseState *pstate, List *opname,
 				 Node *ltree, Node *rtree);
 
@@ -180,6 +181,9 @@ transformExpr(ParseState *pstate, Node *expr)
 					case AEXPR_OF:
 						result = transformAExprOf(pstate, a);
 						break;
+					case AEXPR_IN:
+						result = transformAExprIn(pstate, a);
+						break;
 					default:
 						elog(ERROR, "unrecognized A_Expr kind: %d", a->kind);
 				}
@@ -603,7 +607,15 @@ transformAExprOp(ParseState *pstate, A_Expr *a)
 			 rexpr && IsA(rexpr, RowExpr))
 	{
 		/* "row op row" */
-		result = make_row_op(pstate, a->name, lexpr, rexpr);
+		lexpr = transformExpr(pstate, lexpr);
+		rexpr = transformExpr(pstate, rexpr);
+		Assert(IsA(lexpr, RowExpr));
+		Assert(IsA(rexpr, RowExpr));
+
+		result = make_row_op(pstate,
+							 a->name,
+							 (RowExpr *) lexpr,
+							 (RowExpr *) rexpr);
 	}
 	else
 	{
@@ -686,22 +698,20 @@ transformAExprOpAll(ParseState *pstate, A_Expr *a)
 static Node *
 transformAExprDistinct(ParseState *pstate, A_Expr *a)
 {
-	Node	   *lexpr = a->lexpr;
-	Node	   *rexpr = a->rexpr;
+	Node	   *lexpr = transformExpr(pstate, a->lexpr);
+	Node	   *rexpr = transformExpr(pstate, a->rexpr);
 
 	if (lexpr && IsA(lexpr, RowExpr) &&
 		rexpr && IsA(rexpr, RowExpr))
 	{
 		/* "row op row" */
 		return make_row_distinct_op(pstate, a->name,
-									lexpr, rexpr);
+									(RowExpr *) lexpr,
+									(RowExpr *) rexpr);
 	}
 	else
 	{
 		/* Ordinary scalar operator */
-		lexpr = transformExpr(pstate, lexpr);
-		rexpr = transformExpr(pstate, rexpr);
-
 		return (Node *) make_distinct_op(pstate,
 										 a->name,
 										 lexpr,
@@ -737,15 +747,14 @@ static Node *
 transformAExprOf(ParseState *pstate, A_Expr *a)
 {
 	/*
-	 * Checking an expression for match to type.  Will result in a boolean
-	 * constant node.
+	 * Checking an expression for match to a list of type names.
+	 * Will result in a boolean constant node.
 	 */
+	Node	   *lexpr = transformExpr(pstate, a->lexpr);
 	ListCell   *telem;
-	A_Const    *n;
 	Oid			ltype,
 				rtype;
 	bool		matched = false;
-	Node	   *lexpr = transformExpr(pstate, a->lexpr);
 
 	ltype = exprType(lexpr);
 	foreach(telem, (List *) a->rexpr)
@@ -757,18 +766,145 @@ transformAExprOf(ParseState *pstate, A_Expr *a)
 	}
 
 	/*
-	 * Expect two forms: equals or not equals.	Flip the sense of the result
+	 * We have two forms: equals or not equals.	Flip the sense of the result
 	 * for not equals.
 	 */
-	if (strcmp(strVal(linitial(a->name)), "!=") == 0)
+	if (strcmp(strVal(linitial(a->name)), "<>") == 0)
 		matched = (!matched);
 
-	n = makeNode(A_Const);
-	n->val.type = T_String;
-	n->val.val.str = (matched ? "t" : "f");
-	n->typename = SystemTypeName("bool");
+	return makeBoolConst(matched, false);
+}
+
+static Node *
+transformAExprIn(ParseState *pstate, A_Expr *a)
+{
+	Node	   *lexpr;
+	List	   *rexprs;
+	List	   *typeids;
+	bool		useOr;
+	bool		haveRowExpr;
+	Node	   *result;
+	ListCell   *l;
+
+	/*
+	 * If the operator is <>, combine with AND not OR.
+	 */
+	if (strcmp(strVal(linitial(a->name)), "<>") == 0)
+		useOr = false;
+	else
+		useOr = true;
+
+	/*
+	 * We try to generate a ScalarArrayOpExpr from IN/NOT IN, but this is
+	 * only possible if the inputs are all scalars (no RowExprs) and there
+	 * is a suitable array type available.  If not, we fall back to a
+	 * boolean condition tree with multiple copies of the lefthand expression.
+	 *
+	 * First step: transform all the inputs, and detect whether any are
+	 * RowExprs.
+	 */
+	lexpr = transformExpr(pstate, a->lexpr);
+	haveRowExpr = (lexpr && IsA(lexpr, RowExpr));
+	typeids = list_make1_oid(exprType(lexpr));
+	rexprs = NIL;
+	foreach(l, (List *) a->rexpr)
+	{
+		Node   *rexpr = transformExpr(pstate, lfirst(l));
+
+		haveRowExpr |= (rexpr && IsA(rexpr, RowExpr));
+		rexprs = lappend(rexprs, rexpr);
+		typeids = lappend_oid(typeids, exprType(rexpr));
+	}
 
-	return transformExpr(pstate, (Node *) n);
+	/*
+	 * If not forced by presence of RowExpr, try to resolve a common
+	 * scalar type for all the expressions, and see if it has an array type.
+	 * (But if there's only one righthand expression, we may as well just
+	 * fall through and generate a simple = comparison.)
+	 */
+	if (!haveRowExpr && list_length(rexprs) != 1)
+	{
+		Oid			scalar_type;
+		Oid			array_type;
+
+		/*
+		 * Select a common type for the array elements.  Note that since
+		 * the LHS' type is first in the list, it will be preferred when
+		 * there is doubt (eg, when all the RHS items are unknown literals).
+		 */
+		scalar_type = select_common_type(typeids, "IN");
+
+		/* Do we have an array type to use? */
+		array_type = get_array_type(scalar_type);
+		if (array_type != InvalidOid)
+		{
+			/*
+			 * OK: coerce all the right-hand inputs to the common type
+			 * and build an ArrayExpr for them.
+			 */
+			List	   *aexprs;
+			ArrayExpr  *newa;
+
+			aexprs = NIL;
+			foreach(l, rexprs)
+			{
+				Node	   *rexpr = (Node *) lfirst(l);
+
+				rexpr = coerce_to_common_type(pstate, rexpr,
+											  scalar_type,
+											  "IN");
+				aexprs = lappend(aexprs, rexpr);
+			}
+			newa = makeNode(ArrayExpr);
+			newa->array_typeid = array_type;
+			newa->element_typeid = scalar_type;
+			newa->elements = aexprs;
+			newa->multidims = false;
+
+			return (Node *) make_scalar_array_op(pstate,
+												 a->name,
+												 useOr,
+												 lexpr,
+												 (Node *) newa);
+		}
+	}
+
+	/*
+	 * Must do it the hard way, ie, with a boolean expression tree.
+	 */
+	result = NULL;
+	foreach(l, rexprs)
+	{
+		Node	   *rexpr = (Node *) lfirst(l);
+		Node	   *cmp;
+
+		if (haveRowExpr)
+		{
+			if (!IsA(lexpr, RowExpr) ||
+				!IsA(rexpr, RowExpr))
+				ereport(ERROR,
+						(errcode(ERRCODE_SYNTAX_ERROR),
+						 errmsg("arguments of row IN must all be row expressions")));
+			cmp = make_row_op(pstate,
+							  a->name,
+							  (RowExpr *) copyObject(lexpr),
+							  (RowExpr *) rexpr);
+		}
+		else
+			cmp = (Node *) make_op(pstate,
+								   a->name,
+								   copyObject(lexpr),
+								   rexpr);
+
+		cmp = coerce_to_boolean(pstate, cmp, "IN");
+		if (result == NULL)
+			result = cmp;
+		else
+			result = (Node *) makeBoolExpr(useOr ? OR_EXPR : AND_EXPR,
+										   list_make2(result, cmp));
+	}
+
+	return result;
 }
 
 static Node *
@@ -1818,32 +1954,25 @@ typecast_expression(ParseState *pstate, Node *expr, TypeName *typename)
 
 /*
  * Transform a "row op row" construct
+ *
+ * The input RowExprs are already transformed
  */
 static Node *
-make_row_op(ParseState *pstate, List *opname, Node *ltree, Node *rtree)
+make_row_op(ParseState *pstate, List *opname,
+			RowExpr *lrow, RowExpr *rrow)
 {
 	Node	   *result = NULL;
-	RowExpr    *lrow,
-			   *rrow;
-	List	   *largs,
-			   *rargs;
+	List	   *largs = lrow->args;
+	List	   *rargs = rrow->args;
 	ListCell   *l,
 			   *r;
 	char	   *oprname;
 	BoolExprType boolop;
 
-	/* Inputs are untransformed RowExprs */
-	lrow = (RowExpr *) transformExpr(pstate, ltree);
-	rrow = (RowExpr *) transformExpr(pstate, rtree);
-	Assert(IsA(lrow, RowExpr));
-	Assert(IsA(rrow, RowExpr));
-	largs = lrow->args;
-	rargs = rrow->args;
-
 	if (list_length(largs) != list_length(rargs))
 		ereport(ERROR,
 				(errcode(ERRCODE_SYNTAX_ERROR),
-				 errmsg("unequal number of entries in row expression")));
+				 errmsg("unequal number of entries in row expressions")));
 
 	/*
 	 * XXX it's really wrong to generate a simple AND combination for < <= >
@@ -1898,31 +2027,23 @@ make_row_op(ParseState *pstate, List *opname, Node *ltree, Node *rtree)
 
 /*
  * Transform a "row IS DISTINCT FROM row" construct
+ *
+ * The input RowExprs are already transformed
  */
 static Node *
 make_row_distinct_op(ParseState *pstate, List *opname,
-					 Node *ltree, Node *rtree)
+					 RowExpr *lrow, RowExpr *rrow)
 {
 	Node	   *result = NULL;
-	RowExpr    *lrow,
-			   *rrow;
-	List	   *largs,
-			   *rargs;
+	List	   *largs = lrow->args;
+	List	   *rargs = rrow->args;
 	ListCell   *l,
 			   *r;
 
-	/* Inputs are untransformed RowExprs */
-	lrow = (RowExpr *) transformExpr(pstate, ltree);
-	rrow = (RowExpr *) transformExpr(pstate, rtree);
-	Assert(IsA(lrow, RowExpr));
-	Assert(IsA(rrow, RowExpr));
-	largs = lrow->args;
-	rargs = rrow->args;
-
 	if (list_length(largs) != list_length(rargs))
 		ereport(ERROR,
 				(errcode(ERRCODE_SYNTAX_ERROR),
-				 errmsg("unequal number of entries in row expression")));
+				 errmsg("unequal number of entries in row expressions")));
 
 	forboth(l, largs, r, rargs)
 	{
diff --git a/src/include/nodes/parsenodes.h b/src/include/nodes/parsenodes.h
index 478279c54be938eb9256b767a983518f3b69b786..1ae6824954c7ef021cbc7ed163a4bc88b60d0944 100644
--- a/src/include/nodes/parsenodes.h
+++ b/src/include/nodes/parsenodes.h
@@ -7,7 +7,7 @@
  * Portions Copyright (c) 1996-2005, PostgreSQL Global Development Group
  * Portions Copyright (c) 1994, Regents of the University of California
  *
- * $PostgreSQL: pgsql/src/include/nodes/parsenodes.h,v 1.296 2005/11/22 18:17:31 momjian Exp $
+ * $PostgreSQL: pgsql/src/include/nodes/parsenodes.h,v 1.297 2005/11/28 04:35:32 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -194,7 +194,8 @@ typedef enum A_Expr_Kind
 	AEXPR_OP_ALL,				/* scalar op ALL (array) */
 	AEXPR_DISTINCT,				/* IS DISTINCT FROM - name must be "=" */
 	AEXPR_NULLIF,				/* NULLIF - name must be "=" */
-	AEXPR_OF					/* IS (not) OF - name must be "=" or "!=" */
+	AEXPR_OF,					/* IS [NOT] OF - name must be "=" or "<>" */
+	AEXPR_IN					/* [NOT] IN - name must be "=" or "<>" */
 } A_Expr_Kind;
 
 typedef struct A_Expr
diff --git a/src/test/regress/expected/rules.out b/src/test/regress/expected/rules.out
index 7a8dda3efa7979a6555f8abc41bcb0403c66a3be..2c8070d119586e5cc7f92d2ae95788e5e1fd8703 100644
--- a/src/test/regress/expected/rules.out
+++ b/src/test/regress/expected/rules.out
@@ -1286,22 +1286,22 @@ SELECT viewname, definition FROM pg_views WHERE schemaname <> 'information_schem
  pg_settings              | SELECT a.name, a.setting, a.category, a.short_desc, a.extra_desc, a.context, a.vartype, a.source, a.min_val, a.max_val FROM pg_show_all_settings() a(name text, setting text, category text, short_desc text, extra_desc text, context text, vartype text, source text, min_val text, max_val text);
  pg_shadow                | SELECT pg_authid.rolname AS usename, pg_authid.oid AS usesysid, pg_authid.rolcreatedb AS usecreatedb, pg_authid.rolsuper AS usesuper, pg_authid.rolcatupdate AS usecatupd, pg_authid.rolpassword AS passwd, (pg_authid.rolvaliduntil)::abstime AS valuntil, pg_authid.rolconfig AS useconfig FROM pg_authid WHERE pg_authid.rolcanlogin;
  pg_stat_activity         | SELECT d.oid AS datid, d.datname, pg_stat_get_backend_pid(s.backendid) AS procpid, pg_stat_get_backend_userid(s.backendid) AS usesysid, u.rolname AS usename, pg_stat_get_backend_activity(s.backendid) AS current_query, pg_stat_get_backend_activity_start(s.backendid) AS query_start, pg_stat_get_backend_start(s.backendid) AS backend_start, pg_stat_get_backend_client_addr(s.backendid) AS client_addr, pg_stat_get_backend_client_port(s.backendid) AS client_port FROM pg_database d, (SELECT pg_stat_get_backend_idset() AS backendid) s, pg_authid u WHERE ((pg_stat_get_backend_dbid(s.backendid) = d.oid) AND (pg_stat_get_backend_userid(s.backendid) = u.oid));
- pg_stat_all_indexes      | SELECT c.oid AS relid, i.oid AS indexrelid, n.nspname AS schemaname, c.relname, i.relname AS indexrelname, pg_stat_get_numscans(i.oid) AS idx_scan, pg_stat_get_tuples_returned(i.oid) AS idx_tup_read, pg_stat_get_tuples_fetched(i.oid) AS idx_tup_fetch FROM (((pg_class c JOIN pg_index x ON ((c.oid = x.indrelid))) JOIN pg_class i ON ((i.oid = x.indexrelid))) LEFT JOIN pg_namespace n ON ((n.oid = c.relnamespace))) WHERE ((c.relkind = 'r'::"char") OR (c.relkind = 't'::"char"));
- pg_stat_all_tables       | SELECT c.oid AS relid, n.nspname AS schemaname, c.relname, pg_stat_get_numscans(c.oid) AS seq_scan, pg_stat_get_tuples_returned(c.oid) AS seq_tup_read, (sum(pg_stat_get_numscans(i.indexrelid)))::bigint AS idx_scan, ((sum(pg_stat_get_tuples_fetched(i.indexrelid)))::bigint + pg_stat_get_tuples_fetched(c.oid)) AS idx_tup_fetch, pg_stat_get_tuples_inserted(c.oid) AS n_tup_ins, pg_stat_get_tuples_updated(c.oid) AS n_tup_upd, pg_stat_get_tuples_deleted(c.oid) AS n_tup_del FROM ((pg_class c LEFT JOIN pg_index i ON ((c.oid = i.indrelid))) LEFT JOIN pg_namespace n ON ((n.oid = c.relnamespace))) WHERE ((c.relkind = 'r'::"char") OR (c.relkind = 't'::"char")) GROUP BY c.oid, n.nspname, c.relname;
+ pg_stat_all_indexes      | SELECT c.oid AS relid, i.oid AS indexrelid, n.nspname AS schemaname, c.relname, i.relname AS indexrelname, pg_stat_get_numscans(i.oid) AS idx_scan, pg_stat_get_tuples_returned(i.oid) AS idx_tup_read, pg_stat_get_tuples_fetched(i.oid) AS idx_tup_fetch FROM (((pg_class c JOIN pg_index x ON ((c.oid = x.indrelid))) JOIN pg_class i ON ((i.oid = x.indexrelid))) LEFT JOIN pg_namespace n ON ((n.oid = c.relnamespace))) WHERE (c.relkind = ANY (ARRAY['r'::"char", 't'::"char"]));
+ pg_stat_all_tables       | SELECT c.oid AS relid, n.nspname AS schemaname, c.relname, pg_stat_get_numscans(c.oid) AS seq_scan, pg_stat_get_tuples_returned(c.oid) AS seq_tup_read, (sum(pg_stat_get_numscans(i.indexrelid)))::bigint AS idx_scan, ((sum(pg_stat_get_tuples_fetched(i.indexrelid)))::bigint + pg_stat_get_tuples_fetched(c.oid)) AS idx_tup_fetch, pg_stat_get_tuples_inserted(c.oid) AS n_tup_ins, pg_stat_get_tuples_updated(c.oid) AS n_tup_upd, pg_stat_get_tuples_deleted(c.oid) AS n_tup_del FROM ((pg_class c LEFT JOIN pg_index i ON ((c.oid = i.indrelid))) LEFT JOIN pg_namespace n ON ((n.oid = c.relnamespace))) WHERE (c.relkind = ANY (ARRAY['r'::"char", 't'::"char"])) GROUP BY c.oid, n.nspname, c.relname;
  pg_stat_database         | SELECT d.oid AS datid, d.datname, pg_stat_get_db_numbackends(d.oid) AS numbackends, pg_stat_get_db_xact_commit(d.oid) AS xact_commit, pg_stat_get_db_xact_rollback(d.oid) AS xact_rollback, (pg_stat_get_db_blocks_fetched(d.oid) - pg_stat_get_db_blocks_hit(d.oid)) AS blks_read, pg_stat_get_db_blocks_hit(d.oid) AS blks_hit FROM pg_database d;
- pg_stat_sys_indexes      | SELECT pg_stat_all_indexes.relid, pg_stat_all_indexes.indexrelid, pg_stat_all_indexes.schemaname, pg_stat_all_indexes.relname, pg_stat_all_indexes.indexrelname, pg_stat_all_indexes.idx_scan, pg_stat_all_indexes.idx_tup_read, pg_stat_all_indexes.idx_tup_fetch FROM pg_stat_all_indexes WHERE (((pg_stat_all_indexes.schemaname = 'pg_catalog'::name) OR (pg_stat_all_indexes.schemaname = 'pg_toast'::name)) OR (pg_stat_all_indexes.schemaname = 'information_schema'::name));
- pg_stat_sys_tables       | SELECT pg_stat_all_tables.relid, pg_stat_all_tables.schemaname, pg_stat_all_tables.relname, pg_stat_all_tables.seq_scan, pg_stat_all_tables.seq_tup_read, pg_stat_all_tables.idx_scan, pg_stat_all_tables.idx_tup_fetch, pg_stat_all_tables.n_tup_ins, pg_stat_all_tables.n_tup_upd, pg_stat_all_tables.n_tup_del FROM pg_stat_all_tables WHERE (((pg_stat_all_tables.schemaname = 'pg_catalog'::name) OR (pg_stat_all_tables.schemaname = 'pg_toast'::name)) OR (pg_stat_all_tables.schemaname = 'information_schema'::name));
- pg_stat_user_indexes     | SELECT pg_stat_all_indexes.relid, pg_stat_all_indexes.indexrelid, pg_stat_all_indexes.schemaname, pg_stat_all_indexes.relname, pg_stat_all_indexes.indexrelname, pg_stat_all_indexes.idx_scan, pg_stat_all_indexes.idx_tup_read, pg_stat_all_indexes.idx_tup_fetch FROM pg_stat_all_indexes WHERE (((pg_stat_all_indexes.schemaname <> 'pg_catalog'::name) AND (pg_stat_all_indexes.schemaname <> 'pg_toast'::name)) AND (pg_stat_all_indexes.schemaname <> 'information_schema'::name));
- pg_stat_user_tables      | SELECT pg_stat_all_tables.relid, pg_stat_all_tables.schemaname, pg_stat_all_tables.relname, pg_stat_all_tables.seq_scan, pg_stat_all_tables.seq_tup_read, pg_stat_all_tables.idx_scan, pg_stat_all_tables.idx_tup_fetch, pg_stat_all_tables.n_tup_ins, pg_stat_all_tables.n_tup_upd, pg_stat_all_tables.n_tup_del FROM pg_stat_all_tables WHERE (((pg_stat_all_tables.schemaname <> 'pg_catalog'::name) AND (pg_stat_all_tables.schemaname <> 'pg_toast'::name)) AND (pg_stat_all_tables.schemaname <> 'information_schema'::name));
- pg_statio_all_indexes    | SELECT c.oid AS relid, i.oid AS indexrelid, n.nspname AS schemaname, c.relname, i.relname AS indexrelname, (pg_stat_get_blocks_fetched(i.oid) - pg_stat_get_blocks_hit(i.oid)) AS idx_blks_read, pg_stat_get_blocks_hit(i.oid) AS idx_blks_hit FROM (((pg_class c JOIN pg_index x ON ((c.oid = x.indrelid))) JOIN pg_class i ON ((i.oid = x.indexrelid))) LEFT JOIN pg_namespace n ON ((n.oid = c.relnamespace))) WHERE ((c.relkind = 'r'::"char") OR (c.relkind = 't'::"char"));
+ pg_stat_sys_indexes      | SELECT pg_stat_all_indexes.relid, pg_stat_all_indexes.indexrelid, pg_stat_all_indexes.schemaname, pg_stat_all_indexes.relname, pg_stat_all_indexes.indexrelname, pg_stat_all_indexes.idx_scan, pg_stat_all_indexes.idx_tup_read, pg_stat_all_indexes.idx_tup_fetch FROM pg_stat_all_indexes WHERE (pg_stat_all_indexes.schemaname = ANY (ARRAY['pg_catalog'::name, 'pg_toast'::name, 'information_schema'::name]));
+ pg_stat_sys_tables       | SELECT pg_stat_all_tables.relid, pg_stat_all_tables.schemaname, pg_stat_all_tables.relname, pg_stat_all_tables.seq_scan, pg_stat_all_tables.seq_tup_read, pg_stat_all_tables.idx_scan, pg_stat_all_tables.idx_tup_fetch, pg_stat_all_tables.n_tup_ins, pg_stat_all_tables.n_tup_upd, pg_stat_all_tables.n_tup_del FROM pg_stat_all_tables WHERE (pg_stat_all_tables.schemaname = ANY (ARRAY['pg_catalog'::name, 'pg_toast'::name, 'information_schema'::name]));
+ pg_stat_user_indexes     | SELECT pg_stat_all_indexes.relid, pg_stat_all_indexes.indexrelid, pg_stat_all_indexes.schemaname, pg_stat_all_indexes.relname, pg_stat_all_indexes.indexrelname, pg_stat_all_indexes.idx_scan, pg_stat_all_indexes.idx_tup_read, pg_stat_all_indexes.idx_tup_fetch FROM pg_stat_all_indexes WHERE (pg_stat_all_indexes.schemaname <> ALL (ARRAY['pg_catalog'::name, 'pg_toast'::name, 'information_schema'::name]));
+ pg_stat_user_tables      | SELECT pg_stat_all_tables.relid, pg_stat_all_tables.schemaname, pg_stat_all_tables.relname, pg_stat_all_tables.seq_scan, pg_stat_all_tables.seq_tup_read, pg_stat_all_tables.idx_scan, pg_stat_all_tables.idx_tup_fetch, pg_stat_all_tables.n_tup_ins, pg_stat_all_tables.n_tup_upd, pg_stat_all_tables.n_tup_del FROM pg_stat_all_tables WHERE (pg_stat_all_tables.schemaname <> ALL (ARRAY['pg_catalog'::name, 'pg_toast'::name, 'information_schema'::name]));
+ pg_statio_all_indexes    | SELECT c.oid AS relid, i.oid AS indexrelid, n.nspname AS schemaname, c.relname, i.relname AS indexrelname, (pg_stat_get_blocks_fetched(i.oid) - pg_stat_get_blocks_hit(i.oid)) AS idx_blks_read, pg_stat_get_blocks_hit(i.oid) AS idx_blks_hit FROM (((pg_class c JOIN pg_index x ON ((c.oid = x.indrelid))) JOIN pg_class i ON ((i.oid = x.indexrelid))) LEFT JOIN pg_namespace n ON ((n.oid = c.relnamespace))) WHERE (c.relkind = ANY (ARRAY['r'::"char", 't'::"char"]));
  pg_statio_all_sequences  | SELECT c.oid AS relid, n.nspname AS schemaname, c.relname, (pg_stat_get_blocks_fetched(c.oid) - pg_stat_get_blocks_hit(c.oid)) AS blks_read, pg_stat_get_blocks_hit(c.oid) AS blks_hit FROM (pg_class c LEFT JOIN pg_namespace n ON ((n.oid = c.relnamespace))) WHERE (c.relkind = 'S'::"char");
- pg_statio_all_tables     | SELECT c.oid AS relid, n.nspname AS schemaname, c.relname, (pg_stat_get_blocks_fetched(c.oid) - pg_stat_get_blocks_hit(c.oid)) AS heap_blks_read, pg_stat_get_blocks_hit(c.oid) AS heap_blks_hit, (sum((pg_stat_get_blocks_fetched(i.indexrelid) - pg_stat_get_blocks_hit(i.indexrelid))))::bigint AS idx_blks_read, (sum(pg_stat_get_blocks_hit(i.indexrelid)))::bigint AS idx_blks_hit, (pg_stat_get_blocks_fetched(t.oid) - pg_stat_get_blocks_hit(t.oid)) AS toast_blks_read, pg_stat_get_blocks_hit(t.oid) AS toast_blks_hit, (pg_stat_get_blocks_fetched(x.oid) - pg_stat_get_blocks_hit(x.oid)) AS tidx_blks_read, pg_stat_get_blocks_hit(x.oid) AS tidx_blks_hit FROM ((((pg_class c LEFT JOIN pg_index i ON ((c.oid = i.indrelid))) LEFT JOIN pg_class t ON ((c.reltoastrelid = t.oid))) LEFT JOIN pg_class x ON ((t.reltoastidxid = x.oid))) LEFT JOIN pg_namespace n ON ((n.oid = c.relnamespace))) WHERE ((c.relkind = 'r'::"char") OR (c.relkind = 't'::"char")) GROUP BY c.oid, n.nspname, c.relname, t.oid, x.oid;
- pg_statio_sys_indexes    | SELECT pg_statio_all_indexes.relid, pg_statio_all_indexes.indexrelid, pg_statio_all_indexes.schemaname, pg_statio_all_indexes.relname, pg_statio_all_indexes.indexrelname, pg_statio_all_indexes.idx_blks_read, pg_statio_all_indexes.idx_blks_hit FROM pg_statio_all_indexes WHERE (((pg_statio_all_indexes.schemaname = 'pg_catalog'::name) OR (pg_statio_all_indexes.schemaname = 'pg_toast'::name)) OR (pg_statio_all_indexes.schemaname = 'information_schema'::name));
- pg_statio_sys_sequences  | SELECT pg_statio_all_sequences.relid, pg_statio_all_sequences.schemaname, pg_statio_all_sequences.relname, pg_statio_all_sequences.blks_read, pg_statio_all_sequences.blks_hit FROM pg_statio_all_sequences WHERE (((pg_statio_all_sequences.schemaname = 'pg_catalog'::name) OR (pg_statio_all_sequences.schemaname = 'pg_toast'::name)) OR (pg_statio_all_sequences.schemaname = 'information_schema'::name));
- pg_statio_sys_tables     | SELECT pg_statio_all_tables.relid, pg_statio_all_tables.schemaname, pg_statio_all_tables.relname, pg_statio_all_tables.heap_blks_read, pg_statio_all_tables.heap_blks_hit, pg_statio_all_tables.idx_blks_read, pg_statio_all_tables.idx_blks_hit, pg_statio_all_tables.toast_blks_read, pg_statio_all_tables.toast_blks_hit, pg_statio_all_tables.tidx_blks_read, pg_statio_all_tables.tidx_blks_hit FROM pg_statio_all_tables WHERE (((pg_statio_all_tables.schemaname = 'pg_catalog'::name) OR (pg_statio_all_tables.schemaname = 'pg_toast'::name)) OR (pg_statio_all_tables.schemaname = 'information_schema'::name));
- pg_statio_user_indexes   | SELECT pg_statio_all_indexes.relid, pg_statio_all_indexes.indexrelid, pg_statio_all_indexes.schemaname, pg_statio_all_indexes.relname, pg_statio_all_indexes.indexrelname, pg_statio_all_indexes.idx_blks_read, pg_statio_all_indexes.idx_blks_hit FROM pg_statio_all_indexes WHERE (((pg_statio_all_indexes.schemaname <> 'pg_catalog'::name) AND (pg_statio_all_indexes.schemaname <> 'pg_toast'::name)) AND (pg_statio_all_indexes.schemaname <> 'information_schema'::name));
- pg_statio_user_sequences | SELECT pg_statio_all_sequences.relid, pg_statio_all_sequences.schemaname, pg_statio_all_sequences.relname, pg_statio_all_sequences.blks_read, pg_statio_all_sequences.blks_hit FROM pg_statio_all_sequences WHERE (((pg_statio_all_sequences.schemaname <> 'pg_catalog'::name) AND (pg_statio_all_sequences.schemaname <> 'pg_toast'::name)) AND (pg_statio_all_sequences.schemaname <> 'information_schema'::name));
- pg_statio_user_tables    | SELECT pg_statio_all_tables.relid, pg_statio_all_tables.schemaname, pg_statio_all_tables.relname, pg_statio_all_tables.heap_blks_read, pg_statio_all_tables.heap_blks_hit, pg_statio_all_tables.idx_blks_read, pg_statio_all_tables.idx_blks_hit, pg_statio_all_tables.toast_blks_read, pg_statio_all_tables.toast_blks_hit, pg_statio_all_tables.tidx_blks_read, pg_statio_all_tables.tidx_blks_hit FROM pg_statio_all_tables WHERE (((pg_statio_all_tables.schemaname <> 'pg_catalog'::name) AND (pg_statio_all_tables.schemaname <> 'pg_toast'::name)) AND (pg_statio_all_tables.schemaname <> 'information_schema'::name));
+ pg_statio_all_tables     | SELECT c.oid AS relid, n.nspname AS schemaname, c.relname, (pg_stat_get_blocks_fetched(c.oid) - pg_stat_get_blocks_hit(c.oid)) AS heap_blks_read, pg_stat_get_blocks_hit(c.oid) AS heap_blks_hit, (sum((pg_stat_get_blocks_fetched(i.indexrelid) - pg_stat_get_blocks_hit(i.indexrelid))))::bigint AS idx_blks_read, (sum(pg_stat_get_blocks_hit(i.indexrelid)))::bigint AS idx_blks_hit, (pg_stat_get_blocks_fetched(t.oid) - pg_stat_get_blocks_hit(t.oid)) AS toast_blks_read, pg_stat_get_blocks_hit(t.oid) AS toast_blks_hit, (pg_stat_get_blocks_fetched(x.oid) - pg_stat_get_blocks_hit(x.oid)) AS tidx_blks_read, pg_stat_get_blocks_hit(x.oid) AS tidx_blks_hit FROM ((((pg_class c LEFT JOIN pg_index i ON ((c.oid = i.indrelid))) LEFT JOIN pg_class t ON ((c.reltoastrelid = t.oid))) LEFT JOIN pg_class x ON ((t.reltoastidxid = x.oid))) LEFT JOIN pg_namespace n ON ((n.oid = c.relnamespace))) WHERE (c.relkind = ANY (ARRAY['r'::"char", 't'::"char"])) GROUP BY c.oid, n.nspname, c.relname, t.oid, x.oid;
+ pg_statio_sys_indexes    | SELECT pg_statio_all_indexes.relid, pg_statio_all_indexes.indexrelid, pg_statio_all_indexes.schemaname, pg_statio_all_indexes.relname, pg_statio_all_indexes.indexrelname, pg_statio_all_indexes.idx_blks_read, pg_statio_all_indexes.idx_blks_hit FROM pg_statio_all_indexes WHERE (pg_statio_all_indexes.schemaname = ANY (ARRAY['pg_catalog'::name, 'pg_toast'::name, 'information_schema'::name]));
+ pg_statio_sys_sequences  | SELECT pg_statio_all_sequences.relid, pg_statio_all_sequences.schemaname, pg_statio_all_sequences.relname, pg_statio_all_sequences.blks_read, pg_statio_all_sequences.blks_hit FROM pg_statio_all_sequences WHERE (pg_statio_all_sequences.schemaname = ANY (ARRAY['pg_catalog'::name, 'pg_toast'::name, 'information_schema'::name]));
+ pg_statio_sys_tables     | SELECT pg_statio_all_tables.relid, pg_statio_all_tables.schemaname, pg_statio_all_tables.relname, pg_statio_all_tables.heap_blks_read, pg_statio_all_tables.heap_blks_hit, pg_statio_all_tables.idx_blks_read, pg_statio_all_tables.idx_blks_hit, pg_statio_all_tables.toast_blks_read, pg_statio_all_tables.toast_blks_hit, pg_statio_all_tables.tidx_blks_read, pg_statio_all_tables.tidx_blks_hit FROM pg_statio_all_tables WHERE (pg_statio_all_tables.schemaname = ANY (ARRAY['pg_catalog'::name, 'pg_toast'::name, 'information_schema'::name]));
+ pg_statio_user_indexes   | SELECT pg_statio_all_indexes.relid, pg_statio_all_indexes.indexrelid, pg_statio_all_indexes.schemaname, pg_statio_all_indexes.relname, pg_statio_all_indexes.indexrelname, pg_statio_all_indexes.idx_blks_read, pg_statio_all_indexes.idx_blks_hit FROM pg_statio_all_indexes WHERE (pg_statio_all_indexes.schemaname <> ALL (ARRAY['pg_catalog'::name, 'pg_toast'::name, 'information_schema'::name]));
+ pg_statio_user_sequences | SELECT pg_statio_all_sequences.relid, pg_statio_all_sequences.schemaname, pg_statio_all_sequences.relname, pg_statio_all_sequences.blks_read, pg_statio_all_sequences.blks_hit FROM pg_statio_all_sequences WHERE (pg_statio_all_sequences.schemaname <> ALL (ARRAY['pg_catalog'::name, 'pg_toast'::name, 'information_schema'::name]));
+ pg_statio_user_tables    | SELECT pg_statio_all_tables.relid, pg_statio_all_tables.schemaname, pg_statio_all_tables.relname, pg_statio_all_tables.heap_blks_read, pg_statio_all_tables.heap_blks_hit, pg_statio_all_tables.idx_blks_read, pg_statio_all_tables.idx_blks_hit, pg_statio_all_tables.toast_blks_read, pg_statio_all_tables.toast_blks_hit, pg_statio_all_tables.tidx_blks_read, pg_statio_all_tables.tidx_blks_hit FROM pg_statio_all_tables WHERE (pg_statio_all_tables.schemaname <> ALL (ARRAY['pg_catalog'::name, 'pg_toast'::name, 'information_schema'::name]));
  pg_stats                 | SELECT n.nspname AS schemaname, c.relname AS tablename, a.attname, s.stanullfrac AS null_frac, s.stawidth AS avg_width, s.stadistinct AS n_distinct, CASE 1 WHEN s.stakind1 THEN s.stavalues1 WHEN s.stakind2 THEN s.stavalues2 WHEN s.stakind3 THEN s.stavalues3 WHEN s.stakind4 THEN s.stavalues4 ELSE NULL::"unknown" END AS most_common_vals, CASE 1 WHEN s.stakind1 THEN s.stanumbers1 WHEN s.stakind2 THEN s.stanumbers2 WHEN s.stakind3 THEN s.stanumbers3 WHEN s.stakind4 THEN s.stanumbers4 ELSE NULL::real[] END AS most_common_freqs, CASE 2 WHEN s.stakind1 THEN s.stavalues1 WHEN s.stakind2 THEN s.stavalues2 WHEN s.stakind3 THEN s.stavalues3 WHEN s.stakind4 THEN s.stavalues4 ELSE NULL::"unknown" END AS histogram_bounds, CASE 3 WHEN s.stakind1 THEN s.stanumbers1[1] WHEN s.stakind2 THEN s.stanumbers2[1] WHEN s.stakind3 THEN s.stanumbers3[1] WHEN s.stakind4 THEN s.stanumbers4[1] ELSE NULL::real END AS correlation FROM (((pg_statistic s JOIN pg_class c ON ((c.oid = s.starelid))) JOIN pg_attribute a ON (((c.oid = a.attrelid) AND (a.attnum = s.staattnum)))) LEFT JOIN pg_namespace n ON ((n.oid = c.relnamespace))) WHERE has_table_privilege(c.oid, 'select'::text);
  pg_tables                | SELECT n.nspname AS schemaname, c.relname AS tablename, pg_get_userbyid(c.relowner) AS tableowner, t.spcname AS "tablespace", c.relhasindex AS hasindexes, c.relhasrules AS hasrules, (c.reltriggers > 0) AS hastriggers FROM ((pg_class c LEFT JOIN pg_namespace n ON ((n.oid = c.relnamespace))) LEFT JOIN pg_tablespace t ON ((t.oid = c.reltablespace))) WHERE (c.relkind = 'r'::"char");
  pg_user                  | SELECT pg_shadow.usename, pg_shadow.usesysid, pg_shadow.usecreatedb, pg_shadow.usesuper, pg_shadow.usecatupd, '********'::text AS passwd, pg_shadow.valuntil, pg_shadow.useconfig FROM pg_shadow;