diff --git a/src/backend/commands/tablecmds.c b/src/backend/commands/tablecmds.c
index ba59fc708a..3a99bbd3e2 100644
--- a/src/backend/commands/tablecmds.c
+++ b/src/backend/commands/tablecmds.c
@@ -15666,6 +15666,13 @@ ATExecAttachPartition(List **wqueue, Relation rel, PartitionCmd *cmd)
 		defaultrel = table_open(defaultPartOid, NoLock);
 		defPartConstraint =
 			get_proposed_default_constraint(partBoundConstraint);
+		/*
+		 * Map the Vars in the constraint expression from rel's attnos to
+		 * defaultrel's.
+		 */
+		defPartConstraint =
+			map_partition_varattnos(defPartConstraint,
+									1, defaultrel, rel, NULL);
 		QueuePartitionConstraintValidation(wqueue, defaultrel,
 										   defPartConstraint, true);
 
diff --git a/src/backend/partitioning/partbounds.c b/src/backend/partitioning/partbounds.c
index 99d26de7e6..f3c9236ad5 100644
--- a/src/backend/partitioning/partbounds.c
+++ b/src/backend/partitioning/partbounds.c
@@ -1237,6 +1237,13 @@ check_default_partition_contents(Relation parent, Relation default_rel,
 		: get_qual_for_range(parent, new_spec, false);
 	def_part_constraints =
 		get_proposed_default_constraint(new_part_constraints);
+	/*
+	 * Map the Vars in the constraint expression from parent's attnos to
+	 * default_rel's.
+	 */
+	def_part_constraints =
+			map_partition_varattnos(def_part_constraints, 1, default_rel,
+									parent, NULL);
 
 	/*
 	 * If the existing constraints on the default partition imply that it will
@@ -1265,7 +1272,6 @@ check_default_partition_contents(Relation parent, Relation default_rel,
 	{
 		Oid			part_relid = lfirst_oid(lc);
 		Relation	part_rel;
-		Expr	   *constr;
 		Expr	   *partition_constraint;
 		EState	   *estate;
 		ExprState  *partqualstate = NULL;
@@ -1281,6 +1287,15 @@ check_default_partition_contents(Relation parent, Relation default_rel,
 			part_rel = table_open(part_relid, NoLock);
 
 			/*
+			 * Map the Vars in the constraint expression from default_rel's
+			 * the sub-partition's.
+			 */
+			partition_constraint = make_ands_explicit(def_part_constraints);
+			partition_constraint = (Expr *)
+				map_partition_varattnos((List *) partition_constraint, 1,
+										part_rel, default_rel, NULL);
+
+			/*
 			 * If the partition constraints on default partition child imply
 			 * that it will not contain any row that would belong to the new
 			 * partition, we can avoid scanning the child table.
@@ -1297,7 +1312,10 @@ check_default_partition_contents(Relation parent, Relation default_rel,
 			}
 		}
 		else
+		{
 			part_rel = default_rel;
+			partition_constraint = make_ands_explicit(def_part_constraints);
+		}
 
 		/*
 		 * Only RELKIND_RELATION relations (i.e. leaf partitions) need to be
@@ -1318,10 +1336,6 @@ check_default_partition_contents(Relation parent, Relation default_rel,
 			continue;
 		}
 
-		constr = linitial(def_part_constraints);
-		partition_constraint = (Expr *)
-			map_partition_varattnos((List *) constr,
-									1, part_rel, parent, NULL);
 		estate = CreateExecutorState();
 
 		/* Build expression execution states for partition check quals */
diff --git a/src/test/regress/expected/alter_table.out b/src/test/regress/expected/alter_table.out
index a639601f66..e687150511 100644
--- a/src/test/regress/expected/alter_table.out
+++ b/src/test/regress/expected/alter_table.out
@@ -4008,7 +4008,8 @@ DROP USER regress_alter_table_user1;
 -- default partition
 create table defpart_attach_test (a int) partition by list (a);
 create table defpart_attach_test1 partition of defpart_attach_test for values in (1);
-create table defpart_attach_test_d (like defpart_attach_test);
+create table defpart_attach_test_d (b int, a int);
+alter table defpart_attach_test_d drop b;
 insert into defpart_attach_test_d values (1), (2);
 -- error because its constraint as the default partition would be violated
 -- by the row containing 1
@@ -4019,6 +4020,12 @@ alter table defpart_attach_test_d add check (a > 1);
 -- should be attached successfully and without needing to be scanned
 alter table defpart_attach_test attach partition defpart_attach_test_d default;
 INFO:  partition constraint for table "defpart_attach_test_d" is implied by existing constraints
+-- check that attaching a partition correctly reports any rows in the default
+-- partition that should not be there for the new partition to be attached
+-- successfully
+create table defpart_attach_test_2 (like defpart_attach_test_d);
+alter table defpart_attach_test attach partition defpart_attach_test_2 for values in (2);
+ERROR:  updated partition constraint for default partition would be violated by some row
 drop table defpart_attach_test;
 -- check combinations of temporary and permanent relations when attaching
 -- partitions.
diff --git a/src/test/regress/expected/create_table.out b/src/test/regress/expected/create_table.out
index 204441e759..262abf2bfb 100644
--- a/src/test/regress/expected/create_table.out
+++ b/src/test/regress/expected/create_table.out
@@ -1119,3 +1119,17 @@ select tableoid::regclass from volatile_partbound_test;
 (1 row)
 
 drop table volatile_partbound_test;
+-- test the case where a check constraint on default partition allows
+-- to avoid scanning it when adding a new partition
+create table defcheck (a int, b int) partition by list (b);
+create table defcheck_def (a int, c int, b int);
+alter table defcheck_def drop c;
+alter table defcheck attach partition defcheck_def default;
+alter table defcheck_def add check (b <= 0 and b is not null);
+create table defcheck_1 partition of defcheck for values in (1, null);
+INFO:  updated partition constraint for default partition "defcheck_def" is implied by existing constraints
+-- test that complex default partition constraints are enforced correctly
+insert into defcheck_def values (0, 0);
+create table defcheck_0 partition of defcheck for values in (0);
+ERROR:  updated partition constraint for default partition "defcheck_def" would be violated by some row
+drop table defcheck;
diff --git a/src/test/regress/sql/alter_table.sql b/src/test/regress/sql/alter_table.sql
index 0369909b50..8016f8a823 100644
--- a/src/test/regress/sql/alter_table.sql
+++ b/src/test/regress/sql/alter_table.sql
@@ -2648,7 +2648,8 @@ DROP USER regress_alter_table_user1;
 -- default partition
 create table defpart_attach_test (a int) partition by list (a);
 create table defpart_attach_test1 partition of defpart_attach_test for values in (1);
-create table defpart_attach_test_d (like defpart_attach_test);
+create table defpart_attach_test_d (b int, a int);
+alter table defpart_attach_test_d drop b;
 insert into defpart_attach_test_d values (1), (2);
 
 -- error because its constraint as the default partition would be violated
@@ -2660,6 +2661,12 @@ alter table defpart_attach_test_d add check (a > 1);
 -- should be attached successfully and without needing to be scanned
 alter table defpart_attach_test attach partition defpart_attach_test_d default;
 
+-- check that attaching a partition correctly reports any rows in the default
+-- partition that should not be there for the new partition to be attached
+-- successfully
+create table defpart_attach_test_2 (like defpart_attach_test_d);
+alter table defpart_attach_test attach partition defpart_attach_test_2 for values in (2);
+
 drop table defpart_attach_test;
 
 -- check combinations of temporary and permanent relations when attaching
diff --git a/src/test/regress/sql/create_table.sql b/src/test/regress/sql/create_table.sql
index 751c0d39f5..9c6d86a0bf 100644
--- a/src/test/regress/sql/create_table.sql
+++ b/src/test/regress/sql/create_table.sql
@@ -856,3 +856,17 @@ create table volatile_partbound_test2 partition of volatile_partbound_test for v
 insert into volatile_partbound_test values (current_timestamp);
 select tableoid::regclass from volatile_partbound_test;
 drop table volatile_partbound_test;
+
+-- test the case where a check constraint on default partition allows
+-- to avoid scanning it when adding a new partition
+create table defcheck (a int, b int) partition by list (b);
+create table defcheck_def (a int, c int, b int);
+alter table defcheck_def drop c;
+alter table defcheck attach partition defcheck_def default;
+alter table defcheck_def add check (b <= 0 and b is not null);
+create table defcheck_1 partition of defcheck for values in (1, null);
+
+-- test that complex default partition constraints are enforced correctly
+insert into defcheck_def values (0, 0);
+create table defcheck_0 partition of defcheck for values in (0);
+drop table defcheck;
