diff --git a/src/backend/catalog/partition.c b/src/backend/catalog/partition.c
index 2df2530d5e3..e7809c8937a 100644
--- a/src/backend/catalog/partition.c
+++ b/src/backend/catalog/partition.c
@@ -1813,9 +1813,10 @@ perform_pruning_combine_step(PartitionPruneContext *context,
 			{
 				Bitmapset  *stepresult;
 				Datum	   *ne_datums;
-				int			n_ne_datums = list_length(cstep->argvalues),
+				FmgrInfo  **partsupfuncs;
+				ListCell   *lc2;
+				int			n_ne_datums = list_length(cstep->argexprs),
 							i;
-				FmgrInfo  **partsupfunc;
 
 				/*
 				 * Apply not-equal clauses.  This only applies in the list
@@ -1823,18 +1824,20 @@ perform_pruning_combine_step(PartitionPruneContext *context,
 				 * we have knowledge of the entire set of values that can be
 				 * stored in a given partition.
 				 */
-				ne_datums = (Datum *) palloc0(n_ne_datums * sizeof(Datum));
+				ne_datums = (Datum *) palloc(n_ne_datums * sizeof(Datum));
 
 				/*
 				 * Some datums may require different comparison function than
 				 * the default partitioning-specific one.
 				 */
-				partsupfunc = (FmgrInfo **)
-					palloc0(n_ne_datums * sizeof(FmgrInfo *));
+				partsupfuncs = (FmgrInfo **)
+					palloc(n_ne_datums * sizeof(FmgrInfo *));
+
 				i = 0;
-				foreach(lc, cstep->argvalues)
+				forboth(lc, cstep->argexprs, lc2, cstep->argcmpfuncoids)
 				{
-					Expr	   *expr = lfirst(lc);
+					Expr	   *expr = (Expr *) lfirst(lc);
+					Oid			cmpfuncoid = lfirst_oid(lc2);
 					Datum		datum;
 
 					/*
@@ -1843,38 +1846,28 @@ perform_pruning_combine_step(PartitionPruneContext *context,
 					 */
 					if (partkey_datum_from_expr(context, expr, &datum))
 					{
-						Oid			exprTyp = exprType((Node *) expr);
-
 						/*
-						 * Check if we need to use a different comparison
-						 * function for this value.
+						 * If this datum is not the same type as the partition
+						 * key then we'll need to use the comparison function
+						 * for that type.  We'll need to lookup the FmgrInfo.
 						 */
-						if (context->partopcintype[0] != exprTyp)
+						if (cmpfuncoid != context->partsupfunc[0].fn_oid)
 						{
-							Oid			cmpfn;
-
-							cmpfn = get_opfamily_proc(context->partopfamily[0],
-													  context->partopcintype[0],
-													  exprTyp, BTORDER_PROC);
-							if (OidIsValid(cmpfn))
-							{
-								partsupfunc[i] = palloc0(sizeof(FmgrInfo));
-								fmgr_info(cmpfn, partsupfunc[i]);
-							}
-							else	/* Can't really use datum for pruning. */
-								continue;
+							partsupfuncs[i] = (FmgrInfo *)
+													palloc(sizeof(FmgrInfo));
+							fmgr_info(cmpfuncoid, partsupfuncs[i]);
 						}
 						else
-							partsupfunc[i] = &context->partsupfunc[0];
-
-						ne_datums[i++] = datum;
+							partsupfuncs[i] = &context->partsupfunc[0];
 					}
+
+					ne_datums[i++] = datum;
 				}
 
 				stepresult = get_partitions_excluded_by_ne_datums(context,
 																  ne_datums,
 																  i,
-																  partsupfunc);
+																  partsupfuncs);
 
 				/* All partitions apart from the stepresult partitions match */
 				result = bms_add_range(NULL, 0, context->nparts - 1);
diff --git a/src/backend/nodes/copyfuncs.c b/src/backend/nodes/copyfuncs.c
index 0da34271a6a..adc24b44394 100644
--- a/src/backend/nodes/copyfuncs.c
+++ b/src/backend/nodes/copyfuncs.c
@@ -2158,7 +2158,8 @@ _copyPartitionPruneStepCombine(const PartitionPruneStepCombine *from)
 
 	COPY_SCALAR_FIELD(combineOp);
 	COPY_NODE_FIELD(argsteps);
-	COPY_NODE_FIELD(argvalues);
+	COPY_NODE_FIELD(argexprs);
+	COPY_NODE_FIELD(argcmpfuncoids);
 
 	return newnode;
 }
diff --git a/src/backend/nodes/nodeFuncs.c b/src/backend/nodes/nodeFuncs.c
index 0a3e32ecd12..bec265c8896 100644
--- a/src/backend/nodes/nodeFuncs.c
+++ b/src/backend/nodes/nodeFuncs.c
@@ -2160,7 +2160,9 @@ expression_tree_walker(Node *node,
 
 				if (walker((Node *) cstep->argsteps, context))
 					return true;
-				if (walker((Node *) cstep->argvalues, context))
+				if (walker((Node *) cstep->argexprs, context))
+					return true;
+				if (walker((Node *) cstep->argcmpfuncoids, context))
 					return true;
 			}
 			break;
@@ -2968,7 +2970,8 @@ expression_tree_mutator(Node *node,
 
 				FLATCOPY(newnode, cstep, PartitionPruneStepCombine);
 				MUTATE(newnode->argsteps, cstep->argsteps, List *);
-				MUTATE(newnode->argvalues, cstep->argvalues, List *);
+				MUTATE(newnode->argexprs, cstep->argexprs, List *);
+				MUTATE(newnode->argcmpfuncoids, cstep->argcmpfuncoids, List *);
 
 				return (Node *) newnode;
 			}
diff --git a/src/backend/optimizer/util/partprune.c b/src/backend/optimizer/util/partprune.c
index 6e7bec429be..39b639c7b94 100644
--- a/src/backend/optimizer/util/partprune.c
+++ b/src/backend/optimizer/util/partprune.c
@@ -17,6 +17,7 @@
 #include "postgres.h"
 
 #include "access/hash.h"
+#include "access/nbtree.h"
 #include "catalog/pg_operator.h"
 #include "catalog/pg_opfamily.h"
 #include "catalog/pg_type.h"
@@ -41,6 +42,8 @@ typedef struct PartClauseInfo
 	Oid			opno;			/* operator used to compare partkey to 'value' */
 	Expr	   *value;			/* The value the partition key is being
 								 * compared to */
+	Oid			cmpfuncoid;		/* Oid of function to compare this to the
+								 * partition key */
 
 	/* cached info. */
 	int			op_strategy;
@@ -321,7 +324,8 @@ generate_partition_pruning_steps_internal(RelOptInfo *rel, List *clauses,
 				combineStep = makeNode(PartitionPruneStepCombine);
 				combineStep->combineOp = COMBINE_OR;
 				combineStep->argsteps = all_arg_steps;
-				combineStep->argvalues = NIL;
+				combineStep->argexprs = NIL;
+				combineStep->argcmpfuncoids = NIL;
 				result = lappend(result, combineStep);
 				continue;
 			}
@@ -340,7 +344,8 @@ generate_partition_pruning_steps_internal(RelOptInfo *rel, List *clauses,
 				combineStep = makeNode(PartitionPruneStepCombine);
 				combineStep->combineOp = COMBINE_AND;
 				combineStep->argsteps = argsteps;
-				combineStep->argvalues = NIL;
+				combineStep->argexprs = NIL;
+				combineStep->argcmpfuncoids = NIL;
 				result = lappend(result, combineStep);
 				continue;
 			}
@@ -449,7 +454,8 @@ generate_partition_pruning_steps_internal(RelOptInfo *rel, List *clauses,
 	/* Combine values from all <> operator clauses into one prune step. */
 	if (ne_clauses != NIL)
 	{
-		List	   *argvalues = NIL;
+		List	   *argexprs = NIL;
+		List	   *argcmpfuncs = NIL;
 		PartitionPruneStepCombine *combineStep;
 
 		Assert(part_scheme->strategy == PARTITION_STRATEGY_LIST);
@@ -457,13 +463,15 @@ generate_partition_pruning_steps_internal(RelOptInfo *rel, List *clauses,
 		{
 			PartClauseInfo *pc = lfirst(lc);
 
-			argvalues = lappend(argvalues, pc->value);
+			argexprs = lappend(argexprs, pc->value);
+			argcmpfuncs = lappend_oid(argcmpfuncs, pc->cmpfuncoid);
 		}
 
 		combineStep = makeNode(PartitionPruneStepCombine);
 		combineStep->combineOp = COMBINE_NOT;
 		combineStep->argsteps = NIL;
-		combineStep->argvalues = argvalues;
+		combineStep->argexprs = argexprs;
+		combineStep->argcmpfuncoids = argcmpfuncs;
 		result = lappend(result, combineStep);
 	}
 
@@ -802,16 +810,19 @@ match_clause_to_partition_key(RelOptInfo *rel,
 		/* Do pruning with the Boolean equality operator. */
 		(*pc)->opno = BooleanEqualOperator;
 		(*pc)->value = value;
+		(*pc)->cmpfuncoid = rel->part_scheme->partsupfunc[partkeyidx].fn_oid;
 
 		return PARTCLAUSE_MATCH_CLAUSE;
 	}
-	else if (IsA(clause, OpExpr) &&list_length(((OpExpr *) clause)->args) == 2)
+	else if (IsA(clause, OpExpr) &&
+			 list_length(((OpExpr *) clause)->args) == 2)
 	{
 		OpExpr	   *opclause = (OpExpr *) clause;
 		Expr	   *leftop,
 				   *rightop;
 		Oid			commutator = InvalidOid,
 					negator = InvalidOid;
+		Oid			cmpfuncoid;
 
 		leftop = (Expr *) get_leftop(clause);
 		if (IsA(leftop, RelabelType))
@@ -898,6 +909,20 @@ match_clause_to_partition_key(RelOptInfo *rel,
 				return PARTCLAUSE_UNSUPPORTED;
 		}
 
+		if (part_scheme->strategy == PARTITION_STRATEGY_HASH)
+			cmpfuncoid = get_opfamily_proc(part_scheme->partopfamily[partkeyidx],
+										   part_scheme->partopcintype[partkeyidx],
+										   exprType((Node *) value),
+										   HASHEXTENDED_PROC);
+		else
+			cmpfuncoid = get_opfamily_proc(part_scheme->partopfamily[partkeyidx],
+										   part_scheme->partopcintype[partkeyidx],
+										   exprType((Node *) value),
+										   BTORDER_PROC);
+
+		if (!OidIsValid(cmpfuncoid))
+			return PARTCLAUSE_UNSUPPORTED;
+
 		*pc = palloc0(sizeof(PartClauseInfo));
 		(*pc)->keyno = partkeyidx;
 
@@ -914,6 +939,7 @@ match_clause_to_partition_key(RelOptInfo *rel,
 			(*pc)->opno = opclause->opno;
 
 		(*pc)->value = value;
+		(*pc)->cmpfuncoid = cmpfuncoid;
 
 		return PARTCLAUSE_MATCH_CLAUSE;
 	}
diff --git a/src/include/nodes/primnodes.h b/src/include/nodes/primnodes.h
index 5c157fb1f1e..507cc87af1c 100644
--- a/src/include/nodes/primnodes.h
+++ b/src/include/nodes/primnodes.h
@@ -1538,7 +1538,9 @@ typedef struct PartitionPruneStepCombine
 
 	PartitionPruneCombineOp combineOp;
 	List	   *argsteps;
-	List	   *argvalues;
+	List	   *argexprs; /* Expressions to compare to the partition key */
+	List	   *argcmpfuncoids; /* Comparison function Oid used to compare the
+								 * argexprs to the partition key */
 } PartitionPruneStepCombine;
 
 #endif							/* PRIMNODES_H */
