@@ -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 ,
1342313423catalog ;
13424- List * childrels ;
13425- TupleConstr * attachRel_constr ;
13424+ List * attachrel_children ;
13425+ TupleConstr * attachrel_constr ;
1342613426List * partConstraint ,
1342713427* existConstraint ;
1342813428SysScanDesc scan ;
@@ -13434,22 +13434,22 @@ ATExecAttachPartition(List **wqueue, Relation rel, PartitionCmd *cmd)
1343413434ObjectAddress address ;
1343513435const 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 )
1344713447ereport (ERROR ,
1344813448(errcode (ERRCODE_WRONG_OBJECT_TYPE ),
1344913449errmsg ("\"%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 ))
1345313453ereport (ERROR ,
1345413454(errcode (ERRCODE_WRONG_OBJECT_TYPE ),
1345513455errmsg ("cannot attach a typed table as partition" )));
@@ -13462,7 +13462,7 @@ ATExecAttachPartition(List **wqueue, Relation rel, PartitionCmd *cmd)
1346213462ScanKeyInit (& skey ,
1346313463Anum_pg_inherits_inhrelid ,
1346413464BTEqualStrategyNumber ,F_OIDEQ ,
13465- ObjectIdGetDatum (RelationGetRelid (attachRel )));
13465+ ObjectIdGetDatum (RelationGetRelid (attachrel )));
1346613466scan = systable_beginscan (catalog ,InheritsRelidSeqnoIndexId , true,
1346713467NULL ,1 ,& skey );
1346813468if (HeapTupleIsValid (systable_getnext (scan )))
@@ -13475,34 +13475,34 @@ ATExecAttachPartition(List **wqueue, Relation rel, PartitionCmd *cmd)
1347513475ScanKeyInit (& skey ,
1347613476Anum_pg_inherits_inhparent ,
1347713477BTEqualStrategyNumber ,F_OIDEQ ,
13478- ObjectIdGetDatum (RelationGetRelid (attachRel )));
13478+ ObjectIdGetDatum (RelationGetRelid (attachrel )));
1347913479scan = systable_beginscan (catalog ,InheritsParentIndexId , true,NULL ,
13480134801 ,& skey );
1348113481if (HeapTupleIsValid (systable_getnext (scan ))&&
13482- attachRel -> rd_rel -> relkind == RELKIND_RELATION )
13482+ attachrel -> rd_rel -> relkind == RELKIND_RELATION )
1348313483ereport (ERROR ,
1348413484(errcode (ERRCODE_WRONG_OBJECT_TYPE ),
1348513485errmsg ("cannot attach inheritance parent as partition" )));
1348613486systable_endscan (scan );
1348713487heap_close (catalog ,AccessShareLock );
1348813488
1348913489/*
13490- * Prevent circularity by seeing if rel is a partition ofattachRel . (In
13490+ * Prevent circularity by seeing if rel is a partition ofattachrel . (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 )))
1349613496ereport (ERROR ,
1349713497(errcode (ERRCODE_DUPLICATE_TABLE ),
1349813498errmsg ("circular inheritance not allowed" ),
1349913499errdetail ("\"%s\" is already a child of \"%s\"." ,
1350013500RelationGetRelationName (rel ),
13501- RelationGetRelationName (attachRel ))));
13501+ RelationGetRelationName (attachrel ))));
1350213502
1350313503/* Temp parent cannot have a partition that is itself not a temp */
1350413504if (rel -> rd_rel -> relpersistence == RELPERSISTENCE_TEMP &&
13505- attachRel -> rd_rel -> relpersistence != RELPERSISTENCE_TEMP )
13505+ attachrel -> rd_rel -> relpersistence != RELPERSISTENCE_TEMP )
1350613506ereport (ERROR ,
1350713507(errcode (ERRCODE_WRONG_OBJECT_TYPE ),
1350813508errmsg ("cannot attach a permanent relation as partition of temporary relation \"%s\"" ,
@@ -13516,30 +13516,30 @@ ATExecAttachPartition(List **wqueue, Relation rel, PartitionCmd *cmd)
1351613516errmsg ("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 )
1352113521ereport (ERROR ,
1352213522(errcode (ERRCODE_WRONG_OBJECT_TYPE ),
1352313523errmsg ("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 )
1352713527ereport (ERROR ,
1352813528(errcode (ERRCODE_WRONG_OBJECT_TYPE ),
1352913529errmsg ("cannot attach table \"%s\" without OIDs as partition of"
13530- " table \"%s\" with OIDs" ,RelationGetRelationName (attachRel ),
13530+ " table \"%s\" with OIDs" ,RelationGetRelationName (attachrel ),
1353113531RelationGetRelationName (rel ))));
1353213532
13533- /* OTOH, if parent doesn't have them, do not allow inattachRel either */
13534- if (attachRel -> rd_rel -> relhasoids && !rel -> rd_rel -> relhasoids )
13533+ /* OTOH, if parent doesn't have them, do not allow inattachrel either */
13534+ if (attachrel -> rd_rel -> relhasoids && !rel -> rd_rel -> relhasoids )
1353513535ereport (ERROR ,
1353613536(errcode (ERRCODE_WRONG_OBJECT_TYPE ),
1353713537errmsg ("cannot attach table \"%s\" with OIDs as partition of table"
13538- " \"%s\" without OIDs" ,RelationGetRelationName (attachRel ),
13538+ " \"%s\" without OIDs" ,RelationGetRelationName (attachrel ),
1353913539RelationGetRelationName (rel ))));
1354013540
13541- /* Check if there are any columns inattachRel that aren't in the parent */
13542- tupleDesc = RelationGetDescr (attachRel );
13541+ /* Check if there are any columns inattachrel that aren't in the parent */
13542+ tupleDesc = RelationGetDescr (attachrel );
1354313543natts = tupleDesc -> natts ;
1354413544for (attno = 1 ;attno <=natts ;attno ++ )
1354513545{
@@ -13557,7 +13557,7 @@ ATExecAttachPartition(List **wqueue, Relation rel, PartitionCmd *cmd)
1355713557ereport (ERROR ,
1355813558(errcode (ERRCODE_DATATYPE_MISMATCH ),
1355913559errmsg ("table \"%s\" contains column \"%s\" not found in parent \"%s\"" ,
13560- RelationGetRelationName (attachRel ),attributeName ,
13560+ RelationGetRelationName (attachrel ),attributeName ,
1356113561RelationGetRelationName (rel )),
1356213562errdetail ("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 );
1357113571if (trigger_name != NULL )
1357213572ereport (ERROR ,
1357313573(errcode (ERRCODE_FEATURE_NOT_SUPPORTED ),
1357413574errmsg ("trigger \"%s\" prevents table \"%s\" from becoming a partition" ,
13575- trigger_name ,RelationGetRelationName (attachRel )),
13575+ trigger_name ,RelationGetRelationName (attachrel )),
1357613576errdetail ("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 ,
1358713587cmd -> 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 ,
1359813598cmd -> bound ),
1359913599RelationGetPartitionQual (rel ));
1360013600partConstraint = (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 ;
1361613616existConstraint = 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 ;
1362013620int 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
1362613626for (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
1363013630if (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 )
1366313663continue ;
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)
1368413684skip_validate = true;
1368513685}
1368613686
13687- /* It's safe to skip the validation scan after all */
1368813687if (skip_validate )
13688+ {
13689+ /* No need to scan the table after all. */
1368913690ereport (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. */
1370013697List * all_parts ;
1370113698ListCell * 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 ),
1370613703AccessExclusiveLock ,NULL );
1370713704else
13708- all_parts = list_make1_oid (RelationGetRelid (attachRel ));
13705+ all_parts = list_make1_oid (RelationGetRelid (attachrel ));
1370913706
1371013707foreach (lc ,all_parts )
1371113708{
@@ -13716,23 +13713,23 @@ ATExecAttachPartition(List **wqueue, Relation rel, PartitionCmd *cmd)
1371613713bool found_whole_row ;
1371713714
1371813715/* Lock already taken */
13719- if (part_relid != RelationGetRelid (attachRel ))
13716+ if (part_relid != RelationGetRelid (attachrel ))
1372013717part_rel = heap_open (part_relid ,NoLock );
1372113718else
13722- part_rel = attachRel ;
13719+ part_rel = attachrel ;
1372313720
1372413721/*
13725- * Skip ifit's a partitioned table.Only RELKIND_RELATION
13726- *relations (ie, leaf partitions) need to be scanned .
13722+ * Skip ifthe 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 );
1373213729continue ;
1373313730}
1373413731
13735- /* Grab a work queue entry */
13732+ /* Grab a work queue entry. */
1373613733tab = ATGetQueueEntry (wqueue ,part_rel );
1373713734
1373813735/* Adjust constraint to match this partition */
@@ -13746,15 +13743,15 @@ ATExecAttachPartition(List **wqueue, Relation rel, PartitionCmd *cmd)
1374613743elog (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 )
1375013747heap_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
1375913756return address ;
1376013757}