@ -109,7 +109,9 @@ static void set_baserel_partition_constraint(Relation relation,
* If inhparent is true , all we need to do is set up the attr arrays :
* the RelOptInfo actually represents the appendrel formed by an inheritance
* tree , and so the parent rel ' s physical size and index information isn ' t
* important for it .
* important for it , however , for partitioned tables , we do populate the
* indexlist as the planner uses unique indexes as unique proofs for certain
* optimizations .
*/
void
get_relation_info ( PlannerInfo * root , Oid relationObjectId , bool inhparent ,
@ -175,10 +177,14 @@ get_relation_info(PlannerInfo *root, Oid relationObjectId, bool inhparent,
/*
* Make list of indexes . Ignore indexes on system catalogs if told to .
* Don ' t bother with indexes for an inheritance parent , either .
*/
if ( inhparent | |
( IgnoreSystemIndexes & & IsSystemRelation ( relation ) ) )
* Don ' t bother with indexes from traditional inheritance parents . For
* partitioned tables , we need a list of at least unique indexes as these
* serve as unique proofs for certain planner optimizations . However ,
* let ' s not discriminate here and just record all partitioned indexes
* whether they ' re unique indexes or not .
*/
if ( ( inhparent & & relation - > rd_rel - > relkind ! = RELKIND_PARTITIONED_TABLE )
| | ( IgnoreSystemIndexes & & IsSystemRelation ( relation ) ) )
hasindex = false ;
else
hasindex = relation - > rd_rel - > relhasindex ;
@ -231,16 +237,6 @@ get_relation_info(PlannerInfo *root, Oid relationObjectId, bool inhparent,
continue ;
}
/*
* Ignore partitioned indexes , since they are not usable for
* queries .
*/
if ( indexRelation - > rd_rel - > relkind = = RELKIND_PARTITIONED_INDEX )
{
index_close ( indexRelation , NoLock ) ;
continue ;
}
/*
* If the index is valid , but cannot yet be used , ignore it ; but
* mark the plan we are generating as transient . See
@ -285,6 +281,12 @@ get_relation_info(PlannerInfo *root, Oid relationObjectId, bool inhparent,
info - > relam = indexRelation - > rd_rel - > relam ;
/*
* We don ' t have an AM for partitioned indexes , so we ' ll just
* NULLify the AM related fields for those .
*/
if ( indexRelation - > rd_rel - > relkind ! = RELKIND_PARTITIONED_INDEX )
{
/* We copy just the fields we need, not all of rd_indam */
amroutine = indexRelation - > rd_indam ;
info - > amcanorderbyop = amroutine - > amcanorderbyop ;
@ -329,18 +331,19 @@ get_relation_info(PlannerInfo *root, Oid relationObjectId, bool inhparent,
else if ( amroutine - > amcanorder )
{
/*
* Otherwise , identify the corresponding btree opfamilies by
* trying to map this index ' s " < " operators into btree . Since
* " < " uniquely defines the behavior of a sort order , this is
* a sufficient test .
* Otherwise , identify the corresponding btree opfamilies
* by trying to map this index ' s " < " operators into btree .
* Since " < " uniquely defines the behavior of a sort
* order , this is a sufficient test .
*
* XXX This method is rather slow and also requires the
* undesirable assumption that the other index AM numbers its
* strategies the same as btree . It ' d be better to have a way
* to explicitly declare the corresponding btree opfamily for
* each opfamily of the other index type . But given the lack
* of current or foreseeable amcanorder index types , it ' s not
* worth expending more effort on now .
* undesirable assumption that the other index AM numbers
* its strategies the same as btree . It ' d be better to
* have a way to explicitly declare the corresponding
* btree opfamily for each opfamily of the other index
* type . But given the lack of current or foreseeable
* amcanorder index types , it ' s not worth expending more
* effort on now .
*/
info - > sortopfamily = ( Oid * ) palloc ( sizeof ( Oid ) * nkeycolumns ) ;
info - > reverse_sort = ( bool * ) palloc ( sizeof ( bool ) * nkeycolumns ) ;
@ -388,6 +391,23 @@ get_relation_info(PlannerInfo *root, Oid relationObjectId, bool inhparent,
info - > reverse_sort = NULL ;
info - > nulls_first = NULL ;
}
}
else
{
info - > amcanorderbyop = false ;
info - > amoptionalkey = false ;
info - > amsearcharray = false ;
info - > amsearchnulls = false ;
info - > amcanparallel = false ;
info - > amhasgettuple = false ;
info - > amhasgetbitmap = false ;
info - > amcanmarkpos = false ;
info - > amcostestimate = NULL ;
info - > sortopfamily = NULL ;
info - > reverse_sort = NULL ;
info - > nulls_first = NULL ;
}
/*
* Fetch the index expressions and predicate , if any . We must
@ -416,8 +436,11 @@ get_relation_info(PlannerInfo *root, Oid relationObjectId, bool inhparent,
* the number - of - tuples estimate to equal the parent table ; if it
* is partial then we have to use the same methods as we would for
* a table , except we can be sure that the index is not larger
* than the table .
* than the table . We must ignore partitioned indexes here as as
* there are not physical indexes .
*/
if ( indexRelation - > rd_rel - > relkind ! = RELKIND_PARTITIONED_INDEX )
{
if ( info - > indpred = = NIL )
{
info - > pages = RelationGetNumberOfBlocks ( indexRelation ) ;
@ -435,7 +458,10 @@ get_relation_info(PlannerInfo *root, Oid relationObjectId, bool inhparent,
if ( info - > relam = = BTREE_AM_OID )
{
/* For btrees, get tree height while we have the index open */
/*
* For btrees , get tree height while we have the index
* open
*/
info - > tree_height = _bt_getrootheight ( indexRelation ) ;
}
else
@ -443,6 +469,14 @@ get_relation_info(PlannerInfo *root, Oid relationObjectId, bool inhparent,
/* For other index types, just set it to "unknown" for now */
info - > tree_height = - 1 ;
}
}
else
{
/* Zero these out for partitioned indexes */
info - > pages = 0 ;
info - > tuples = 0.0 ;
info - > tree_height = - 1 ;
}
index_close ( indexRelation , NoLock ) ;