From 064c7e1bffbec468e35a90a078d24270fcd2216c Mon Sep 17 00:00:00 2001
From: Emre Hasegeli <emre@hasegeli.com>
Date: Wed, 6 May 2015 11:17:14 +0200
Subject: [PATCH 4/7] fix brin deform tuple

---
 contrib/pageinspect/brinfuncs.c       | 2 +-
 doc/src/sgml/brin.sgml                | 4 ++--
 src/backend/access/brin/brin_minmax.c | 4 ++--
 src/backend/access/brin/brin_tuple.c  | 6 +++---
 src/include/access/brin_internal.h    | 7 ++++---
 5 files changed, 12 insertions(+), 11 deletions(-)

diff --git a/contrib/pageinspect/brinfuncs.c b/contrib/pageinspect/brinfuncs.c
index 1b15a7b..bd3191d 100644
--- a/contrib/pageinspect/brinfuncs.c
+++ b/contrib/pageinspect/brinfuncs.c
@@ -174,21 +174,21 @@ brin_page_items(PG_FUNCTION_ARGS)
 			int		i;
 			brin_column_state *column;
 
 			opcinfo = state->bdesc->bd_info[attno - 1];
 			column = palloc(offsetof(brin_column_state, outputFn) +
 							sizeof(FmgrInfo) * opcinfo->oi_nstored);
 
 			column->nstored = opcinfo->oi_nstored;
 			for (i = 0; i < opcinfo->oi_nstored; i++)
 			{
-				getTypeOutputInfo(opcinfo->oi_typids[i], &output, &isVarlena);
+				getTypeOutputInfo(opcinfo->oi_typcache[i]->type_id, &output, &isVarlena);
 				fmgr_info(output, &column->outputFn[i]);
 			}
 
 			state->columns[attno - 1] = column;
 		}
 
 		index_close(indexRel, AccessShareLock);
 
 		fctx->user_fctx = state;
 		fctx->tuple_desc = BlessTupleDesc(tupdesc);
diff --git a/doc/src/sgml/brin.sgml b/doc/src/sgml/brin.sgml
index 1ac282c..92dac7c 100644
--- a/doc/src/sgml/brin.sgml
+++ b/doc/src/sgml/brin.sgml
@@ -421,22 +421,22 @@
       which has this definition:
 <programlisting>
 typedef struct BrinOpcInfo
 {
     /* Number of columns stored in an index column of this opclass */
     uint16      oi_nstored;
 
     /* Opaque pointer for the opclass' private use */
     void       *oi_opaque;
 
-    /* Type IDs of the stored columns */
-    Oid         oi_typids[FLEXIBLE_ARRAY_MEMBER];
+    /* Type cache entries of the stored columns */
+    TypeCacheEntry *oi_typcache[FLEXIBLE_ARRAY_MEMBER];
 } BrinOpcInfo;
 </programlisting>
       <structname>BrinOpcInfo</>.<structfield>oi_opaque</> can be used by the
       operator class routines to pass information between support procedures
       during an index scan.
      </para>
     </listitem>
    </varlistentry>
 
    <varlistentry>
diff --git a/src/backend/access/brin/brin_minmax.c b/src/backend/access/brin/brin_minmax.c
index 299d6f7..ce8652d 100644
--- a/src/backend/access/brin/brin_minmax.c
+++ b/src/backend/access/brin/brin_minmax.c
@@ -55,22 +55,22 @@ brin_minmax_opcinfo(PG_FUNCTION_ARGS)
 	/*
 	 * opaque->operators is initialized lazily, as indicated by 'inited' which
 	 * is initialized to all false by palloc0.
 	 */
 
 	result = palloc0(MAXALIGN(SizeofBrinOpcInfo(2)) +
 					 sizeof(MinmaxOpaque));
 	result->oi_nstored = 2;
 	result->oi_opaque = (MinmaxOpaque *)
 		MAXALIGN((char *) result + SizeofBrinOpcInfo(2));
-	result->oi_typids[0] = typoid;
-	result->oi_typids[1] = typoid;
+	result->oi_typcache[0] = result->oi_typcache[1] =
+		lookup_type_cache(typoid, 0);
 
 	PG_RETURN_POINTER(result);
 }
 
 /*
  * Examine the given index tuple (which contains partial status of a certain
  * page range) by comparing it to the given value that comes from another heap
  * tuple.  If the new value is outside the min/max range specified by the
  * existing tuple values, update the index tuple and return true.  Otherwise,
  * return false and do not modify in this case.
diff --git a/src/backend/access/brin/brin_tuple.c b/src/backend/access/brin/brin_tuple.c
index 08fa998..22ce74a 100644
--- a/src/backend/access/brin/brin_tuple.c
+++ b/src/backend/access/brin/brin_tuple.c
@@ -61,21 +61,21 @@ brtuple_disk_tupdesc(BrinDesc *brdesc)
 
 		/* make sure it's in the bdesc's context */
 		oldcxt = MemoryContextSwitchTo(brdesc->bd_context);
 
 		tupdesc = CreateTemplateTupleDesc(brdesc->bd_totalstored, false);
 
 		for (i = 0; i < brdesc->bd_tupdesc->natts; i++)
 		{
 			for (j = 0; j < brdesc->bd_info[i]->oi_nstored; j++)
 				TupleDescInitEntry(tupdesc, attno++, NULL,
-								   brdesc->bd_info[i]->oi_typids[j],
+								   brdesc->bd_info[i]->oi_typcache[j]->type_id,
 								   -1, 0);
 		}
 
 		MemoryContextSwitchTo(oldcxt);
 
 		brdesc->bd_disktdesc = tupdesc;
 	}
 
 	return brdesc->bd_disktdesc;
 }
@@ -437,22 +437,22 @@ brin_deform_tuple(BrinDesc *brdesc, BrinTuple *tuple)
 			continue;
 		}
 
 		/*
 		 * We would like to skip datumCopy'ing the values datum in some cases,
 		 * caller permitting ...
 		 */
 		for (i = 0; i < brdesc->bd_info[keyno]->oi_nstored; i++)
 			dtup->bt_columns[keyno].bv_values[i] =
 				datumCopy(values[valueno++],
-						  brdesc->bd_tupdesc->attrs[keyno]->attbyval,
-						  brdesc->bd_tupdesc->attrs[keyno]->attlen);
+						  brdesc->bd_info[keyno]->oi_typcache[i]->typbyval,
+						  brdesc->bd_info[keyno]->oi_typcache[i]->typlen);
 
 		dtup->bt_columns[keyno].bv_hasnulls = hasnulls[keyno];
 		dtup->bt_columns[keyno].bv_allnulls = false;
 	}
 
 	MemoryContextSwitchTo(oldcxt);
 
 	pfree(values);
 	pfree(allnulls);
 	pfree(hasnulls);
diff --git a/src/include/access/brin_internal.h b/src/include/access/brin_internal.h
index 84eed61..1486d04 100644
--- a/src/include/access/brin_internal.h
+++ b/src/include/access/brin_internal.h
@@ -9,43 +9,44 @@
  *		src/include/access/brin_internal.h
  */
 #ifndef BRIN_INTERNAL_H
 #define BRIN_INTERNAL_H
 
 #include "fmgr.h"
 #include "storage/buf.h"
 #include "storage/bufpage.h"
 #include "storage/off.h"
 #include "utils/relcache.h"
+#include "utils/typcache.h"
 
 
 /*
  * A BrinDesc is a struct designed to enable decoding a BRIN tuple from the
  * on-disk format to an in-memory tuple and vice-versa.
  */
 
 /* struct returned by "OpcInfo" amproc */
 typedef struct BrinOpcInfo
 {
 	/* Number of columns stored in an index column of this opclass */
 	uint16		oi_nstored;
 
 	/* Opaque pointer for the opclass' private use */
 	void	   *oi_opaque;
 
-	/* Type IDs of the stored columns */
-	Oid			oi_typids[FLEXIBLE_ARRAY_MEMBER];
+	/* Type cache entries of the stored columns */
+	TypeCacheEntry *oi_typcache[FLEXIBLE_ARRAY_MEMBER];
 } BrinOpcInfo;
 
 /* the size of a BrinOpcInfo for the given number of columns */
 #define SizeofBrinOpcInfo(ncols) \
-	(offsetof(BrinOpcInfo, oi_typids) + sizeof(Oid) * ncols)
+	(offsetof(BrinOpcInfo, oi_typcache) + sizeof(TypeCacheEntry *) * ncols)
 
 typedef struct BrinDesc
 {
 	/* Containing memory context */
 	MemoryContext bd_context;
 
 	/* the index relation itself */
 	Relation	bd_index;
 
 	/* tuple descriptor of the index relation */
-- 
2.3.2

