diff --git a/src/backend/optimizer/path/equivclass.c b/src/backend/optimizer/path/equivclass.c
index 6f1abbe47d..12a1d390b7 100644
--- a/src/backend/optimizer/path/equivclass.c
+++ b/src/backend/optimizer/path/equivclass.c
@@ -1623,8 +1623,21 @@ generate_join_implied_equalities_normal(PlannerInfo *root,
 		EquivalenceMember *best_inner_em = NULL;
 		Oid			best_eq_op = InvalidOid;
 		int			best_score = -1;
+		int			max_score = 3;
 		RestrictInfo *rinfo;
 
+		/* The case of possible self-join */
+		if (bms_num_members(outer_relids) == 1 &&
+			bms_num_members(inner_relids) == 1)
+		{
+			int orel = bms_next_member(outer_relids, -1);
+			int irel = bms_next_member(inner_relids, -1);
+
+			if (root->simple_rte_array[irel]->relid ==
+				root->simple_rte_array[orel]->relid)
+				max_score = 4;
+		}
+
 		foreach(lc1, outer_members)
 		{
 			EquivalenceMember *outer_em = (EquivalenceMember *) lfirst(lc1);
@@ -1653,17 +1666,31 @@ generate_join_implied_equalities_normal(PlannerInfo *root,
 				if (op_hashjoinable(eq_op,
 									exprType((Node *) outer_em->em_expr)))
 					score++;
+				if (score == 3 && score < max_score)
+				{
+					/* Look for self-join clause */
+					Var *outer_var = (Var *) (IsA(outer_em->em_expr, Var) ?
+									outer_em->em_expr :
+									((RelabelType *) outer_em->em_expr)->arg);
+					Var *inner_var = (Var *) (IsA(inner_em->em_expr, Var) ?
+									inner_em->em_expr :
+									((RelabelType *) inner_em->em_expr)->arg);
+
+					if (outer_var->varattno == inner_var->varattno)
+						score++;
+				}
+
 				if (score > best_score)
 				{
 					best_outer_em = outer_em;
 					best_inner_em = inner_em;
 					best_eq_op = eq_op;
 					best_score = score;
-					if (best_score == 3)
+					if (best_score == max_score)
 						break;	/* no need to look further */
 				}
 			}
-			if (best_score == 3)
+			if (best_score == max_score)
 				break;			/* no need to look further */
 		}
 		if (best_score < 0)
