@@ -13419,10 +13419,10 @@ ComputePartitionAttrs(Relation rel, List *partParams, AttrNumber *partattrs,
1341913419static ObjectAddress
1342013420ATExecAttachPartition (List * * wqueue , Relation rel , PartitionCmd * cmd )
1342113421{
13422- Relation attachRel ,
13422+ Relation attachrel ,
1342313423 catalog ;
13424- List * childrels ;
13425- TupleConstr * attachRel_constr ;
13424+ List * attachrel_children ;
13425+ TupleConstr * attachrel_constr ;
1342613426 List * partConstraint ,
1342713427 * existConstraint ;
1342813428 SysScanDesc scan ;
@@ -13434,22 +13434,22 @@ ATExecAttachPartition(List **wqueue, Relation rel, PartitionCmd *cmd)
1343413434 ObjectAddress address ;
1343513435 const char * trigger_name ;
1343613436
13437- attachRel = heap_openrv (cmd -> name , AccessExclusiveLock );
13437+ attachrel = heap_openrv (cmd -> name , AccessExclusiveLock );
1343813438
1343913439 /*
1344013440 * Must be owner of both parent and source table -- parent was checked by
1344113441 * ATSimplePermissions call in ATPrepCmd
1344213442 */
13443- ATSimplePermissions (attachRel , ATT_TABLE | ATT_FOREIGN_TABLE );
13443+ ATSimplePermissions (attachrel , ATT_TABLE | ATT_FOREIGN_TABLE );
1344413444
1344513445 /* A partition can only have one parent */
13446- if (attachRel -> rd_rel -> relispartition )
13446+ if (attachrel -> rd_rel -> relispartition )
1344713447 ereport (ERROR ,
1344813448 (errcode (ERRCODE_WRONG_OBJECT_TYPE ),
1344913449 errmsg ("\"%s\" is already a partition" ,
13450- RelationGetRelationName (attachRel ))));
13450+ RelationGetRelationName (attachrel ))));
1345113451
13452- if (OidIsValid (attachRel -> rd_rel -> reloftype ))
13452+ if (OidIsValid (attachrel -> rd_rel -> reloftype ))
1345313453 ereport (ERROR ,
1345413454 (errcode (ERRCODE_WRONG_OBJECT_TYPE ),
1345513455 errmsg ("cannot attach a typed table as partition" )));
@@ -13462,7 +13462,7 @@ ATExecAttachPartition(List **wqueue, Relation rel, PartitionCmd *cmd)
1346213462 ScanKeyInit (& skey ,
1346313463 Anum_pg_inherits_inhrelid ,
1346413464 BTEqualStrategyNumber , F_OIDEQ ,
13465- ObjectIdGetDatum (RelationGetRelid (attachRel )));
13465+ ObjectIdGetDatum (RelationGetRelid (attachrel )));
1346613466 scan = systable_beginscan (catalog , InheritsRelidSeqnoIndexId , true,
1346713467 NULL , 1 , & skey );
1346813468 if (HeapTupleIsValid (systable_getnext (scan )))
@@ -13475,34 +13475,34 @@ ATExecAttachPartition(List **wqueue, Relation rel, PartitionCmd *cmd)
1347513475 ScanKeyInit (& skey ,
1347613476 Anum_pg_inherits_inhparent ,
1347713477 BTEqualStrategyNumber , F_OIDEQ ,
13478- ObjectIdGetDatum (RelationGetRelid (attachRel )));
13478+ ObjectIdGetDatum (RelationGetRelid (attachrel )));
1347913479 scan = systable_beginscan (catalog , InheritsParentIndexId , true, NULL ,
1348013480 1 , & skey );
1348113481 if (HeapTupleIsValid (systable_getnext (scan )) &&
13482- attachRel -> rd_rel -> relkind == RELKIND_RELATION )
13482+ attachrel -> rd_rel -> relkind == RELKIND_RELATION )
1348313483 ereport (ERROR ,
1348413484 (errcode (ERRCODE_WRONG_OBJECT_TYPE ),
1348513485 errmsg ("cannot attach inheritance parent as partition" )));
1348613486 systable_endscan (scan );
1348713487 heap_close (catalog , AccessShareLock );
1348813488
1348913489 /*
13490- * Prevent circularity by seeing if rel is a partition of attachRel . (In
13490+ * Prevent circularity by seeing if rel is a partition of attachrel . (In
1349113491 * particular, this disallows making a rel a partition of itself.)
1349213492 */
13493- childrels = find_all_inheritors (RelationGetRelid (attachRel ),
13494- AccessShareLock , NULL );
13495- if (list_member_oid (childrels , RelationGetRelid (rel )))
13493+ attachrel_children = find_all_inheritors (RelationGetRelid (attachrel ),
13494+ AccessShareLock , NULL );
13495+ if (list_member_oid (attachrel_children , RelationGetRelid (rel )))
1349613496 ereport (ERROR ,
1349713497 (errcode (ERRCODE_DUPLICATE_TABLE ),
1349813498 errmsg ("circular inheritance not allowed" ),
1349913499 errdetail ("\"%s\" is already a child of \"%s\"." ,
1350013500 RelationGetRelationName (rel ),
13501- RelationGetRelationName (attachRel ))));
13501+ RelationGetRelationName (attachrel ))));
1350213502
1350313503 /* Temp parent cannot have a partition that is itself not a temp */
1350413504 if (rel -> rd_rel -> relpersistence == RELPERSISTENCE_TEMP &&
13505- attachRel -> rd_rel -> relpersistence != RELPERSISTENCE_TEMP )
13505+ attachrel -> rd_rel -> relpersistence != RELPERSISTENCE_TEMP )
1350613506 ereport (ERROR ,
1350713507 (errcode (ERRCODE_WRONG_OBJECT_TYPE ),
1350813508 errmsg ("cannot attach a permanent relation as partition of temporary relation \"%s\"" ,
@@ -13516,30 +13516,30 @@ ATExecAttachPartition(List **wqueue, Relation rel, PartitionCmd *cmd)
1351613516 errmsg ("cannot attach as partition of temporary relation of another session" )));
1351713517
1351813518 /* Ditto for the partition */
13519- if (attachRel -> rd_rel -> relpersistence == RELPERSISTENCE_TEMP &&
13520- !attachRel -> rd_islocaltemp )
13519+ if (attachrel -> rd_rel -> relpersistence == RELPERSISTENCE_TEMP &&
13520+ !attachrel -> rd_islocaltemp )
1352113521 ereport (ERROR ,
1352213522 (errcode (ERRCODE_WRONG_OBJECT_TYPE ),
1352313523 errmsg ("cannot attach temporary relation of another session as partition" )));
1352413524
1352513525 /* If parent has OIDs then child must have OIDs */
13526- if (rel -> rd_rel -> relhasoids && !attachRel -> rd_rel -> relhasoids )
13526+ if (rel -> rd_rel -> relhasoids && !attachrel -> rd_rel -> relhasoids )
1352713527 ereport (ERROR ,
1352813528 (errcode (ERRCODE_WRONG_OBJECT_TYPE ),
1352913529 errmsg ("cannot attach table \"%s\" without OIDs as partition of"
13530- " table \"%s\" with OIDs" , RelationGetRelationName (attachRel ),
13530+ " table \"%s\" with OIDs" , RelationGetRelationName (attachrel ),
1353113531 RelationGetRelationName (rel ))));
1353213532
13533- /* OTOH, if parent doesn't have them, do not allow in attachRel either */
13534- if (attachRel -> rd_rel -> relhasoids && !rel -> rd_rel -> relhasoids )
13533+ /* OTOH, if parent doesn't have them, do not allow in attachrel either */
13534+ if (attachrel -> rd_rel -> relhasoids && !rel -> rd_rel -> relhasoids )
1353513535 ereport (ERROR ,
1353613536 (errcode (ERRCODE_WRONG_OBJECT_TYPE ),
1353713537 errmsg ("cannot attach table \"%s\" with OIDs as partition of table"
13538- " \"%s\" without OIDs" , RelationGetRelationName (attachRel ),
13538+ " \"%s\" without OIDs" , RelationGetRelationName (attachrel ),
1353913539 RelationGetRelationName (rel ))));
1354013540
13541- /* Check if there are any columns in attachRel that aren't in the parent */
13542- tupleDesc = RelationGetDescr (attachRel );
13541+ /* Check if there are any columns in attachrel that aren't in the parent */
13542+ tupleDesc = RelationGetDescr (attachrel );
1354313543 natts = tupleDesc -> natts ;
1354413544 for (attno = 1 ; attno <= natts ; attno ++ )
1354513545 {
@@ -13557,7 +13557,7 @@ ATExecAttachPartition(List **wqueue, Relation rel, PartitionCmd *cmd)
1355713557 ereport (ERROR ,
1355813558 (errcode (ERRCODE_DATATYPE_MISMATCH ),
1355913559 errmsg ("table \"%s\" contains column \"%s\" not found in parent \"%s\"" ,
13560- RelationGetRelationName (attachRel ), attributeName ,
13560+ RelationGetRelationName (attachrel ), attributeName ,
1356113561 RelationGetRelationName (rel )),
1356213562 errdetail ("New partition should contain only the columns present in parent." )));
1356313563 }
@@ -13567,34 +13567,34 @@ ATExecAttachPartition(List **wqueue, Relation rel, PartitionCmd *cmd)
1356713567 * currently don't allow it to become a partition. See also prohibitions
1356813568 * in ATExecAddInherit() and CreateTrigger().
1356913569 */
13570- trigger_name = FindTriggerIncompatibleWithInheritance (attachRel -> trigdesc );
13570+ trigger_name = FindTriggerIncompatibleWithInheritance (attachrel -> trigdesc );
1357113571 if (trigger_name != NULL )
1357213572 ereport (ERROR ,
1357313573 (errcode (ERRCODE_FEATURE_NOT_SUPPORTED ),
1357413574 errmsg ("trigger \"%s\" prevents table \"%s\" from becoming a partition" ,
13575- trigger_name , RelationGetRelationName (attachRel )),
13575+ trigger_name , RelationGetRelationName (attachrel )),
1357613576 errdetail ("ROW triggers with transition tables are not supported on partitions" )));
1357713577
1357813578 /* OK to create inheritance. Rest of the checks performed there */
13579- CreateInheritance (attachRel , rel );
13579+ CreateInheritance (attachrel , rel );
1358013580
1358113581 /*
1358213582 * Check that the new partition's bound is valid and does not overlap any
1358313583 * of existing partitions of the parent - note that it does not return on
1358413584 * error.
1358513585 */
13586- check_new_partition_bound (RelationGetRelationName (attachRel ), rel ,
13586+ check_new_partition_bound (RelationGetRelationName (attachrel ), rel ,
1358713587 cmd -> bound );
1358813588
1358913589 /* Update the pg_class entry. */
13590- StorePartitionBound (attachRel , rel , cmd -> bound );
13590+ StorePartitionBound (attachrel , rel , cmd -> bound );
1359113591
1359213592 /*
1359313593 * Generate partition constraint from the partition bound specification.
1359413594 * If the parent itself is a partition, make sure to include its
1359513595 * constraint as well.
1359613596 */
13597- partConstraint = list_concat (get_qual_from_partbound (attachRel , rel ,
13597+ partConstraint = list_concat (get_qual_from_partbound (attachrel , rel ,
1359813598 cmd -> bound ),
1359913599 RelationGetPartitionQual (rel ));
1360013600 partConstraint = (List * ) eval_const_expressions (NULL ,
@@ -13612,20 +13612,20 @@ ATExecAttachPartition(List **wqueue, Relation rel, PartitionCmd *cmd)
1361213612 * There is a case in which we cannot rely on just the result of the
1361313613 * proof.
1361413614 */
13615- attachRel_constr = tupleDesc -> constr ;
13615+ attachrel_constr = tupleDesc -> constr ;
1361613616 existConstraint = NIL ;
13617- if (attachRel_constr != NULL )
13617+ if (attachrel_constr != NULL )
1361813618 {
13619- int num_check = attachRel_constr -> num_check ;
13619+ int num_check = attachrel_constr -> num_check ;
1362013620 int i ;
1362113621
13622- if (attachRel_constr -> has_not_null )
13622+ if (attachrel_constr -> has_not_null )
1362313623 {
13624- int natts = attachRel -> rd_att -> natts ;
13624+ int natts = attachrel -> rd_att -> natts ;
1362513625
1362613626 for (i = 1 ; i <= natts ; i ++ )
1362713627 {
13628- Form_pg_attribute att = attachRel -> rd_att -> attrs [i - 1 ];
13628+ Form_pg_attribute att = attachrel -> rd_att -> attrs [i - 1 ];
1362913629
1363013630 if (att -> attnotnull && !att -> attisdropped )
1363113631 {
@@ -13659,10 +13659,10 @@ ATExecAttachPartition(List **wqueue, Relation rel, PartitionCmd *cmd)
1365913659 * If this constraint hasn't been fully validated yet, we must
1366013660 * ignore it here.
1366113661 */
13662- if (!attachRel_constr -> check [i ].ccvalid )
13662+ if (!attachrel_constr -> check [i ].ccvalid )
1366313663 continue ;
1366413664
13665- cexpr = stringToNode (attachRel_constr -> check [i ].ccbin );
13665+ cexpr = stringToNode (attachrel_constr -> check [i ].ccbin );
1366613666
1366713667 /*
1366813668 * Run each expression through const-simplification and
@@ -13684,28 +13684,25 @@ ATExecAttachPartition(List **wqueue, Relation rel, PartitionCmd *cmd)
1368413684 skip_validate = true;
1368513685 }
1368613686
13687- /* It's safe to skip the validation scan after all */
1368813687 if (skip_validate )
13688+ {
13689+ /* No need to scan the table after all. */
1368913690 ereport (INFO ,
1369013691 (errmsg ("partition constraint for table \"%s\" is implied by existing constraints" ,
13691- RelationGetRelationName (attachRel ))));
13692-
13693- /*
13694- * Set up to have the table be scanned to validate the partition
13695- * constraint (see partConstraint above). If it's a partitioned table, we
13696- * instead schedule its leaf partitions to be scanned.
13697- */
13698- if (!skip_validate )
13692+ RelationGetRelationName (attachrel ))));
13693+ }
13694+ else
1369913695 {
13696+ /* Constraints proved insufficient, so we need to scan the table. */
1370013697 List * all_parts ;
1370113698 ListCell * lc ;
1370213699
1370313700 /* Take an exclusive lock on the partitions to be checked */
13704- if (attachRel -> rd_rel -> relkind == RELKIND_PARTITIONED_TABLE )
13705- all_parts = find_all_inheritors (RelationGetRelid (attachRel ),
13701+ if (attachrel -> rd_rel -> relkind == RELKIND_PARTITIONED_TABLE )
13702+ all_parts = find_all_inheritors (RelationGetRelid (attachrel ),
1370613703 AccessExclusiveLock , NULL );
1370713704 else
13708- all_parts = list_make1_oid (RelationGetRelid (attachRel ));
13705+ all_parts = list_make1_oid (RelationGetRelid (attachrel ));
1370913706
1371013707 foreach (lc , all_parts )
1371113708 {
@@ -13716,23 +13713,23 @@ ATExecAttachPartition(List **wqueue, Relation rel, PartitionCmd *cmd)
1371613713 bool found_whole_row ;
1371713714
1371813715 /* Lock already taken */
13719- if (part_relid != RelationGetRelid (attachRel ))
13716+ if (part_relid != RelationGetRelid (attachrel ))
1372013717 part_rel = heap_open (part_relid , NoLock );
1372113718 else
13722- part_rel = attachRel ;
13719+ part_rel = attachrel ;
1372313720
1372413721 /*
13725- * Skip if it's a partitioned table. Only RELKIND_RELATION
13726- * relations (ie, leaf partitions) need to be scanned .
13722+ * Skip if the partition is itself a partitioned table. We can
13723+ * only ever scan RELKIND_RELATION relations .
1372713724 */
13728- if (part_rel != attachRel &&
13729- part_rel -> rd_rel -> relkind == RELKIND_PARTITIONED_TABLE )
13725+ if (part_rel -> rd_rel -> relkind == RELKIND_PARTITIONED_TABLE )
1373013726 {
13731- heap_close (part_rel , NoLock );
13727+ if (part_rel != attachrel )
13728+ heap_close (part_rel , NoLock );
1373213729 continue ;
1373313730 }
1373413731
13735- /* Grab a work queue entry */
13732+ /* Grab a work queue entry. */
1373613733 tab = ATGetQueueEntry (wqueue , part_rel );
1373713734
1373813735 /* Adjust constraint to match this partition */
@@ -13746,15 +13743,15 @@ ATExecAttachPartition(List **wqueue, Relation rel, PartitionCmd *cmd)
1374613743 elog (ERROR , "unexpected whole-row reference found in partition key" );
1374713744
1374813745 /* keep our lock until commit */
13749- if (part_rel != attachRel )
13746+ if (part_rel != attachrel )
1375013747 heap_close (part_rel , NoLock );
1375113748 }
1375213749 }
1375313750
13754- ObjectAddressSet (address , RelationRelationId , RelationGetRelid (attachRel ));
13751+ ObjectAddressSet (address , RelationRelationId , RelationGetRelid (attachrel ));
1375513752
1375613753 /* keep our lock until commit */
13757- heap_close (attachRel , NoLock );
13754+ heap_close (attachrel , NoLock );
1375813755
1375913756 return address ;
1376013757}
0 commit comments