diff --git a/src/backend/utils/adt/ruleutils.c b/src/backend/utils/adt/ruleutils.c
index a5f9d2ace1a0c319137d339c343e945381079f9d..6d4d926078d4385131b14580f9d44f83174741da 100644
--- a/src/backend/utils/adt/ruleutils.c
+++ b/src/backend/utils/adt/ruleutils.c
@@ -3,7 +3,7 @@
  *				back to source text
  *
  * IDENTIFICATION
- *	  $Header: /cvsroot/pgsql/src/backend/utils/adt/ruleutils.c,v 1.82 2001/08/12 21:35:19 tgl Exp $
+ *	  $Header: /cvsroot/pgsql/src/backend/utils/adt/ruleutils.c,v 1.83 2001/10/01 20:15:26 tgl Exp $
  *
  *	  This software is copyrighted by Jan Wieck - Hamburg.
  *
@@ -41,7 +41,9 @@
 #include <fcntl.h>
 
 #include "catalog/heap.h"
+#include "catalog/index.h"
 #include "catalog/pg_index.h"
+#include "catalog/pg_opclass.h"
 #include "catalog/pg_operator.h"
 #include "catalog/pg_shadow.h"
 #include "executor/spi.h"
@@ -94,10 +96,6 @@ static void *plan_getrule = NULL;
 static char *query_getrule = "SELECT * FROM pg_rewrite WHERE rulename = $1";
 static void *plan_getview = NULL;
 static char *query_getview = "SELECT * FROM pg_rewrite WHERE rulename = $1";
-static void *plan_getam = NULL;
-static char *query_getam = "SELECT * FROM pg_am WHERE oid = $1";
-static void *plan_getopclass = NULL;
-static char *query_getopclass = "SELECT * FROM pg_opclass WHERE oid = $1";
 
 
 /* ----------
@@ -138,6 +136,8 @@ static void get_sublink_expr(Node *node, deparse_context *context);
 static void get_from_clause(Query *query, deparse_context *context);
 static void get_from_clause_item(Node *jtnode, Query *query,
 					 deparse_context *context);
+static void get_opclass_name(Oid opclass, bool only_nondefault,
+							 StringInfo buf);
 static bool tleIsArrayAssign(TargetEntry *tle);
 static char *quote_identifier(char *ident);
 static char *get_relation_name(Oid relid);
@@ -341,48 +341,16 @@ pg_get_indexdef(PG_FUNCTION_ARGS)
 	HeapTuple	ht_idx;
 	HeapTuple	ht_idxrel;
 	HeapTuple	ht_indrel;
-	HeapTuple	spi_tup;
-	TupleDesc	spi_ttc;
-	int			spi_fno;
 	Form_pg_index idxrec;
 	Form_pg_class idxrelrec;
 	Form_pg_class indrelrec;
-	Datum		spi_args[1];
-	char		spi_nulls[2];
-	int			spirc;
+	Form_pg_am	amrec;
 	int			len;
 	int			keyno;
 	StringInfoData buf;
 	StringInfoData keybuf;
 	char	   *sep;
 
-	/*
-	 * Connect to SPI manager
-	 */
-	if (SPI_connect() != SPI_OK_CONNECT)
-		elog(ERROR, "get_indexdef: cannot connect to SPI manager");
-
-	/*
-	 * On the first call prepare the plans to lookup pg_am and pg_opclass.
-	 */
-	if (plan_getam == NULL)
-	{
-		Oid			argtypes[1];
-		void	   *plan;
-
-		argtypes[0] = OIDOID;
-		plan = SPI_prepare(query_getam, 1, argtypes);
-		if (plan == NULL)
-			elog(ERROR, "SPI_prepare() failed for \"%s\"", query_getam);
-		plan_getam = SPI_saveplan(plan);
-
-		argtypes[0] = OIDOID;
-		plan = SPI_prepare(query_getopclass, 1, argtypes);
-		if (plan == NULL)
-			elog(ERROR, "SPI_prepare() failed for \"%s\"", query_getopclass);
-		plan_getopclass = SPI_saveplan(plan);
-	}
-
 	/*
 	 * Fetch the pg_index tuple by the Oid of the index
 	 */
@@ -414,21 +382,14 @@ pg_get_indexdef(PG_FUNCTION_ARGS)
 	indrelrec = (Form_pg_class) GETSTRUCT(ht_indrel);
 
 	/*
-	 * Get the am name for the index relation
+	 * Fetch the pg_am tuple of the index' access method
+	 *
+	 * There is no syscache for this, so use index.c subroutine.
 	 */
-	spi_args[0] = ObjectIdGetDatum(idxrelrec->relam);
-	spi_nulls[0] = ' ';
-	spi_nulls[1] = '\0';
-	spirc = SPI_execp(plan_getam, spi_args, spi_nulls, 1);
-	if (spirc != SPI_OK_SELECT)
-		elog(ERROR, "failed to get pg_am tuple for index %s",
-			 NameStr(idxrelrec->relname));
-	if (SPI_processed != 1)
-		elog(ERROR, "failed to get pg_am tuple for index %s",
-			 NameStr(idxrelrec->relname));
-	spi_tup = SPI_tuptable->vals[0];
-	spi_ttc = SPI_tuptable->tupdesc;
-	spi_fno = SPI_fnumber(spi_ttc, "amname");
+	amrec = AccessMethodObjectIdGetForm(idxrelrec->relam,
+										CurrentMemoryContext);
+	if (!amrec)
+		elog(ERROR, "lookup for AM %u failed", idxrelrec->relam);
 
 	/*
 	 * Start the index definition
@@ -436,13 +397,12 @@ pg_get_indexdef(PG_FUNCTION_ARGS)
 	initStringInfo(&buf);
 	appendStringInfo(&buf, "CREATE %sINDEX %s ON %s USING %s (",
 					 idxrec->indisunique ? "UNIQUE " : "",
-				  quote_identifier(pstrdup(NameStr(idxrelrec->relname))),
-				  quote_identifier(pstrdup(NameStr(indrelrec->relname))),
-					 quote_identifier(SPI_getvalue(spi_tup, spi_ttc,
-												   spi_fno)));
+					 quote_identifier(NameStr(idxrelrec->relname)),
+					 quote_identifier(NameStr(indrelrec->relname)),
+					 quote_identifier(NameStr(amrec->amname)));
 
 	/*
-	 * Collect the indexed attributes
+	 * Collect the indexed attributes in keybuf
 	 */
 	initStringInfo(&keybuf);
 	sep = "";
@@ -465,29 +425,14 @@ pg_get_indexdef(PG_FUNCTION_ARGS)
 		 * If not a functional index, add the operator class name
 		 */
 		if (idxrec->indproc == InvalidOid)
-		{
-			spi_args[0] = ObjectIdGetDatum(idxrec->indclass[keyno]);
-			spi_nulls[0] = ' ';
-			spi_nulls[1] = '\0';
-			spirc = SPI_execp(plan_getopclass, spi_args, spi_nulls, 1);
-			if (spirc != SPI_OK_SELECT)
-				elog(ERROR, "failed to get pg_opclass tuple %u", idxrec->indclass[keyno]);
-			if (SPI_processed != 1)
-				elog(ERROR, "failed to get pg_opclass tuple %u", idxrec->indclass[keyno]);
-			spi_tup = SPI_tuptable->vals[0];
-			spi_ttc = SPI_tuptable->tupdesc;
-			spi_fno = SPI_fnumber(spi_ttc, "opcname");
-			appendStringInfo(&keybuf, " %s",
-						  quote_identifier(SPI_getvalue(spi_tup, spi_ttc,
-														spi_fno)));
-		}
+			get_opclass_name(idxrec->indclass[keyno], true, &keybuf);
 	}
 
-	/*
-	 * For functional index say 'func (attrs) opclass'
-	 */
 	if (idxrec->indproc != InvalidOid)
 	{
+		/*
+		 * For functional index say 'func (attrs) opclass'
+		 */
 		HeapTuple	proctup;
 		Form_pg_proc procStruct;
 
@@ -498,58 +443,67 @@ pg_get_indexdef(PG_FUNCTION_ARGS)
 			elog(ERROR, "cache lookup for proc %u failed", idxrec->indproc);
 		procStruct = (Form_pg_proc) GETSTRUCT(proctup);
 
-		appendStringInfo(&buf, "%s(%s) ",
-				 quote_identifier(pstrdup(NameStr(procStruct->proname))),
+		appendStringInfo(&buf, "%s(%s)",
+						 quote_identifier(NameStr(procStruct->proname)),
 						 keybuf.data);
+		get_opclass_name(idxrec->indclass[0], true, &buf);
 
-		spi_args[0] = ObjectIdGetDatum(idxrec->indclass[0]);
-		spi_nulls[0] = ' ';
-		spi_nulls[1] = '\0';
-		spirc = SPI_execp(plan_getopclass, spi_args, spi_nulls, 1);
-		if (spirc != SPI_OK_SELECT)
-			elog(ERROR, "failed to get pg_opclass tuple %u", idxrec->indclass[0]);
-		if (SPI_processed != 1)
-			elog(ERROR, "failed to get pg_opclass tuple %u", idxrec->indclass[0]);
-		spi_tup = SPI_tuptable->vals[0];
-		spi_ttc = SPI_tuptable->tupdesc;
-		spi_fno = SPI_fnumber(spi_ttc, "opcname");
-		appendStringInfo(&buf, "%s",
-						 quote_identifier(SPI_getvalue(spi_tup, spi_ttc,
-													   spi_fno)));
 		ReleaseSysCache(proctup);
 	}
 	else
-
+	{
 		/*
-		 * For the others say 'attr opclass [, ...]'
+		 * Otherwise say 'attr opclass [, ...]'
 		 */
 		appendStringInfo(&buf, "%s", keybuf.data);
+	}
+
+	appendStringInfo(&buf, ")");
 
 	/*
-	 * Finish
+	 * If it's a partial index, decompile and append the predicate
 	 */
-	appendStringInfo(&buf, ")");
+	if (VARSIZE(&idxrec->indpred) > VARHDRSZ)
+	{
+		Node	*node;
+		List	*context;
+		char	*exprstr;
+		char	*str;
+
+		/* Convert TEXT object to C string */
+		exprstr = DatumGetCString(DirectFunctionCall1(textout,
+													  PointerGetDatum(&idxrec->indpred)));
+		/* Convert expression to node tree */
+		node = (Node *) stringToNode(exprstr);
+		/*
+		 * If top level is a List, assume it is an implicit-AND structure,
+		 * and convert to explicit AND.  This is needed for partial index
+		 * predicates.
+		 */
+		if (node && IsA(node, List))
+			node = (Node *) make_ands_explicit((List *) node);
+		/* Deparse */
+		context = deparse_context_for(NameStr(indrelrec->relname),
+									  idxrec->indrelid);
+		str = deparse_expression(node, context, false);
+		appendStringInfo(&buf, " WHERE %s", str);
+	}
 
 	/*
-	 * Create the result in upper executor memory, and free objects
+	 * Create the result as a TEXT datum, and free working data
 	 */
 	len = buf.len + VARHDRSZ;
-	indexdef = SPI_palloc(len);
+	indexdef = (text *) palloc(len);
 	VARATT_SIZEP(indexdef) = len;
 	memcpy(VARDATA(indexdef), buf.data, buf.len);
 
 	pfree(buf.data);
 	pfree(keybuf.data);
+	pfree(amrec);
 	ReleaseSysCache(ht_idx);
 	ReleaseSysCache(ht_idxrel);
 	ReleaseSysCache(ht_indrel);
 
-	/*
-	 * Disconnect from SPI manager
-	 */
-	if (SPI_finish() != SPI_OK_FINISH)
-		elog(ERROR, "get_viewdef: SPI_finish() failed");
-
 	PG_RETURN_TEXT_P(indexdef);
 }
 
@@ -2546,6 +2500,32 @@ get_from_clause_item(Node *jtnode, Query *query, deparse_context *context)
 	dpns->namespace = sv_namespace;
 }
 
+/* ----------
+ * get_opclass_name			- fetch name of an index operator class
+ *
+ * The opclass name is appended (after a space) to buf.
+ * If "only_nondefault" is true, the opclass name is appended only if
+ * it isn't the default for its datatype.
+ * ----------
+ */
+static void
+get_opclass_name(Oid opclass, bool only_nondefault,
+				 StringInfo buf)
+{
+	HeapTuple	ht_opc;
+	Form_pg_opclass opcrec;
+
+	ht_opc = SearchSysCache(CLAOID,
+							ObjectIdGetDatum(opclass),
+							0, 0, 0);
+	if (!HeapTupleIsValid(ht_opc))
+		elog(ERROR, "cache lookup failed for opclass %u", opclass);
+	opcrec = (Form_pg_opclass) GETSTRUCT(ht_opc);
+	if (!only_nondefault || !opcrec->opcdefault)
+		appendStringInfo(buf, " %s",
+						 quote_identifier(NameStr(opcrec->opcname)));
+	ReleaseSysCache(ht_opc);
+}
 
 /* ----------
  * tleIsArrayAssign			- check for array assignment