diff options
Diffstat (limited to 'src/backend/utils')
-rw-r--r-- | src/backend/utils/adt/pseudotypes.c | 27 | ||||
-rw-r--r-- | src/backend/utils/adt/ruleutils.c | 8 | ||||
-rw-r--r-- | src/backend/utils/adt/selfuncs.c | 98 | ||||
-rw-r--r-- | src/backend/utils/cache/lsyscache.c | 1 | ||||
-rw-r--r-- | src/backend/utils/cache/relcache.c | 86 | ||||
-rw-r--r-- | src/backend/utils/cache/syscache.c | 1 | ||||
-rw-r--r-- | src/backend/utils/cache/typcache.c | 1 | ||||
-rw-r--r-- | src/backend/utils/sort/sortsupport.c | 1 | ||||
-rw-r--r-- | src/backend/utils/sort/tuplesort.c | 1 |
9 files changed, 119 insertions, 105 deletions
diff --git a/src/backend/utils/adt/pseudotypes.c b/src/backend/utils/adt/pseudotypes.c index f309ad3cbee..dd447cf4e86 100644 --- a/src/backend/utils/adt/pseudotypes.c +++ b/src/backend/utils/adt/pseudotypes.c @@ -374,6 +374,33 @@ fdw_handler_out(PG_FUNCTION_ARGS) /* + * index_am_handler_in - input routine for pseudo-type INDEX_AM_HANDLER. + */ +Datum +index_am_handler_in(PG_FUNCTION_ARGS) +{ + ereport(ERROR, + (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), + errmsg("cannot accept a value of type index_am_handler"))); + + PG_RETURN_VOID(); /* keep compiler quiet */ +} + +/* + * index_am_handler_out - output routine for pseudo-type INDEX_AM_HANDLER. + */ +Datum +index_am_handler_out(PG_FUNCTION_ARGS) +{ + ereport(ERROR, + (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), + errmsg("cannot display a value of type index_am_handler"))); + + PG_RETURN_VOID(); /* keep compiler quiet */ +} + + +/* * tsm_handler_in - input routine for pseudo-type TSM_HANDLER. */ Datum diff --git a/src/backend/utils/adt/ruleutils.c b/src/backend/utils/adt/ruleutils.c index 023d651899a..4efd2988e79 100644 --- a/src/backend/utils/adt/ruleutils.c +++ b/src/backend/utils/adt/ruleutils.c @@ -19,11 +19,13 @@ #include <unistd.h> #include <fcntl.h> +#include "access/amapi.h" #include "access/htup_details.h" #include "access/sysattr.h" #include "catalog/dependency.h" #include "catalog/indexing.h" #include "catalog/pg_aggregate.h" +#include "catalog/pg_am.h" #include "catalog/pg_authid.h" #include "catalog/pg_collation.h" #include "catalog/pg_constraint.h" @@ -1019,6 +1021,7 @@ pg_get_indexdef_worker(Oid indexrelid, int colno, Form_pg_index idxrec; Form_pg_class idxrelrec; Form_pg_am amrec; + IndexAmRoutine *amroutine; List *indexprs; ListCell *indexpr_item; List *context; @@ -1079,6 +1082,9 @@ pg_get_indexdef_worker(Oid indexrelid, int colno, idxrelrec->relam); amrec = (Form_pg_am) GETSTRUCT(ht_am); + /* Fetch the index AM's API struct */ + amroutine = GetIndexAmRoutine(amrec->amhandler); + /* * Get the index expressions, if any. (NOTE: we do not use the relcache * versions of the expressions and predicate, because we want to display @@ -1190,7 +1196,7 @@ pg_get_indexdef_worker(Oid indexrelid, int colno, get_opclass_name(indclass->values[keyno], keycoltype, &buf); /* Add options if relevant */ - if (amrec->amcanorder) + if (amroutine->amcanorder) { /* if it supports sort ordering, report DESC and NULLS opts */ if (opt & INDOPTION_DESC) diff --git a/src/backend/utils/adt/selfuncs.c b/src/backend/utils/adt/selfuncs.c index ebb03aae475..46c95b089ed 100644 --- a/src/backend/utils/adt/selfuncs.c +++ b/src/backend/utils/adt/selfuncs.c @@ -7,8 +7,8 @@ * Selectivity routines are registered in the pg_operator catalog * in the "oprrest" and "oprjoin" attributes. * - * Index cost functions are registered in the pg_am catalog - * in the "amcostestimate" attribute. + * Index cost functions are located via the index AM's API struct, + * which is obtained from the handler function registered in pg_am. * * Portions Copyright (c) 1996-2016, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California @@ -104,6 +104,7 @@ #include "access/htup_details.h" #include "access/sysattr.h" #include "catalog/index.h" +#include "catalog/pg_am.h" #include "catalog/pg_collation.h" #include "catalog/pg_operator.h" #include "catalog/pg_opfamily.h" @@ -129,6 +130,7 @@ #include "utils/date.h" #include "utils/datum.h" #include "utils/fmgroids.h" +#include "utils/index_selfuncs.h" #include "utils/lsyscache.h" #include "utils/nabstime.h" #include "utils/pg_locale.h" @@ -6443,16 +6445,11 @@ add_predicate_to_quals(IndexOptInfo *index, List *indexQuals) } -Datum -btcostestimate(PG_FUNCTION_ARGS) +void +btcostestimate(PlannerInfo *root, IndexPath *path, double loop_count, + Cost *indexStartupCost, Cost *indexTotalCost, + Selectivity *indexSelectivity, double *indexCorrelation) { - PlannerInfo *root = (PlannerInfo *) PG_GETARG_POINTER(0); - IndexPath *path = (IndexPath *) PG_GETARG_POINTER(1); - double loop_count = PG_GETARG_FLOAT8(2); - Cost *indexStartupCost = (Cost *) PG_GETARG_POINTER(3); - Cost *indexTotalCost = (Cost *) PG_GETARG_POINTER(4); - Selectivity *indexSelectivity = (Selectivity *) PG_GETARG_POINTER(5); - double *indexCorrelation = (double *) PG_GETARG_POINTER(6); IndexOptInfo *index = path->indexinfo; List *qinfos; GenericCosts costs; @@ -6741,20 +6738,13 @@ btcostestimate(PG_FUNCTION_ARGS) *indexTotalCost = costs.indexTotalCost; *indexSelectivity = costs.indexSelectivity; *indexCorrelation = costs.indexCorrelation; - - PG_RETURN_VOID(); } -Datum -hashcostestimate(PG_FUNCTION_ARGS) +void +hashcostestimate(PlannerInfo *root, IndexPath *path, double loop_count, + Cost *indexStartupCost, Cost *indexTotalCost, + Selectivity *indexSelectivity, double *indexCorrelation) { - PlannerInfo *root = (PlannerInfo *) PG_GETARG_POINTER(0); - IndexPath *path = (IndexPath *) PG_GETARG_POINTER(1); - double loop_count = PG_GETARG_FLOAT8(2); - Cost *indexStartupCost = (Cost *) PG_GETARG_POINTER(3); - Cost *indexTotalCost = (Cost *) PG_GETARG_POINTER(4); - Selectivity *indexSelectivity = (Selectivity *) PG_GETARG_POINTER(5); - double *indexCorrelation = (double *) PG_GETARG_POINTER(6); List *qinfos; GenericCosts costs; @@ -6794,20 +6784,13 @@ hashcostestimate(PG_FUNCTION_ARGS) *indexTotalCost = costs.indexTotalCost; *indexSelectivity = costs.indexSelectivity; *indexCorrelation = costs.indexCorrelation; - - PG_RETURN_VOID(); } -Datum -gistcostestimate(PG_FUNCTION_ARGS) +void +gistcostestimate(PlannerInfo *root, IndexPath *path, double loop_count, + Cost *indexStartupCost, Cost *indexTotalCost, + Selectivity *indexSelectivity, double *indexCorrelation) { - PlannerInfo *root = (PlannerInfo *) PG_GETARG_POINTER(0); - IndexPath *path = (IndexPath *) PG_GETARG_POINTER(1); - double loop_count = PG_GETARG_FLOAT8(2); - Cost *indexStartupCost = (Cost *) PG_GETARG_POINTER(3); - Cost *indexTotalCost = (Cost *) PG_GETARG_POINTER(4); - Selectivity *indexSelectivity = (Selectivity *) PG_GETARG_POINTER(5); - double *indexCorrelation = (double *) PG_GETARG_POINTER(6); IndexOptInfo *index = path->indexinfo; List *qinfos; GenericCosts costs; @@ -6860,20 +6843,13 @@ gistcostestimate(PG_FUNCTION_ARGS) *indexTotalCost = costs.indexTotalCost; *indexSelectivity = costs.indexSelectivity; *indexCorrelation = costs.indexCorrelation; - - PG_RETURN_VOID(); } -Datum -spgcostestimate(PG_FUNCTION_ARGS) +void +spgcostestimate(PlannerInfo *root, IndexPath *path, double loop_count, + Cost *indexStartupCost, Cost *indexTotalCost, + Selectivity *indexSelectivity, double *indexCorrelation) { - PlannerInfo *root = (PlannerInfo *) PG_GETARG_POINTER(0); - IndexPath *path = (IndexPath *) PG_GETARG_POINTER(1); - double loop_count = PG_GETARG_FLOAT8(2); - Cost *indexStartupCost = (Cost *) PG_GETARG_POINTER(3); - Cost *indexTotalCost = (Cost *) PG_GETARG_POINTER(4); - Selectivity *indexSelectivity = (Selectivity *) PG_GETARG_POINTER(5); - double *indexCorrelation = (double *) PG_GETARG_POINTER(6); IndexOptInfo *index = path->indexinfo; List *qinfos; GenericCosts costs; @@ -6926,8 +6902,6 @@ spgcostestimate(PG_FUNCTION_ARGS) *indexTotalCost = costs.indexTotalCost; *indexSelectivity = costs.indexSelectivity; *indexCorrelation = costs.indexCorrelation; - - PG_RETURN_VOID(); } @@ -7222,16 +7196,11 @@ gincost_scalararrayopexpr(PlannerInfo *root, /* * GIN has search behavior completely different from other index types */ -Datum -gincostestimate(PG_FUNCTION_ARGS) +void +gincostestimate(PlannerInfo *root, IndexPath *path, double loop_count, + Cost *indexStartupCost, Cost *indexTotalCost, + Selectivity *indexSelectivity, double *indexCorrelation) { - PlannerInfo *root = (PlannerInfo *) PG_GETARG_POINTER(0); - IndexPath *path = (IndexPath *) PG_GETARG_POINTER(1); - double loop_count = PG_GETARG_FLOAT8(2); - Cost *indexStartupCost = (Cost *) PG_GETARG_POINTER(3); - Cost *indexTotalCost = (Cost *) PG_GETARG_POINTER(4); - Selectivity *indexSelectivity = (Selectivity *) PG_GETARG_POINTER(5); - double *indexCorrelation = (double *) PG_GETARG_POINTER(6); IndexOptInfo *index = path->indexinfo; List *indexQuals = path->indexquals; List *indexOrderBys = path->indexorderbys; @@ -7418,7 +7387,7 @@ gincostestimate(PG_FUNCTION_ARGS) *indexStartupCost = 0; *indexTotalCost = 0; *indexSelectivity = 0; - PG_RETURN_VOID(); + return; } if (counts.haveFullScan || indexQuals == NIL) @@ -7545,23 +7514,16 @@ gincostestimate(PG_FUNCTION_ARGS) *indexStartupCost += qual_arg_cost; *indexTotalCost += qual_arg_cost; *indexTotalCost += (numTuples * *indexSelectivity) * (cpu_index_tuple_cost + qual_op_cost); - - PG_RETURN_VOID(); } /* * BRIN has search behavior completely different from other index types */ -Datum -brincostestimate(PG_FUNCTION_ARGS) +void +brincostestimate(PlannerInfo *root, IndexPath *path, double loop_count, + Cost *indexStartupCost, Cost *indexTotalCost, + Selectivity *indexSelectivity, double *indexCorrelation) { - PlannerInfo *root = (PlannerInfo *) PG_GETARG_POINTER(0); - IndexPath *path = (IndexPath *) PG_GETARG_POINTER(1); - double loop_count = PG_GETARG_FLOAT8(2); - Cost *indexStartupCost = (Cost *) PG_GETARG_POINTER(3); - Cost *indexTotalCost = (Cost *) PG_GETARG_POINTER(4); - Selectivity *indexSelectivity = (Selectivity *) PG_GETARG_POINTER(5); - double *indexCorrelation = (double *) PG_GETARG_POINTER(6); IndexOptInfo *index = path->indexinfo; List *indexQuals = path->indexquals; List *indexOrderBys = path->indexorderbys; @@ -7614,6 +7576,4 @@ brincostestimate(PG_FUNCTION_ARGS) *indexTotalCost += (numTuples * *indexSelectivity) * (cpu_index_tuple_cost + qual_op_cost); /* XXX what about pages_per_range? */ - - PG_RETURN_VOID(); } diff --git a/src/backend/utils/cache/lsyscache.c b/src/backend/utils/cache/lsyscache.c index 5c9333c296c..a180d2b507a 100644 --- a/src/backend/utils/cache/lsyscache.c +++ b/src/backend/utils/cache/lsyscache.c @@ -20,6 +20,7 @@ #include "access/nbtree.h" #include "bootstrap/bootstrap.h" #include "catalog/namespace.h" +#include "catalog/pg_am.h" #include "catalog/pg_amop.h" #include "catalog/pg_amproc.h" #include "catalog/pg_collation.h" diff --git a/src/backend/utils/cache/relcache.c b/src/backend/utils/cache/relcache.c index fc5b9d99340..130c06d81c8 100644 --- a/src/backend/utils/cache/relcache.c +++ b/src/backend/utils/cache/relcache.c @@ -34,13 +34,13 @@ #include "access/multixact.h" #include "access/reloptions.h" #include "access/sysattr.h" -#include "access/transam.h" #include "access/xact.h" #include "access/xlog.h" #include "catalog/catalog.h" #include "catalog/index.h" #include "catalog/indexing.h" #include "catalog/namespace.h" +#include "catalog/pg_am.h" #include "catalog/pg_amproc.h" #include "catalog/pg_attrdef.h" #include "catalog/pg_authid.h" @@ -267,6 +267,7 @@ static void AttrDefaultFetch(Relation relation); static void CheckConstraintFetch(Relation relation); static int CheckConstraintCmp(const void *a, const void *b); static List *insert_ordered_oid(List *list, Oid datum); +static void InitIndexAmRoutine(Relation relation); static void IndexSupportInitialize(oidvector *indclass, RegProcedure *indexSupport, Oid *opFamily, @@ -417,7 +418,7 @@ AllocateRelationDesc(Form_pg_class relp) * * tuple is the real pg_class tuple (not rd_rel!) for relation * - * Note: rd_rel and (if an index) rd_am must be valid already + * Note: rd_rel and (if an index) rd_amroutine must be valid already */ static void RelationParseRelOptions(Relation relation, HeapTuple tuple) @@ -447,7 +448,7 @@ RelationParseRelOptions(Relation relation, HeapTuple tuple) options = extractRelOptions(tuple, GetPgClassDescriptor(), relation->rd_rel->relkind == RELKIND_INDEX ? - relation->rd_am->amoptions : InvalidOid); + relation->rd_amroutine->amoptions : NULL); /* * Copy parsed data into CacheMemoryContext. To guard against the @@ -1162,6 +1163,32 @@ RelationInitPhysicalAddr(Relation relation) } /* + * Fill in the IndexAmRoutine for an index relation. + * + * relation's rd_amhandler and rd_indexcxt must be valid already. + */ +static void +InitIndexAmRoutine(Relation relation) +{ + IndexAmRoutine *cached, + *tmp; + + /* + * Call the amhandler in current, short-lived memory context, just in case + * it leaks anything (it probably won't, but let's be paranoid). + */ + tmp = GetIndexAmRoutine(relation->rd_amhandler); + + /* OK, now transfer the data into relation's rd_indexcxt. */ + cached = (IndexAmRoutine *) MemoryContextAlloc(relation->rd_indexcxt, + sizeof(IndexAmRoutine)); + memcpy(cached, tmp, sizeof(IndexAmRoutine)); + relation->rd_amroutine = cached; + + pfree(tmp); +} + +/* * Initialize index-access-method support data for an index relation */ void @@ -1198,22 +1225,20 @@ RelationInitIndexAccessInfo(Relation relation) ReleaseSysCache(tuple); /* - * Make a copy of the pg_am entry for the index's access method + * Look up the index's access method, save the OID of its handler function */ tuple = SearchSysCache1(AMOID, ObjectIdGetDatum(relation->rd_rel->relam)); if (!HeapTupleIsValid(tuple)) elog(ERROR, "cache lookup failed for access method %u", relation->rd_rel->relam); - aform = (Form_pg_am) MemoryContextAlloc(CacheMemoryContext, sizeof *aform); - memcpy(aform, GETSTRUCT(tuple), sizeof *aform); + aform = (Form_pg_am) GETSTRUCT(tuple); + relation->rd_amhandler = aform->amhandler; ReleaseSysCache(tuple); - relation->rd_am = aform; natts = relation->rd_rel->relnatts; if (natts != relation->rd_index->indnatts) elog(ERROR, "relnatts disagrees with indnatts for index %u", RelationGetRelid(relation)); - amsupport = aform->amsupport; /* * Make the private context to hold index access info. The reason we need @@ -1231,16 +1256,19 @@ RelationInitIndexAccessInfo(Relation relation) relation->rd_indexcxt = indexcxt; /* - * Allocate arrays to hold data + * Now we can fetch the index AM's API struct */ - relation->rd_aminfo = (RelationAmInfo *) - MemoryContextAllocZero(indexcxt, sizeof(RelationAmInfo)); + InitIndexAmRoutine(relation); + /* + * Allocate arrays to hold data + */ relation->rd_opfamily = (Oid *) MemoryContextAllocZero(indexcxt, natts * sizeof(Oid)); relation->rd_opcintype = (Oid *) MemoryContextAllocZero(indexcxt, natts * sizeof(Oid)); + amsupport = relation->rd_amroutine->amsupport; if (amsupport > 0) { int nsupport = natts * amsupport; @@ -2011,8 +2039,6 @@ RelationDestroyRelation(Relation relation, bool remember_tupdesc) pfree(relation->rd_options); if (relation->rd_indextuple) pfree(relation->rd_indextuple); - if (relation->rd_am) - pfree(relation->rd_am); if (relation->rd_indexcxt) MemoryContextDelete(relation->rd_indexcxt); if (relation->rd_rulescxt) @@ -4746,7 +4772,6 @@ load_relcache_init_file(bool shared) /* If it's an index, there's more to do */ if (rel->rd_rel->relkind == RELKIND_INDEX) { - Form_pg_am am; MemoryContext indexcxt; Oid *opfamily; Oid *opcintype; @@ -4771,15 +4796,6 @@ load_relcache_init_file(bool shared) rel->rd_indextuple->t_data = (HeapTupleHeader) ((char *) rel->rd_indextuple + HEAPTUPLESIZE); rel->rd_index = (Form_pg_index) GETSTRUCT(rel->rd_indextuple); - /* next, read the access method tuple form */ - if (fread(&len, 1, sizeof(len), fp) != sizeof(len)) - goto read_failed; - - am = (Form_pg_am) palloc(len); - if (fread(am, 1, len, fp) != len) - goto read_failed; - rel->rd_am = am; - /* * prepare index info context --- parameters should match * RelationInitIndexAccessInfo @@ -4791,6 +4807,14 @@ load_relcache_init_file(bool shared) ALLOCSET_SMALL_MAXSIZE); rel->rd_indexcxt = indexcxt; + /* + * Now we can fetch the index AM's API struct. (We can't store + * that in the init file, since it contains function pointers that + * might vary across server executions. Fortunately, it should be + * safe to call the amhandler even while bootstrapping indexes.) + */ + InitIndexAmRoutine(rel); + /* next, read the vector of opfamily OIDs */ if (fread(&len, 1, sizeof(len), fp) != sizeof(len)) goto read_failed; @@ -4840,10 +4864,8 @@ load_relcache_init_file(bool shared) rel->rd_indoption = indoption; - /* set up zeroed fmgr-info vectors */ - rel->rd_aminfo = (RelationAmInfo *) - MemoryContextAllocZero(indexcxt, sizeof(RelationAmInfo)); - nsupport = relform->relnatts * am->amsupport; + /* set up zeroed fmgr-info vector */ + nsupport = relform->relnatts * rel->rd_amroutine->amsupport; rel->rd_supportinfo = (FmgrInfo *) MemoryContextAllocZero(indexcxt, nsupport * sizeof(FmgrInfo)); } @@ -4855,9 +4877,8 @@ load_relcache_init_file(bool shared) Assert(rel->rd_index == NULL); Assert(rel->rd_indextuple == NULL); - Assert(rel->rd_am == NULL); Assert(rel->rd_indexcxt == NULL); - Assert(rel->rd_aminfo == NULL); + Assert(rel->rd_amroutine == NULL); Assert(rel->rd_opfamily == NULL); Assert(rel->rd_opcintype == NULL); Assert(rel->rd_support == NULL); @@ -5101,17 +5122,12 @@ write_relcache_init_file(bool shared) /* If it's an index, there's more to do */ if (rel->rd_rel->relkind == RELKIND_INDEX) { - Form_pg_am am = rel->rd_am; - /* write the pg_index tuple */ /* we assume this was created by heap_copytuple! */ write_item(rel->rd_indextuple, HEAPTUPLESIZE + rel->rd_indextuple->t_len, fp); - /* next, write the access method tuple form */ - write_item(am, sizeof(FormData_pg_am), fp); - /* next, write the vector of opfamily OIDs */ write_item(rel->rd_opfamily, relform->relnatts * sizeof(Oid), @@ -5124,7 +5140,7 @@ write_relcache_init_file(bool shared) /* next, write the vector of support procedure OIDs */ write_item(rel->rd_support, - relform->relnatts * (am->amsupport * sizeof(RegProcedure)), + relform->relnatts * (rel->rd_amroutine->amsupport * sizeof(RegProcedure)), fp); /* next, write the vector of collation OIDs */ diff --git a/src/backend/utils/cache/syscache.c b/src/backend/utils/cache/syscache.c index 6eb2ac69a13..65ffe844093 100644 --- a/src/backend/utils/cache/syscache.c +++ b/src/backend/utils/cache/syscache.c @@ -24,6 +24,7 @@ #include "access/sysattr.h" #include "catalog/indexing.h" #include "catalog/pg_aggregate.h" +#include "catalog/pg_am.h" #include "catalog/pg_amop.h" #include "catalog/pg_amproc.h" #include "catalog/pg_auth_members.h" diff --git a/src/backend/utils/cache/typcache.c b/src/backend/utils/cache/typcache.c index 4ad787bfa45..ea6f787a527 100644 --- a/src/backend/utils/cache/typcache.c +++ b/src/backend/utils/cache/typcache.c @@ -47,6 +47,7 @@ #include "access/htup_details.h" #include "access/nbtree.h" #include "catalog/indexing.h" +#include "catalog/pg_am.h" #include "catalog/pg_constraint.h" #include "catalog/pg_enum.h" #include "catalog/pg_operator.h" diff --git a/src/backend/utils/sort/sortsupport.c b/src/backend/utils/sort/sortsupport.c index e193372d2e5..e9eeb18b7ec 100644 --- a/src/backend/utils/sort/sortsupport.c +++ b/src/backend/utils/sort/sortsupport.c @@ -16,6 +16,7 @@ #include "postgres.h" #include "access/nbtree.h" +#include "catalog/pg_am.h" #include "fmgr.h" #include "utils/lsyscache.h" #include "utils/rel.h" diff --git a/src/backend/utils/sort/tuplesort.c b/src/backend/utils/sort/tuplesort.c index 3d5b8ed9070..a30e1707a79 100644 --- a/src/backend/utils/sort/tuplesort.c +++ b/src/backend/utils/sort/tuplesort.c @@ -103,6 +103,7 @@ #include "access/htup_details.h" #include "access/nbtree.h" #include "catalog/index.h" +#include "catalog/pg_am.h" #include "commands/tablespace.h" #include "executor/executor.h" #include "miscadmin.h" |