diff --git a/src/backend/nodes/outfuncs.c b/src/backend/nodes/outfuncs.c index c2f0e0f8ee..389808c9e9 100644 --- a/src/backend/nodes/outfuncs.c +++ b/src/backend/nodes/outfuncs.c @@ -2137,16 +2137,6 @@ _outIndexOptInfo(StringInfo str, const IndexOptInfo *node) /* we don't bother with fields copied from the index AM's API struct */ } -static void -_outForeignKeyOptInfo(StringInfo str, const ForeignKeyOptInfo *node) -{ - WRITE_NODE_TYPE("FOREIGNKEYOPTINFO"); - - WRITE_OID_FIELD(conrelid); - WRITE_OID_FIELD(confrelid); - WRITE_INT_FIELD(nkeys); -} - static void _outEquivalenceClass(StringInfo str, const EquivalenceClass *node) { @@ -3617,9 +3607,6 @@ outNode(StringInfo str, const void *obj) case T_IndexOptInfo: _outIndexOptInfo(str, obj); break; - case T_ForeignKeyOptInfo: - _outForeignKeyOptInfo(str, obj); - break; case T_EquivalenceClass: _outEquivalenceClass(str, obj); break; diff --git a/src/backend/optimizer/path/costsize.c b/src/backend/optimizer/path/costsize.c index 4c9d8d9cbd..b39c928eba 100644 --- a/src/backend/optimizer/path/costsize.c +++ b/src/backend/optimizer/path/costsize.c @@ -126,7 +126,6 @@ bool enable_nestloop = true; bool enable_material = true; bool enable_mergejoin = true; bool enable_hashjoin = true; -bool enable_fkey_estimates = true; typedef struct { @@ -3888,361 +3887,6 @@ get_parameterized_joinrel_size(PlannerInfo *root, RelOptInfo *rel, return nrows; } -/* - * quals_match_foreign_key - * Determines if the foreign key is matched by joinquals. - * - * Checks that there are conditions on all columns of the foreign key, matching - * the operator used by the foreign key etc. If such complete match is found, - * the function returns bitmap identifying the matching quals (0-based). - * - * Otherwise (no match at all or incomplete match), NULL is returned. - * - * XXX It seems possible in the future to do something useful when a - * partial match occurs between join and FK, but that is less common - * and that part isn't worked out yet. - */ -static Bitmapset * -quals_match_foreign_key(PlannerInfo *root, ForeignKeyOptInfo *fkinfo, - RelOptInfo *fkrel, RelOptInfo *foreignrel, - List *joinquals) -{ - int i; - int nkeys = fkinfo->nkeys; - Bitmapset *qualmatches = NULL; - Bitmapset *fkmatches = NULL; - - /* - * Loop over each column of the foreign key and build a bitmapset - * of each joinqual which matches. Note that we don't stop when we find - * the first match, as the expression could be duplicated in the - * joinquals, and we want to generate a bitmapset which has bits set for - * every matching join qual. - */ - for (i = 0; i < nkeys; i++) - { - ListCell *lc; - int quallstidx = -1; - - foreach(lc, joinquals) - { - RestrictInfo *rinfo; - OpExpr *clause; - Var *leftvar; - Var *rightvar; - - quallstidx++; - - /* - * Technically we don't need to, but here we skip this qual if - * we've matched it to part of the foreign key already. This - * should prove to be a useful optimization when the quals appear - * in the same order as the foreign key's keys. We need only bother - * doing this when the foreign key is made up of more than 1 set - * of columns, and we're not testing the first column. - */ - if (i > 0 && bms_is_member(quallstidx, qualmatches)) - continue; - - rinfo = (RestrictInfo *) lfirst(lc); - clause = (OpExpr *) rinfo->clause; - - /* only OpExprs are useful for consideration */ - if (!IsA(clause, OpExpr)) - continue; - - /* - * If the operator does not match then there's little point in - * checking the operands. - */ - if (clause->opno != fkinfo->conpfeqop[i]) - continue; - - leftvar = (Var *) get_leftop((Expr *) clause); - rightvar = (Var *) get_rightop((Expr *) clause); - - /* Foreign keys only support Vars, so ignore anything more complex */ - if (!IsA(leftvar, Var) || !IsA(rightvar, Var)) - continue; - - /* - * For RestrictInfos built from an eclass we must consider each - * member of the eclass as rinfo's operands may not belong to the - * foreign key. For efficient tracking of which Vars we've found, - * since we're only tracking 2 Vars, we use a bitmask. We can - * safely finish searching when both of the least significant bits - * are set. - */ - if (rinfo->parent_ec) - { - EquivalenceClass *ec = rinfo->parent_ec; - ListCell *lc2; - int foundvarmask = 0; - - foreach(lc2, ec->ec_members) - { - EquivalenceMember *em = (EquivalenceMember *) lfirst(lc2); - Var *var = (Var *) em->em_expr; - - if (!IsA(var, Var)) - continue; - - if (foreignrel->relid == var->varno && - fkinfo->confkeys[i] == var->varattno) - foundvarmask |= 1; - - else if (fkrel->relid == var->varno && - fkinfo->conkeys[i] == var->varattno) - foundvarmask |= 2; - - /* - * Check if we've found both matches. If found we add - * this qual to the matched list and mark this key as - * matched too. - */ - if (foundvarmask == 3) - { - qualmatches = bms_add_member(qualmatches, quallstidx); - fkmatches = bms_add_member(fkmatches, i); - break; - } - } - } - else - { - /* - * In this non eclass RestrictInfo case we'll check if the left - * and right Vars match to this part of the foreign key. - * Remember that this could be written with the Vars in either - * order, so we test both permutations of the expression. - */ - if ((foreignrel->relid == leftvar->varno) && - (fkrel->relid == rightvar->varno) && - (fkinfo->confkeys[i] == leftvar->varattno) && - (fkinfo->conkeys[i] == rightvar->varattno)) - { - qualmatches = bms_add_member(qualmatches, quallstidx); - fkmatches = bms_add_member(fkmatches, i); - } - else if ((foreignrel->relid == rightvar->varno) && - (fkrel->relid == leftvar->varno) && - (fkinfo->confkeys[i] == rightvar->varattno) && - (fkinfo->conkeys[i] == leftvar->varattno)) - { - qualmatches = bms_add_member(qualmatches, quallstidx); - fkmatches = bms_add_member(fkmatches, i); - } - } - } - } - - /* can't find more matches than columns in the foreign key */ - Assert(bms_num_members(fkmatches) <= nkeys); - - /* Only return the matches if the foreign key is matched fully. */ - if (bms_num_members(fkmatches) == nkeys) - { - bms_free(fkmatches); - return qualmatches; - } - - bms_free(fkmatches); - bms_free(qualmatches); - - return NULL; -} - -/* - * find_best_foreign_key_quals - * Finds the foreign key best matching the joinquals. - * - * Analyzes joinquals to determine if any quals match foreign keys defined the - * two relations (fkrel referencing foreignrel). When multiple foreign keys - * match, we choose the one with the most keys as the best one because of the - * way estimation occurs in clauselist_join_selectivity(). We could choose - * the FK matching the most quals, however we assume the quals may be duplicated. - * - * We also track which joinquals match the current foreign key, so that we can - * easily skip then when computing the selectivity. - * - * When no matching foreign key is found we return 0, otherwise we return the - * number of keys in the foreign key. - * - * Foreign keys matched only partially are currently ignored. - */ -static int -find_best_foreign_key_quals(PlannerInfo *root, RelOptInfo *fkrel, - RelOptInfo *foreignrel, List *joinquals, - Bitmapset **joinqualsbitmap) -{ - Bitmapset *qualbestmatch; - ListCell *lc; - int bestmatchnkeys; - - /* - * fast path out when there's no foreign keys on fkrel, or when use of - * foreign keys for estimation is disabled by GUC - */ - if ((fkrel->fkeylist == NIL) || (!enable_fkey_estimates)) - { - *joinqualsbitmap = NULL; - return 0; - } - - qualbestmatch = NULL; - bestmatchnkeys = 0; - - /* now check the matches for each foreign key defined on the fkrel */ - foreach(lc, fkrel->fkeylist) - { - ForeignKeyOptInfo *fkinfo = (ForeignKeyOptInfo *) lfirst(lc); - Bitmapset *qualsmatched; - - /* - * We make no attempt in checking that this foreign key actually - * references 'foreignrel', the reasoning here is that we may be able - * to match the foreign key to an eclass member Var of a RestrictInfo - * that's in qualslist, this Var may belong to some other relation. - * - * XXX Is this assumption safe in all cases? Maybe not, but does - * it lead to a worse estimate than the previous approach? Doubt it. - */ - qualsmatched = quals_match_foreign_key(root, fkinfo, fkrel, foreignrel, - joinquals); - - /* Did we get a match? And is that match better than a previous one? */ - if (qualsmatched != NULL && fkinfo->nkeys > bestmatchnkeys) - { - /* save the new best match */ - bms_free(qualbestmatch); - qualbestmatch = qualsmatched; - bestmatchnkeys = fkinfo->nkeys; - } - } - - *joinqualsbitmap = qualbestmatch; - return bestmatchnkeys; -} - -/* - * clauselist_join_selectivity - * Estimate selectivity of join clauses either by using foreign key info - * or by using the regular clauselist_selectivity(). - * - * Since selectivity estimates for each joinqual are multiplied together, this - * can cause significant underestimates on the number of join tuples in cases - * where there's more than 1 clause in the join condition. To help ease the - * pain here we make use of foreign keys, and we assume that 1 row will match - * when *all* of the foreign key columns are present in the join condition, any - * additional clauses are estimated using clauselist_selectivity(). - * - * Note this ignores whether the FK is invalid or currently deferred; we don't - * rely on this assumption for correctness of the query, so it is a reasonable - * and safe assumption for planning purposes. - */ -static Selectivity -clauselist_join_selectivity(PlannerInfo *root, List *joinquals, - JoinType jointype, SpecialJoinInfo *sjinfo) -{ - int outerid; - int innerid; - Selectivity sel = 1.0; - Bitmapset *foundfkquals = NULL; - - innerid = -1; - while ((innerid = bms_next_member(sjinfo->min_righthand, innerid)) >= 0) - { - RelOptInfo *innerrel = find_base_rel(root, innerid); - - outerid = -1; - while ((outerid = bms_next_member(sjinfo->min_lefthand, outerid)) >= 0) - { - RelOptInfo *outerrel = find_base_rel(root, outerid); - Bitmapset *outer2inner; - Bitmapset *inner2outer; - int innermatches; - int outermatches; - - /* - * check which quals are matched by a foreign key referencing the - * innerrel. - */ - outermatches = find_best_foreign_key_quals(root, outerrel, - innerrel, joinquals, &outer2inner); - - /* do the same, but with relations swapped */ - innermatches = find_best_foreign_key_quals(root, innerrel, - outerrel, joinquals, &inner2outer); - - /* - * did we find any matches at all? If so we need to see which one is - * the best/longest match - */ - if (outermatches != 0 || innermatches != 0) - { - double referenced_tuples; - bool overlap; - - /* either could be zero, but not both. */ - if (outermatches < innermatches) - { - overlap = bms_overlap(foundfkquals, inner2outer); - - foundfkquals = bms_add_members(foundfkquals, inner2outer); - referenced_tuples = Max(outerrel->tuples, 1.0); - } - else - { - overlap = bms_overlap(foundfkquals, outer2inner); - - foundfkquals = bms_add_members(foundfkquals, outer2inner); - referenced_tuples = Max(innerrel->tuples, 1.0); - } - - /* - * XXX should we ignore these overlapping matches? - * Or perhaps take the Max() or Min()? - */ - if (overlap) - { - if (jointype == JOIN_SEMI || jointype == JOIN_ANTI) - sel = Min(sel,Min(1.0 / (outerrel->tuples / Max(innerrel->tuples, 1.0)), 1.0)); - else - sel = Min(sel, 1.0 / referenced_tuples); - } - else - { - if (jointype == JOIN_SEMI || jointype == JOIN_ANTI) - sel *= Min(1.0 / (outerrel->tuples / Max(innerrel->tuples, 1.0)), 1.0); - else - sel *= 1.0 / referenced_tuples; - } - } - } - } - - /* - * If any non matched quals exist then we build a list of the non-matches - * and use clauselist_selectivity() to estimate the selectivity of these. - */ - if (bms_num_members(foundfkquals) < list_length(joinquals)) - { - ListCell *lc; - int lstidx = 0; - List *nonfkeyclauses = NIL; - - foreach (lc, joinquals) - { - if (!bms_is_member(lstidx, foundfkquals)) - nonfkeyclauses = lappend(nonfkeyclauses, lfirst(lc)); - lstidx++; - } - sel *= clauselist_selectivity(root, nonfkeyclauses, 0, jointype, sjinfo); - } - - return sel; -} - /* * calc_joinrel_size_estimate * Workhorse for set_joinrel_size_estimates and @@ -4289,11 +3933,11 @@ calc_joinrel_size_estimate(PlannerInfo *root, } /* Get the separate selectivities */ - jselec = clauselist_join_selectivity(root, - joinquals, - jointype, - sjinfo); - + jselec = clauselist_selectivity(root, + joinquals, + 0, + jointype, + sjinfo); pselec = clauselist_selectivity(root, pushedquals, 0, @@ -4306,10 +3950,11 @@ calc_joinrel_size_estimate(PlannerInfo *root, } else { - jselec = clauselist_join_selectivity(root, - restrictlist, - jointype, - sjinfo); + jselec = clauselist_selectivity(root, + restrictlist, + 0, + jointype, + sjinfo); pselec = 0.0; /* not used, keep compiler quiet */ } diff --git a/src/backend/optimizer/util/plancat.c b/src/backend/optimizer/util/plancat.c index b0b606ebc8..3a585ade74 100644 --- a/src/backend/optimizer/util/plancat.c +++ b/src/backend/optimizer/util/plancat.c @@ -28,7 +28,6 @@ #include "catalog/dependency.h" #include "catalog/heap.h" #include "catalog/pg_am.h" -#include "catalog/pg_constraint.h" #include "foreign/fdwapi.h" #include "miscadmin.h" #include "nodes/makefuncs.h" @@ -42,7 +41,6 @@ #include "rewrite/rewriteManip.h" #include "storage/bufmgr.h" #include "utils/lsyscache.h" -#include "utils/syscache.h" #include "utils/rel.h" #include "utils/snapmgr.h" @@ -96,9 +94,6 @@ get_relation_info(PlannerInfo *root, Oid relationObjectId, bool inhparent, Relation relation; bool hasindex; List *indexinfos = NIL; - List *fkinfos = NIL; - List *fkoidlist; - ListCell *l; /* * We need not lock the relation since it was already locked, either by @@ -149,6 +144,7 @@ get_relation_info(PlannerInfo *root, Oid relationObjectId, bool inhparent, if (hasindex) { List *indexoidlist; + ListCell *l; LOCKMODE lmode; indexoidlist = RelationGetIndexList(relation); @@ -395,85 +391,6 @@ get_relation_info(PlannerInfo *root, Oid relationObjectId, bool inhparent, rel->indexlist = indexinfos; - /* - * Load foreign key data. Note this is the definitional data from the - * catalog only and does not lock the referenced tables here. The - * precise definition of the FK is important and may affect the usage - * elsewhere in the planner, e.g. if the constraint is deferred or - * if the constraint is not valid then relying upon this in the executor - * may not be accurate, though might be considered a useful estimate for - * planning purposes. - */ - fkoidlist = RelationGetFKeyList(relation); - - foreach(l, fkoidlist) - { - Oid fkoid = lfirst_oid(l); - HeapTuple htup; - Form_pg_constraint constraint; - ForeignKeyOptInfo *info; - Datum adatum; - bool isnull; - ArrayType *arr; - int numkeys; - int i; - - htup = SearchSysCache1(CONSTROID, ObjectIdGetDatum(fkoid)); - if (!HeapTupleIsValid(htup)) /* should not happen */ - elog(ERROR, "cache lookup failed for constraint %u", fkoid); - constraint = (Form_pg_constraint) GETSTRUCT(htup); - - Assert(constraint->contype == CONSTRAINT_FOREIGN); - - info = makeNode(ForeignKeyOptInfo); - - info->conrelid = constraint->conrelid; - info->confrelid = constraint->confrelid; - - /* conkey */ - adatum = SysCacheGetAttr(CONSTROID, htup, - Anum_pg_constraint_conkey, &isnull); - Assert(!isnull); - - arr = DatumGetArrayTypeP(adatum); - numkeys = ARR_DIMS(arr)[0]; - info->conkeys = (int*)palloc(numkeys * sizeof(int)); - for (i = 0; i < numkeys; i++) - info->conkeys[i] = ((int16 *) ARR_DATA_PTR(arr))[i]; - - /* confkey */ - adatum = SysCacheGetAttr(CONSTROID, htup, - Anum_pg_constraint_confkey, &isnull); - Assert(!isnull); - - arr = DatumGetArrayTypeP(adatum); - Assert(numkeys == ARR_DIMS(arr)[0]); - info->confkeys = (int*)palloc(numkeys * sizeof(int)); - for (i = 0; i < numkeys; i++) - info->confkeys[i] = ((int16 *) ARR_DATA_PTR(arr))[i]; - - /* conpfeqop */ - adatum = SysCacheGetAttr(CONSTROID, htup, - Anum_pg_constraint_conpfeqop, &isnull); - Assert(!isnull); - - arr = DatumGetArrayTypeP(adatum); - Assert(numkeys == ARR_DIMS(arr)[0]); - info->conpfeqop = (Oid*)palloc(numkeys * sizeof(Oid)); - for (i = 0; i < numkeys; i++) - info->conpfeqop[i] = ((Oid *) ARR_DATA_PTR(arr))[i]; - - info->nkeys = numkeys; - - ReleaseSysCache(htup); - - fkinfos = lappend(fkinfos, info); - } - - list_free(fkoidlist); - - rel->fkeylist = fkinfos; - /* Grab foreign-table info using the relcache, while we have it */ if (relation->rd_rel->relkind == RELKIND_FOREIGN_TABLE) { diff --git a/src/backend/utils/cache/relcache.c b/src/backend/utils/cache/relcache.c index 79cc3df590..1b7b99548c 100644 --- a/src/backend/utils/cache/relcache.c +++ b/src/backend/utils/cache/relcache.c @@ -2031,7 +2031,6 @@ RelationDestroyRelation(Relation relation, bool remember_tupdesc) FreeTupleDesc(relation->rd_att); } list_free(relation->rd_indexlist); - list_free(relation->rd_fkeylist); bms_free(relation->rd_indexattr); bms_free(relation->rd_keyattr); bms_free(relation->rd_idattr); @@ -3957,79 +3956,6 @@ RelationGetIndexList(Relation relation) return result; } -/* - * RelationGetFKeyList -- get a list of foreign key oids - * - * Use an index scan on pg_constraint to load in FK definitions, - * intended for use within the planner, not for enforcing FKs. - * - * Data is ordered by Oid, though this is not critical at this point - * since we do not lock the referenced relations. - */ -List * -RelationGetFKeyList(Relation relation) -{ - Relation conrel; - SysScanDesc conscan; - ScanKeyData skey; - HeapTuple htup; - List *result; - List *oldlist; - MemoryContext oldcxt; - - /* Quick exit if we already computed the list. */ - if (relation->rd_fkeylist) - return list_copy(relation->rd_fkeylist); - - /* Fast path if no FKs... if it doesn't have a trigger, it can't have a FK */ - if (!relation->rd_rel->relhastriggers) - return NIL; - /* - * We build the list we intend to return (in the caller's context) while - * doing the scan. After successfully completing the scan, we copy that - * list into the relcache entry. This avoids cache-context memory leakage - * if we get some sort of error partway through. - */ - result = NIL; - - /* Prepare to scan pg_constraint for entries having conrelid = this rel. */ - ScanKeyInit(&skey, - Anum_pg_constraint_conrelid, - BTEqualStrategyNumber, F_OIDEQ, - ObjectIdGetDatum(RelationGetRelid(relation))); - - conrel = heap_open(ConstraintRelationId, AccessShareLock); - conscan = systable_beginscan(conrel, ConstraintRelidIndexId, true, - NULL, 1, &skey); - - while (HeapTupleIsValid(htup = systable_getnext(conscan))) - { - Form_pg_constraint constraint = (Form_pg_constraint) GETSTRUCT(htup); - - /* return only foreign keys */ - if (constraint->contype != CONSTRAINT_FOREIGN) - continue; - - /* Add FK's OID to result list in the proper order */ - result = insert_ordered_oid(result, HeapTupleGetOid(htup)); - } - - systable_endscan(conscan); - - heap_close(conrel, AccessShareLock); - - /* Now save a copy of the completed list in the relcache entry. */ - oldcxt = MemoryContextSwitchTo(CacheMemoryContext); - oldlist = relation->rd_fkeylist; - relation->rd_fkeylist = list_copy(result); - MemoryContextSwitchTo(oldcxt); - - /* Don't leak the old list, if there is one */ - list_free(oldlist); - - return result; -} - /* * insert_ordered_oid * Insert a new Oid into a sorted list of Oids, preserving ordering @@ -4994,7 +4920,6 @@ load_relcache_init_file(bool shared) rel->rd_indexattr = NULL; rel->rd_keyattr = NULL; rel->rd_idattr = NULL; - rel->rd_fkeylist = NIL; rel->rd_createSubid = InvalidSubTransactionId; rel->rd_newRelfilenodeSubid = InvalidSubTransactionId; rel->rd_amcache = NULL; diff --git a/src/backend/utils/misc/guc.c b/src/backend/utils/misc/guc.c index e246a9c2f0..edfa39adf4 100644 --- a/src/backend/utils/misc/guc.c +++ b/src/backend/utils/misc/guc.c @@ -877,15 +877,6 @@ static struct config_bool ConfigureNamesBool[] = true, NULL, NULL, NULL }, - { - {"enable_fkey_estimates", PGC_USERSET, QUERY_TUNING_METHOD, - gettext_noop("Enables use of foreign keys for estimating joins."), - NULL - }, - &enable_fkey_estimates, - true, - NULL, NULL, NULL - }, { {"geqo", PGC_USERSET, QUERY_TUNING_GEQO, diff --git a/src/include/nodes/nodes.h b/src/include/nodes/nodes.h index ea65f2e453..5953db45a8 100644 --- a/src/include/nodes/nodes.h +++ b/src/include/nodes/nodes.h @@ -223,7 +223,6 @@ typedef enum NodeTag T_PlannerGlobal, T_RelOptInfo, T_IndexOptInfo, - T_ForeignKeyOptInfo, T_ParamPathInfo, T_Path, T_IndexPath, diff --git a/src/include/nodes/relation.h b/src/include/nodes/relation.h index 45739c3ee7..b1f6cf45f0 100644 --- a/src/include/nodes/relation.h +++ b/src/include/nodes/relation.h @@ -516,7 +516,6 @@ typedef struct RelOptInfo List *lateral_vars; /* LATERAL Vars and PHVs referenced by rel */ Relids lateral_referencers; /* rels that reference me laterally */ List *indexlist; /* list of IndexOptInfo */ - List *fkeylist; /* list of ForeignKeyOptInfo */ BlockNumber pages; /* size estimates derived from pg_class */ double tuples; double allvisfrac; @@ -623,27 +622,6 @@ typedef struct IndexOptInfo void (*amcostestimate) (); /* AM's cost estimator */ } IndexOptInfo; -/* - * ForeignKeyOptInfo - * Per-foreign-key information for planning/optimization - * - * Only includes columns from pg_constraint related to foreign keys. - * - * conkeys[], confkeys[] and conpfeqop[] each have nkeys entries. - */ -typedef struct ForeignKeyOptInfo -{ - NodeTag type; - - Oid conrelid; /* relation constrained by the foreign key */ - Oid confrelid; /* relation referenced by the foreign key */ - - int nkeys; /* number of columns in the foreign key */ - int *conkeys; /* attnums of columns in the constrained table */ - int *confkeys; /* attnums of columns in the referenced table */ - Oid *conpfeqop; /* OIDs of equality operators used by the FK */ - -} ForeignKeyOptInfo; /* * EquivalenceClasses diff --git a/src/include/optimizer/cost.h b/src/include/optimizer/cost.h index 58ac1638ec..d4adca6836 100644 --- a/src/include/optimizer/cost.h +++ b/src/include/optimizer/cost.h @@ -66,7 +66,6 @@ extern bool enable_nestloop; extern bool enable_material; extern bool enable_mergejoin; extern bool enable_hashjoin; -extern bool enable_fkey_estimates; extern int constraint_exclusion; extern double clamp_row_est(double nrows); diff --git a/src/include/optimizer/paths.h b/src/include/optimizer/paths.h index e0ac4515c9..f3b25e2419 100644 --- a/src/include/optimizer/paths.h +++ b/src/include/optimizer/paths.h @@ -76,8 +76,6 @@ extern Expr *adjust_rowcompare_for_index(RowCompareExpr *clause, int indexcol, List **indexcolnos, bool *var_on_left_p); -extern bool has_matching_fkey(RelOptInfo *rel, RelOptInfo *frel, List *clauses, - bool reverse); /* * tidpath.h diff --git a/src/include/utils/rel.h b/src/include/utils/rel.h index a0ba417764..5d354c0f67 100644 --- a/src/include/utils/rel.h +++ b/src/include/utils/rel.h @@ -95,9 +95,6 @@ typedef struct RelationData Oid rd_oidindex; /* OID of unique index on OID, if any */ Oid rd_replidindex; /* OID of replica identity index, if any */ - /* data managed by RelationGetFKList: */ - List *rd_fkeylist; /* OIDs of foreign keys */ - /* data managed by RelationGetIndexAttrBitmap: */ Bitmapset *rd_indexattr; /* identifies columns used in indexes */ Bitmapset *rd_keyattr; /* cols that can be ref'd by foreign keys */ diff --git a/src/include/utils/relcache.h b/src/include/utils/relcache.h index 7f07c26914..1b4830462d 100644 --- a/src/include/utils/relcache.h +++ b/src/include/utils/relcache.h @@ -38,7 +38,6 @@ extern void RelationClose(Relation relation); * Routines to compute/retrieve additional cached information */ extern List *RelationGetIndexList(Relation relation); -extern List *RelationGetFKeyList(Relation relation); extern Oid RelationGetOidIndex(Relation relation); extern Oid RelationGetReplicaIndex(Relation relation); extern List *RelationGetIndexExpressions(Relation relation); diff --git a/src/test/regress/expected/rangefuncs.out b/src/test/regress/expected/rangefuncs.out index abe0dc983e..00ef421054 100644 --- a/src/test/regress/expected/rangefuncs.out +++ b/src/test/regress/expected/rangefuncs.out @@ -1,19 +1,18 @@ SELECT name, setting FROM pg_settings WHERE name LIKE 'enable%'; - name | setting ------------------------+--------- - enable_bitmapscan | on - enable_fkey_estimates | on - enable_hashagg | on - enable_hashjoin | on - enable_indexonlyscan | on - enable_indexscan | on - enable_material | on - enable_mergejoin | on - enable_nestloop | on - enable_seqscan | on - enable_sort | on - enable_tidscan | on -(12 rows) + name | setting +----------------------+--------- + enable_bitmapscan | on + enable_hashagg | on + enable_hashjoin | on + enable_indexonlyscan | on + enable_indexscan | on + enable_material | on + enable_mergejoin | on + enable_nestloop | on + enable_seqscan | on + enable_sort | on + enable_tidscan | on +(11 rows) CREATE TABLE foo2(fooid int, f2 int); INSERT INTO foo2 VALUES(1, 11);