diff --git a/src/backend/optimizer/path/costsize.c b/src/backend/optimizer/path/costsize.c
index 051a854..38c27b7 100644
--- a/src/backend/optimizer/path/costsize.c
+++ b/src/backend/optimizer/path/costsize.c
@@ -4037,21 +4037,57 @@ void
 set_baserel_size_estimates(PlannerInfo *root, RelOptInfo *rel)
 {
 	double		nrows;
+	Selectivity prev_sel, sel;
+	List *clause_list;
+	List *ordered_clauses;
+	ListCell *l;
+	QualCost cost;
 
 	/* Should only be applied to base relations */
 	Assert(rel->relid > 0);
 
-	nrows = rel->tuples *
-		clauselist_selectivity(root,
-							   rel->baserestrictinfo,
-							   0,
-							   JOIN_INNER,
-							   NULL);
+	ordered_clauses = order_qual_clauses(root, rel->baserestrictinfo);
+	clause_list = ordered_clauses;
 
-	rel->rows = clamp_row_est(nrows);
+	cost.startup = 0;
+	cost.per_tuple = 0;
+	prev_sel = 1.0;
+	foreach(l, clause_list)
+	{
+		Node *qual = (Node *) lfirst(l);
+		List *clause_list_for_sel = NULL;
+		ListCell *m;
+		cost_qual_eval_context context;
+		context.root = root;
+		context.total.startup = 0;
+		context.total.per_tuple = 0;
+
+		/* Make a temporary clause list for selectivity calcuation */
+		foreach(m, ordered_clauses)
+		{
+			clause_list_for_sel = lappend(clause_list_for_sel, lfirst(m));
 
-	cost_qual_eval(&rel->baserestrictcost, rel->baserestrictinfo, root);
+			if(m == l)
+				break;
+		}
+
+		sel = clauselist_selectivity(root,
+									 clause_list_for_sel,
+									 0,
+									 JOIN_INNER,
+									 NULL);
+
+		cost_qual_eval_walker(qual, &context);
+		cost.startup += context.total.startup * prev_sel;
+		cost.per_tuple += context.total.per_tuple * prev_sel;
 
+		prev_sel = sel;
+	}
+
+	nrows = rel->tuples * prev_sel;
+
+	rel->rows = clamp_row_est(nrows);
+	rel->baserestrictcost = cost;
 	set_rel_width(root, rel);
 }
 
diff --git a/src/backend/optimizer/plan/createplan.c b/src/backend/optimizer/plan/createplan.c
index 2821662..35d9755 100644
--- a/src/backend/optimizer/plan/createplan.c
+++ b/src/backend/optimizer/plan/createplan.c
@@ -159,7 +159,6 @@ static List *fix_indexqual_references(PlannerInfo *root, IndexPath *index_path);
 static List *fix_indexorderby_references(PlannerInfo *root, IndexPath *index_path);
 static Node *fix_indexqual_operand(Node *node, IndexOptInfo *index, int indexcol);
 static List *get_switched_clauses(List *clauses, Relids outerrelids);
-static List *order_qual_clauses(PlannerInfo *root, List *clauses);
 static void copy_generic_path_info(Plan *dest, Path *src);
 static void copy_plan_costsize(Plan *dest, Plan *src);
 static void label_sort_with_costsize(PlannerInfo *root, Sort *plan,
@@ -4762,7 +4761,7 @@ get_switched_clauses(List *clauses, Relids outerrelids)
  * instead of bare clauses.  This is another reason why trying to consider
  * selectivity in the ordering would likely do the wrong thing.
  */
-static List *
+List *
 order_qual_clauses(PlannerInfo *root, List *clauses)
 {
 	typedef struct
diff --git a/src/include/optimizer/planmain.h b/src/include/optimizer/planmain.h
index f1d16cf..016fb12 100644
--- a/src/include/optimizer/planmain.h
+++ b/src/include/optimizer/planmain.h
@@ -64,6 +64,8 @@ extern Agg *make_agg(List *tlist, List *qual,
 		 List *groupingSets, List *chain,
 		 double dNumGroups, Plan *lefttree);
 extern Limit *make_limit(Plan *lefttree, Node *limitOffset, Node *limitCount);
+extern List *order_qual_clauses(PlannerInfo *root, List *clauses);
+
 
 /*
  * prototypes for plan/initsplan.c
