diff --git a/src/backend/optimizer/path/costsize.c b/src/backend/optimizer/path/costsize.c
index b35acb7..1c3d872 100644
--- a/src/backend/optimizer/path/costsize.c
+++ b/src/backend/optimizer/path/costsize.c
@@ -112,6 +112,7 @@ double		parallel_setup_cost = DEFAULT_PARALLEL_SETUP_COST;
 int			effective_cache_size = DEFAULT_EFFECTIVE_CACHE_SIZE;
 
 Cost		disable_cost = 1.0e10;
+int		cost_clause_count_limit = 100;
 
 int			max_parallel_workers_per_gather = 2;
 
@@ -4012,21 +4013,75 @@ void
 set_baserel_size_estimates(PlannerInfo *root, RelOptInfo *rel)
 {
 	double		nrows;
+	int		clause_count;
+	Selectivity total_sel, prev_total_sel;
+	List *clause_list;
+	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);
-
-	rel->rows = clamp_row_est(nrows);
+	/*
+	 * When 'clause_list' consists of multiple quals, each qual will be
+	 * evaluated different times because earlier quals filter some input
+	 * tuples. At this point, the order of quals in 'clause_list' may be
+	 * different from the order of quals at runtime, we first sort
+	 * 'clause_list' and then loop over 'clause_list' to estimate cost of each
+	 * qual evaluations.
+	 */
 
 	cost_qual_eval(&rel->baserestrictcost, rel->baserestrictinfo, root);
+	clause_list = order_qual_clauses(root, rel->baserestrictinfo);
 
+	cost.startup = 0;
+	cost.per_tuple = 0;
+	total_sel = prev_total_sel = 1.0;
+	clause_count = 0;
+	foreach(l, clause_list)
+	{
+		Node	   *qual = (Node *) lfirst(l);
+		List *clause_list_for_sel = NIL;
+		ListCell *temp_l;
+		cost_qual_eval_context context;
+		context.root = root;
+		context.total.startup = 0;
+		context.total.per_tuple = 0;
+
+		if (clause_count < cost_clause_count_limit) {
+			/*
+			 * Make a temporary clause list of quals we have checked so far for
+			 * selectivity calculation
+			 */
+			for (temp_l = list_head(clause_list); ; temp_l = lnext(temp_l))
+			{
+				clause_list_for_sel = lappend(clause_list_for_sel, lfirst(temp_l));
+				if(temp_l == l)
+				{
+					break;
+				}
+			}
+
+			total_sel = clauselist_selectivity(root,
+											   clause_list_for_sel,
+											   0,
+											   JOIN_INNER,
+											   NULL);
+		}
+
+		/* We don't charge any cost for the implicit ANDing at top level ... */
+		cost_qual_eval_walker(qual, &context);
+		cost.startup += context.total.startup * prev_total_sel;
+		cost.per_tuple += context.total.per_tuple * prev_total_sel;
+
+		prev_total_sel = total_sel;
+		clause_count++;
+	}
+
+	nrows = rel->tuples * total_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 78a1503..70a01cc 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
diff --git a/src/test/regress/expected/updatable_views.out b/src/test/regress/expected/updatable_views.out
index 2090a41..d9e7c2a 100644
--- a/src/test/regress/expected/updatable_views.out
+++ b/src/test/regress/expected/updatable_views.out
@@ -2097,17 +2097,16 @@ SELECT * FROM v1 WHERE a=8;
 
 EXPLAIN (VERBOSE, COSTS OFF)
 UPDATE v1 SET a=100 WHERE snoop(a) AND leakproof(a) AND a < 7 AND a != 6;
-                                                        QUERY PLAN                                                         
----------------------------------------------------------------------------------------------------------------------------
+                                                                         QUERY PLAN                                                                          
+-------------------------------------------------------------------------------------------------------------------------------------------------------------
  Update on public.t1
    Update on public.t1
    Update on public.t11
    Update on public.t12
    Update on public.t111
-   ->  Index Scan using t1_a_idx on public.t1
+   ->  Seq Scan on public.t1
          Output: 100, t1.b, t1.c, t1.ctid
-         Index Cond: ((t1.a > 5) AND (t1.a < 7))
-         Filter: ((t1.a <> 6) AND (alternatives: SubPlan 1 or hashed SubPlan 2) AND snoop(t1.a) AND leakproof(t1.a))
+         Filter: ((t1.a > 5) AND (t1.a < 7) AND (t1.a <> 6) AND (alternatives: SubPlan 1 or hashed SubPlan 2) AND snoop(t1.a) AND leakproof(t1.a))
          SubPlan 1
            ->  Append
                  ->  Seq Scan on public.t12 t12_1
@@ -2120,19 +2119,16 @@ UPDATE v1 SET a=100 WHERE snoop(a) AND leakproof(a) AND a < 7 AND a != 6;
                        Output: t12_2.a
                  ->  Seq Scan on public.t111 t111_2
                        Output: t111_2.a
-   ->  Index Scan using t11_a_idx on public.t11
+   ->  Seq Scan on public.t11
          Output: 100, t11.b, t11.c, t11.d, t11.ctid
-         Index Cond: ((t11.a > 5) AND (t11.a < 7))
-         Filter: ((t11.a <> 6) AND (alternatives: SubPlan 1 or hashed SubPlan 2) AND snoop(t11.a) AND leakproof(t11.a))
-   ->  Index Scan using t12_a_idx on public.t12
+         Filter: ((t11.a > 5) AND (t11.a < 7) AND (t11.a <> 6) AND (alternatives: SubPlan 1 or hashed SubPlan 2) AND snoop(t11.a) AND leakproof(t11.a))
+   ->  Seq Scan on public.t12
          Output: 100, t12.b, t12.c, t12.e, t12.ctid
-         Index Cond: ((t12.a > 5) AND (t12.a < 7))
-         Filter: ((t12.a <> 6) AND (alternatives: SubPlan 1 or hashed SubPlan 2) AND snoop(t12.a) AND leakproof(t12.a))
-   ->  Index Scan using t111_a_idx on public.t111
+         Filter: ((t12.a > 5) AND (t12.a < 7) AND (t12.a <> 6) AND (alternatives: SubPlan 1 or hashed SubPlan 2) AND snoop(t12.a) AND leakproof(t12.a))
+   ->  Seq Scan on public.t111
          Output: 100, t111.b, t111.c, t111.d, t111.e, t111.ctid
-         Index Cond: ((t111.a > 5) AND (t111.a < 7))
-         Filter: ((t111.a <> 6) AND (alternatives: SubPlan 1 or hashed SubPlan 2) AND snoop(t111.a) AND leakproof(t111.a))
-(33 rows)
+         Filter: ((t111.a > 5) AND (t111.a < 7) AND (t111.a <> 6) AND (alternatives: SubPlan 1 or hashed SubPlan 2) AND snoop(t111.a) AND leakproof(t111.a))
+(29 rows)
 
 UPDATE v1 SET a=100 WHERE snoop(a) AND leakproof(a) AND a < 7 AND a != 6;
 SELECT * FROM v1 WHERE a=100; -- Nothing should have been changed to 100
@@ -2147,17 +2143,16 @@ SELECT * FROM t1 WHERE a=100; -- Nothing should have been changed to 100
 
 EXPLAIN (VERBOSE, COSTS OFF)
 UPDATE v1 SET a=a+1 WHERE snoop(a) AND leakproof(a) AND a = 8;
-                                               QUERY PLAN                                                
----------------------------------------------------------------------------------------------------------
+                                                                QUERY PLAN                                                                 
+-------------------------------------------------------------------------------------------------------------------------------------------
  Update on public.t1
    Update on public.t1
    Update on public.t11
    Update on public.t12
    Update on public.t111
-   ->  Index Scan using t1_a_idx on public.t1
+   ->  Seq Scan on public.t1
          Output: (t1.a + 1), t1.b, t1.c, t1.ctid
-         Index Cond: ((t1.a > 5) AND (t1.a = 8))
-         Filter: ((alternatives: SubPlan 1 or hashed SubPlan 2) AND snoop(t1.a) AND leakproof(t1.a))
+         Filter: ((t1.a > 5) AND (t1.a = 8) AND (alternatives: SubPlan 1 or hashed SubPlan 2) AND snoop(t1.a) AND leakproof(t1.a))
          SubPlan 1
            ->  Append
                  ->  Seq Scan on public.t12 t12_1
@@ -2170,19 +2165,16 @@ UPDATE v1 SET a=a+1 WHERE snoop(a) AND leakproof(a) AND a = 8;
                        Output: t12_2.a
                  ->  Seq Scan on public.t111 t111_2
                        Output: t111_2.a
-   ->  Index Scan using t11_a_idx on public.t11
+   ->  Seq Scan on public.t11
          Output: (t11.a + 1), t11.b, t11.c, t11.d, t11.ctid
-         Index Cond: ((t11.a > 5) AND (t11.a = 8))
-         Filter: ((alternatives: SubPlan 1 or hashed SubPlan 2) AND snoop(t11.a) AND leakproof(t11.a))
-   ->  Index Scan using t12_a_idx on public.t12
+         Filter: ((t11.a > 5) AND (t11.a = 8) AND (alternatives: SubPlan 1 or hashed SubPlan 2) AND snoop(t11.a) AND leakproof(t11.a))
+   ->  Seq Scan on public.t12
          Output: (t12.a + 1), t12.b, t12.c, t12.e, t12.ctid
-         Index Cond: ((t12.a > 5) AND (t12.a = 8))
-         Filter: ((alternatives: SubPlan 1 or hashed SubPlan 2) AND snoop(t12.a) AND leakproof(t12.a))
-   ->  Index Scan using t111_a_idx on public.t111
+         Filter: ((t12.a > 5) AND (t12.a = 8) AND (alternatives: SubPlan 1 or hashed SubPlan 2) AND snoop(t12.a) AND leakproof(t12.a))
+   ->  Seq Scan on public.t111
          Output: (t111.a + 1), t111.b, t111.c, t111.d, t111.e, t111.ctid
-         Index Cond: ((t111.a > 5) AND (t111.a = 8))
-         Filter: ((alternatives: SubPlan 1 or hashed SubPlan 2) AND snoop(t111.a) AND leakproof(t111.a))
-(33 rows)
+         Filter: ((t111.a > 5) AND (t111.a = 8) AND (alternatives: SubPlan 1 or hashed SubPlan 2) AND snoop(t111.a) AND leakproof(t111.a))
+(29 rows)
 
 UPDATE v1 SET a=a+1 WHERE snoop(a) AND leakproof(a) AND a = 8;
 NOTICE:  snooped value: 8
