diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/backend/access/index/indexam.c | 24 | ||||
-rw-r--r-- | src/backend/access/nbtree/nbtsearch.c | 12 | ||||
-rw-r--r-- | src/backend/access/nbtree/nbtutils.c | 17 | ||||
-rw-r--r-- | src/backend/optimizer/path/indxpath.c | 53 | ||||
-rw-r--r-- | src/backend/optimizer/util/plancat.c | 5 | ||||
-rw-r--r-- | src/backend/utils/adt/selfuncs.c | 122 | ||||
-rw-r--r-- | src/include/access/genam.h | 3 | ||||
-rw-r--r-- | src/include/catalog/catversion.h | 4 | ||||
-rw-r--r-- | src/include/catalog/pg_am.h | 42 | ||||
-rw-r--r-- | src/include/nodes/relation.h | 3 |
10 files changed, 181 insertions, 104 deletions
diff --git a/src/backend/access/index/indexam.c b/src/backend/access/index/indexam.c index 81c2114976e..a445efc7154 100644 --- a/src/backend/access/index/indexam.c +++ b/src/backend/access/index/indexam.c @@ -8,7 +8,7 @@ * * * IDENTIFICATION - * $PostgreSQL: pgsql/src/backend/access/index/indexam.c,v 1.82 2005/05/27 23:31:20 tgl Exp $ + * $PostgreSQL: pgsql/src/backend/access/index/indexam.c,v 1.83 2005/06/13 23:14:48 tgl Exp $ * * INTERFACE ROUTINES * index_open - open an index relation by relation OID @@ -25,7 +25,6 @@ * index_getmulti - get multiple tuples from a scan * index_bulk_delete - bulk deletion of index tuples * index_vacuum_cleanup - post-deletion cleanup of an index - * index_cost_estimator - fetch amcostestimate procedure OID * index_getprocid - get a support procedure OID * index_getprocinfo - get a support procedure's lookup info * @@ -719,27 +718,6 @@ index_vacuum_cleanup(Relation indexRelation, } /* ---------------- - * index_cost_estimator - * - * Fetch the amcostestimate procedure OID for an index. - * - * We could combine fetching and calling the procedure, - * as index_insert does for example; but that would require - * importing a bunch of planner/optimizer stuff into this file. - * ---------------- - */ -RegProcedure -index_cost_estimator(Relation indexRelation) -{ - FmgrInfo *procedure; - - RELATION_CHECKS; - GET_REL_PROCEDURE(amcostestimate); - - return procedure->fn_oid; -} - -/* ---------------- * index_getprocid * * Some indexed access methods may require support routines that are diff --git a/src/backend/access/nbtree/nbtsearch.c b/src/backend/access/nbtree/nbtsearch.c index 17b3b0dcddf..824d5ea70e6 100644 --- a/src/backend/access/nbtree/nbtsearch.c +++ b/src/backend/access/nbtree/nbtsearch.c @@ -8,7 +8,7 @@ * Portions Copyright (c) 1994, Regents of the University of California * * IDENTIFICATION - * $PostgreSQL: pgsql/src/backend/access/nbtree/nbtsearch.c,v 1.91 2005/03/29 00:16:52 tgl Exp $ + * $PostgreSQL: pgsql/src/backend/access/nbtree/nbtsearch.c,v 1.92 2005/06/13 23:14:48 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -594,15 +594,17 @@ _bt_first(IndexScanDesc scan, ScanDirection dir) } /* - * Done if that was the last attribute. + * Done if that was the last attribute, or if next key + * is not in sequence (implying no boundary key is available + * for the next attribute). */ - if (i >= so->numberOfKeys) + if (i >= so->numberOfKeys || + cur->sk_attno != curattr + 1) break; /* - * Reset for next attr, which should be in sequence. + * Reset for next attr. */ - Assert(cur->sk_attno == curattr + 1); curattr = cur->sk_attno; chosen = NULL; } diff --git a/src/backend/access/nbtree/nbtutils.c b/src/backend/access/nbtree/nbtutils.c index 96a3f05a5d6..9a5f8d7ac90 100644 --- a/src/backend/access/nbtree/nbtutils.c +++ b/src/backend/access/nbtree/nbtutils.c @@ -8,7 +8,7 @@ * * * IDENTIFICATION - * $PostgreSQL: pgsql/src/backend/access/nbtree/nbtutils.c,v 1.62 2004/12/31 21:59:22 pgsql Exp $ + * $PostgreSQL: pgsql/src/backend/access/nbtree/nbtutils.c,v 1.63 2005/06/13 23:14:48 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -190,7 +190,9 @@ _bt_formitem(IndexTuple itup) * matched to continue the scan. In general, numberOfRequiredKeys is equal * to the number of keys for leading attributes with "=" keys, plus the * key(s) for the first non "=" attribute, which can be seen to be correct - * by considering the above example. + * by considering the above example. Note in particular that if there are no + * keys for a given attribute, the keys for subsequent attributes can never + * be required; for instance "WHERE y = 4" requires a full-index scan. * * If possible, redundant keys are eliminated: we keep only the tightest * >/>= bound and the tightest </<= bound, and if there's an = key then @@ -248,8 +250,8 @@ _bt_preprocess_keys(IndexScanDesc scan) outkeys = so->keyData; cur = &inkeys[0]; /* we check that input keys are correctly ordered */ - if (cur->sk_attno != 1) - elog(ERROR, "key(s) for attribute 1 missed"); + if (cur->sk_attno < 1) + elog(ERROR, "btree index keys must be ordered by attribute"); /* We can short-circuit most of the work if there's just one key */ if (numberOfKeys == 1) @@ -270,7 +272,8 @@ _bt_preprocess_keys(IndexScanDesc scan) } memcpy(outkeys, inkeys, sizeof(ScanKeyData)); so->numberOfKeys = 1; - so->numberOfRequiredKeys = 1; + if (cur->sk_attno == 1) + so->numberOfRequiredKeys = 1; return; } @@ -324,8 +327,8 @@ _bt_preprocess_keys(IndexScanDesc scan) int priorNumberOfEqualCols = numberOfEqualCols; /* check input keys are correctly ordered */ - if (i < numberOfKeys && cur->sk_attno != attno + 1) - elog(ERROR, "key(s) for attribute %d missed", attno + 1); + if (i < numberOfKeys && cur->sk_attno < attno) + elog(ERROR, "btree index keys must be ordered by attribute"); /* * If = has been specified, no other key will be used. In case diff --git a/src/backend/optimizer/path/indxpath.c b/src/backend/optimizer/path/indxpath.c index 9c1874d5907..525304f5cb3 100644 --- a/src/backend/optimizer/path/indxpath.c +++ b/src/backend/optimizer/path/indxpath.c @@ -9,7 +9,7 @@ * * * IDENTIFICATION - * $PostgreSQL: pgsql/src/backend/optimizer/path/indxpath.c,v 1.183 2005/06/10 22:25:36 tgl Exp $ + * $PostgreSQL: pgsql/src/backend/optimizer/path/indxpath.c,v 1.184 2005/06/13 23:14:48 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -87,7 +87,8 @@ static Const *string_to_const(const char *str, Oid datatype); * * To be considered for an index scan, an index must match one or more * restriction clauses or join clauses from the query's qual condition, - * or match the query's ORDER BY condition. + * or match the query's ORDER BY condition, or have a predicate that + * matches the query's qual condition. * * There are two basic kinds of index scans. A "plain" index scan uses * only restriction clauses (possibly none at all) in its indexqual, @@ -210,6 +211,7 @@ create_index_paths(PlannerInfo *root, RelOptInfo *rel) * 'clauses' is the current list of clauses (RestrictInfo nodes) * 'outer_clauses' is the list of additional upper-level clauses * 'istoplevel' is true if clauses are the rel's top-level restriction list + * (outer_clauses must be NIL when this is true) * 'isjoininner' is true if forming an inner indexscan (so some of the * given clauses are join clauses) * 'outer_relids' identifies the outer side of the join (pass NULL @@ -295,13 +297,12 @@ find_usable_indexes(PlannerInfo *root, RelOptInfo *rel, * selectivity of the predicate might alone make the index useful. * * Note: not all index AMs support scans with no restriction clauses. - * We assume here that the AM does so if and only if it supports - * ordered scans. (It would probably be better if there were a - * specific flag for this in pg_am, but there's not.) + * We can't generate a scan over an index with amoptionalkey = false + * unless there's at least one restriction clause. */ if (restrictclauses != NIL || - useful_pathkeys != NIL || - (index->indpred != NIL && index_is_ordered)) + (index->amoptionalkey && + (useful_pathkeys != NIL || index->indpred != NIL))) { ipath = create_index_path(root, index, restrictclauses, @@ -608,6 +609,11 @@ bitmap_and_cost_est(PlannerInfo *root, RelOptInfo *rel, List *paths) * group_clauses_by_indexkey * Find restriction clauses that can be used with an index. * + * Returns a list of sublists of RestrictInfo nodes for clauses that can be + * used with this index. Each sublist contains clauses that can be used + * with one index key (in no particular order); the top list is ordered by + * index key. (This is depended on by expand_indexqual_conditions().) + * * As explained in the comments for find_usable_indexes(), we can use * clauses from either of the given lists, but the result is required to * use at least one clause from the "current clauses" list. We return @@ -616,18 +622,14 @@ bitmap_and_cost_est(PlannerInfo *root, RelOptInfo *rel, List *paths) * outer_relids determines what Vars will be allowed on the other side * of a possible index qual; see match_clause_to_indexcol(). * - * Returns a list of sublists of RestrictInfo nodes for clauses that can be - * used with this index. Each sublist contains clauses that can be used - * with one index key (in no particular order); the top list is ordered by - * index key. (This is depended on by expand_indexqual_conditions().) + * If the index has amoptionalkey = false, we give up and return NIL when + * there are no restriction clauses matching the first index key. Otherwise, + * we return NIL if there are no restriction clauses matching any index key. + * A non-NIL result will have one (possibly empty) sublist for each index key. * - * Note that in a multi-key index, we stop if we find a key that cannot be - * used with any clause. For example, given an index on (A,B,C), we might - * return ((C1 C2) (C3 C4)) if we find that clauses C1 and C2 use column A, - * clauses C3 and C4 use column B, and no clauses use column C. But if - * no clauses match B we will return ((C1 C2)), whether or not there are - * clauses matching column C, because the executor couldn't use them anyway. - * Therefore, there are no empty sublists in the result. + * Example: given an index on (A,B,C), we would return ((C1 C2) () (C3 C4)) + * if we find that clauses C1 and C2 use column A, clauses C3 and C4 use + * column C, and no clauses use column B. */ List * group_clauses_by_indexkey(IndexOptInfo *index, @@ -680,11 +682,10 @@ group_clauses_by_indexkey(IndexOptInfo *index, } /* - * If no clauses match this key, we're done; we don't want to look - * at keys to its right. + * If no clauses match this key, check for amoptionalkey restriction. */ - if (clausegroup == NIL) - break; + if (clausegroup == NIL && !index->amoptionalkey && indexcol == 0) + return NIL; clausegroup_list = lappend(clausegroup_list, clausegroup); @@ -1581,11 +1582,9 @@ match_special_index_operator(Expr *clause, Oid opclass, * will know what to do with. * * The input list is ordered by index key, and so the output list is too. - * (The latter is not depended on by any part of the planner, so far as I can - * tell; but some parts of the executor do assume that the indexqual list - * ultimately delivered to the executor is so ordered. One such place is - * _bt_preprocess_keys() in the btree support. Perhaps that ought to be fixed - * someday --- tgl 7/00) + * (The latter is not depended on by any part of the core planner, I believe, + * but parts of the executor require it, and so do the amcostestimate + * functions.) */ List * expand_indexqual_conditions(IndexOptInfo *index, List *clausegroups) diff --git a/src/backend/optimizer/util/plancat.c b/src/backend/optimizer/util/plancat.c index a8dcdae9a2f..067e9f701ca 100644 --- a/src/backend/optimizer/util/plancat.c +++ b/src/backend/optimizer/util/plancat.c @@ -9,7 +9,7 @@ * * * IDENTIFICATION - * $PostgreSQL: pgsql/src/backend/optimizer/util/plancat.c,v 1.111 2005/06/05 22:32:56 tgl Exp $ + * $PostgreSQL: pgsql/src/backend/optimizer/util/plancat.c,v 1.112 2005/06/13 23:14:48 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -161,7 +161,8 @@ get_relation_info(Oid relationObjectId, RelOptInfo *rel) } info->relam = indexRelation->rd_rel->relam; - info->amcostestimate = index_cost_estimator(indexRelation); + info->amcostestimate = indexRelation->rd_am->amcostestimate; + info->amoptionalkey = indexRelation->rd_am->amoptionalkey; /* * Fetch the ordering operators associated with the index, if diff --git a/src/backend/utils/adt/selfuncs.c b/src/backend/utils/adt/selfuncs.c index 0b03f27c39c..204d37bf415 100644 --- a/src/backend/utils/adt/selfuncs.c +++ b/src/backend/utils/adt/selfuncs.c @@ -15,7 +15,7 @@ * * * IDENTIFICATION - * $PostgreSQL: pgsql/src/backend/utils/adt/selfuncs.c,v 1.181 2005/06/10 22:25:36 tgl Exp $ + * $PostgreSQL: pgsql/src/backend/utils/adt/selfuncs.c,v 1.182 2005/06/13 23:14:48 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -4195,18 +4195,23 @@ string_to_bytea_const(const char *str, size_t str_len) * don't have any better idea about how to estimate. Index-type-specific * knowledge can be incorporated in the type-specific routines. * + * One bit of index-type-specific knowledge we can relatively easily use + * in genericcostestimate is the estimate of the number of index tuples + * visited. If numIndexTuples is not 0 then it is used as the estimate, + * otherwise we compute a generic estimate. + * *------------------------------------------------------------------------- */ static void genericcostestimate(PlannerInfo *root, IndexOptInfo *index, List *indexQuals, + double numIndexTuples, Cost *indexStartupCost, Cost *indexTotalCost, Selectivity *indexSelectivity, double *indexCorrelation) { - double numIndexTuples; double numIndexPages; QualCost index_qual_cost; double qual_op_cost; @@ -4254,20 +4259,20 @@ genericcostestimate(PlannerInfo *root, JOIN_INNER); /* - * Estimate the number of tuples that will be visited. We do it in - * this rather peculiar-looking way in order to get the right answer - * for partial indexes. We can bound the number of tuples by the - * index size, in any case. + * If caller didn't give us an estimate, estimate the number of index + * tuples that will be visited. We do it in this rather peculiar-looking + * way in order to get the right answer for partial indexes. */ - numIndexTuples = *indexSelectivity * index->rel->tuples; - - if (numIndexTuples > index->tuples) - numIndexTuples = index->tuples; + if (numIndexTuples <= 0.0) + numIndexTuples = *indexSelectivity * index->rel->tuples; /* - * Always estimate at least one tuple is touched, even when + * We can bound the number of tuples by the index size in any case. + * Also, always estimate at least one tuple is touched, even when * indexSelectivity estimate is tiny. */ + if (numIndexTuples > index->tuples) + numIndexTuples = index->tuples; if (numIndexTuples < 1.0) numIndexTuples = 1.0; @@ -4337,8 +4342,95 @@ btcostestimate(PG_FUNCTION_ARGS) Oid relid; AttrNumber colnum; HeapTuple tuple; + double numIndexTuples; + List *indexBoundQuals; + int indexcol; + bool eqQualHere; + ListCell *l; + + /* + * For a btree scan, only leading '=' quals plus inequality quals + * for the immediately next attribute contribute to index selectivity + * (these are the "boundary quals" that determine the starting and + * stopping points of the index scan). Additional quals can suppress + * visits to the heap, so it's OK to count them in indexSelectivity, + * but they should not count for estimating numIndexTuples. So we must + * examine the given indexQuals to find out which ones count as boundary + * quals. We rely on the knowledge that they are given in index column + * order. + */ + indexBoundQuals = NIL; + indexcol = 0; + eqQualHere = false; + foreach(l, indexQuals) + { + RestrictInfo *rinfo = (RestrictInfo *) lfirst(l); + Expr *clause; + Oid clause_op; + int op_strategy; + + Assert(IsA(rinfo, RestrictInfo)); + clause = rinfo->clause; + Assert(IsA(clause, OpExpr)); + clause_op = ((OpExpr *) clause)->opno; + if (match_index_to_operand(get_leftop(clause), indexcol, index)) + { + /* clause_op is correct */ + } + else if (match_index_to_operand(get_rightop(clause), indexcol, index)) + { + /* Must flip operator to get the opclass member */ + clause_op = get_commutator(clause_op); + } + else + { + /* Must be past the end of quals for indexcol, try next */ + if (!eqQualHere) + break; /* done if no '=' qual for indexcol */ + indexcol++; + eqQualHere = false; + if (match_index_to_operand(get_leftop(clause), indexcol, index)) + { + /* clause_op is correct */ + } + else if (match_index_to_operand(get_rightop(clause), + indexcol, index)) + { + /* Must flip operator to get the opclass member */ + clause_op = get_commutator(clause_op); + } + else + { + /* No quals for new indexcol, so we are done */ + break; + } + } + op_strategy = get_op_opclass_strategy(clause_op, + index->classlist[indexcol]); + Assert(op_strategy != 0); /* not a member of opclass?? */ + if (op_strategy == BTEqualStrategyNumber) + eqQualHere = true; + indexBoundQuals = lappend(indexBoundQuals, rinfo); + } + + /* + * If index is unique and we found an '=' clause for each column, + * we can just assume numIndexTuples = 1 and skip the expensive + * clauselist_selectivity calculations. + */ + if (index->unique && indexcol == index->ncolumns - 1 && eqQualHere) + numIndexTuples = 1.0; + else + { + Selectivity btreeSelectivity; + + btreeSelectivity = clauselist_selectivity(root, indexBoundQuals, + index->rel->relid, + JOIN_INNER); + numIndexTuples = btreeSelectivity * index->rel->tuples; + } - genericcostestimate(root, index, indexQuals, + genericcostestimate(root, index, indexQuals, numIndexTuples, indexStartupCost, indexTotalCost, indexSelectivity, indexCorrelation); @@ -4414,7 +4506,7 @@ rtcostestimate(PG_FUNCTION_ARGS) Selectivity *indexSelectivity = (Selectivity *) PG_GETARG_POINTER(5); double *indexCorrelation = (double *) PG_GETARG_POINTER(6); - genericcostestimate(root, index, indexQuals, + genericcostestimate(root, index, indexQuals, 0.0, indexStartupCost, indexTotalCost, indexSelectivity, indexCorrelation); @@ -4432,7 +4524,7 @@ hashcostestimate(PG_FUNCTION_ARGS) Selectivity *indexSelectivity = (Selectivity *) PG_GETARG_POINTER(5); double *indexCorrelation = (double *) PG_GETARG_POINTER(6); - genericcostestimate(root, index, indexQuals, + genericcostestimate(root, index, indexQuals, 0.0, indexStartupCost, indexTotalCost, indexSelectivity, indexCorrelation); @@ -4450,7 +4542,7 @@ gistcostestimate(PG_FUNCTION_ARGS) Selectivity *indexSelectivity = (Selectivity *) PG_GETARG_POINTER(5); double *indexCorrelation = (double *) PG_GETARG_POINTER(6); - genericcostestimate(root, index, indexQuals, + genericcostestimate(root, index, indexQuals, 0.0, indexStartupCost, indexTotalCost, indexSelectivity, indexCorrelation); diff --git a/src/include/access/genam.h b/src/include/access/genam.h index 3ad0a3d4b2c..1ed42f8be60 100644 --- a/src/include/access/genam.h +++ b/src/include/access/genam.h @@ -7,7 +7,7 @@ * Portions Copyright (c) 1996-2005, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * - * $PostgreSQL: pgsql/src/include/access/genam.h,v 1.51 2005/05/27 23:31:21 tgl Exp $ + * $PostgreSQL: pgsql/src/include/access/genam.h,v 1.52 2005/06/13 23:14:48 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -101,7 +101,6 @@ extern IndexBulkDeleteResult *index_bulk_delete(Relation indexRelation, extern IndexBulkDeleteResult *index_vacuum_cleanup(Relation indexRelation, IndexVacuumCleanupInfo *info, IndexBulkDeleteResult *stats); -extern RegProcedure index_cost_estimator(Relation indexRelation); extern RegProcedure index_getprocid(Relation irel, AttrNumber attnum, uint16 procnum); extern FmgrInfo *index_getprocinfo(Relation irel, AttrNumber attnum, diff --git a/src/include/catalog/catversion.h b/src/include/catalog/catversion.h index ee8b3aee0a2..969c0e83299 100644 --- a/src/include/catalog/catversion.h +++ b/src/include/catalog/catversion.h @@ -37,7 +37,7 @@ * Portions Copyright (c) 1996-2005, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * - * $PostgreSQL: pgsql/src/include/catalog/catversion.h,v 1.274 2005/06/13 02:26:50 tgl Exp $ + * $PostgreSQL: pgsql/src/include/catalog/catversion.h,v 1.275 2005/06/13 23:14:49 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -53,6 +53,6 @@ */ /* yyyymmddN */ -#define CATALOG_VERSION_NO 200506121 +#define CATALOG_VERSION_NO 200506131 #endif diff --git a/src/include/catalog/pg_am.h b/src/include/catalog/pg_am.h index bddfda993bb..f473277b46b 100644 --- a/src/include/catalog/pg_am.h +++ b/src/include/catalog/pg_am.h @@ -8,7 +8,7 @@ * Portions Copyright (c) 1996-2005, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * - * $PostgreSQL: pgsql/src/include/catalog/pg_am.h,v 1.33 2005/04/14 01:38:20 tgl Exp $ + * $PostgreSQL: pgsql/src/include/catalog/pg_am.h,v 1.34 2005/06/13 23:14:49 tgl Exp $ * * NOTES * the genbki.sh script reads this file and generates .bki @@ -48,6 +48,7 @@ CATALOG(pg_am,2601) * Zero if AM is not ordered. */ bool amcanunique; /* does AM support UNIQUE indexes? */ bool amcanmulticol; /* does AM support multi-column indexes? */ + bool amoptionalkey; /* can query omit key for the first column? */ bool amindexnulls; /* does AM support NULL index entries? */ bool amconcurrent; /* does AM support concurrent updates? */ regproc aminsert; /* "insert this tuple" function */ @@ -75,42 +76,43 @@ typedef FormData_pg_am *Form_pg_am; * compiler constants for pg_am * ---------------- */ -#define Natts_pg_am 20 +#define Natts_pg_am 21 #define Anum_pg_am_amname 1 #define Anum_pg_am_amstrategies 2 #define Anum_pg_am_amsupport 3 #define Anum_pg_am_amorderstrategy 4 #define Anum_pg_am_amcanunique 5 #define Anum_pg_am_amcanmulticol 6 -#define Anum_pg_am_amindexnulls 7 -#define Anum_pg_am_amconcurrent 8 -#define Anum_pg_am_aminsert 9 -#define Anum_pg_am_ambeginscan 10 -#define Anum_pg_am_amgettuple 11 -#define Anum_pg_am_amgetmulti 12 -#define Anum_pg_am_amrescan 13 -#define Anum_pg_am_amendscan 14 -#define Anum_pg_am_ammarkpos 15 -#define Anum_pg_am_amrestrpos 16 -#define Anum_pg_am_ambuild 17 -#define Anum_pg_am_ambulkdelete 18 -#define Anum_pg_am_amvacuumcleanup 19 -#define Anum_pg_am_amcostestimate 20 +#define Anum_pg_am_amoptionalkey 7 +#define Anum_pg_am_amindexnulls 8 +#define Anum_pg_am_amconcurrent 9 +#define Anum_pg_am_aminsert 10 +#define Anum_pg_am_ambeginscan 11 +#define Anum_pg_am_amgettuple 12 +#define Anum_pg_am_amgetmulti 13 +#define Anum_pg_am_amrescan 14 +#define Anum_pg_am_amendscan 15 +#define Anum_pg_am_ammarkpos 16 +#define Anum_pg_am_amrestrpos 17 +#define Anum_pg_am_ambuild 18 +#define Anum_pg_am_ambulkdelete 19 +#define Anum_pg_am_amvacuumcleanup 20 +#define Anum_pg_am_amcostestimate 21 /* ---------------- * initial contents of pg_am * ---------------- */ -DATA(insert OID = 402 ( rtree 8 3 0 f f f f rtinsert rtbeginscan rtgettuple rtgetmulti rtrescan rtendscan rtmarkpos rtrestrpos rtbuild rtbulkdelete - rtcostestimate )); +DATA(insert OID = 402 ( rtree 8 3 0 f f f f f rtinsert rtbeginscan rtgettuple rtgetmulti rtrescan rtendscan rtmarkpos rtrestrpos rtbuild rtbulkdelete - rtcostestimate )); DESCR("r-tree index access method"); -DATA(insert OID = 403 ( btree 5 1 1 t t t t btinsert btbeginscan btgettuple btgetmulti btrescan btendscan btmarkpos btrestrpos btbuild btbulkdelete btvacuumcleanup btcostestimate )); +DATA(insert OID = 403 ( btree 5 1 1 t t t t t btinsert btbeginscan btgettuple btgetmulti btrescan btendscan btmarkpos btrestrpos btbuild btbulkdelete btvacuumcleanup btcostestimate )); DESCR("b-tree index access method"); #define BTREE_AM_OID 403 -DATA(insert OID = 405 ( hash 1 1 0 f f f t hashinsert hashbeginscan hashgettuple hashgetmulti hashrescan hashendscan hashmarkpos hashrestrpos hashbuild hashbulkdelete - hashcostestimate )); +DATA(insert OID = 405 ( hash 1 1 0 f f f f t hashinsert hashbeginscan hashgettuple hashgetmulti hashrescan hashendscan hashmarkpos hashrestrpos hashbuild hashbulkdelete - hashcostestimate )); DESCR("hash index access method"); #define HASH_AM_OID 405 -DATA(insert OID = 783 ( gist 100 7 0 f t f f gistinsert gistbeginscan gistgettuple gistgetmulti gistrescan gistendscan gistmarkpos gistrestrpos gistbuild gistbulkdelete - gistcostestimate )); +DATA(insert OID = 783 ( gist 100 7 0 f t f f f gistinsert gistbeginscan gistgettuple gistgetmulti gistrescan gistendscan gistmarkpos gistrestrpos gistbuild gistbulkdelete - gistcostestimate )); DESCR("GiST index access method"); #define GIST_AM_OID 783 diff --git a/src/include/nodes/relation.h b/src/include/nodes/relation.h index 687ef367841..0a2ca0e5f33 100644 --- a/src/include/nodes/relation.h +++ b/src/include/nodes/relation.h @@ -7,7 +7,7 @@ * Portions Copyright (c) 1996-2005, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * - * $PostgreSQL: pgsql/src/include/nodes/relation.h,v 1.114 2005/06/10 03:32:25 tgl Exp $ + * $PostgreSQL: pgsql/src/include/nodes/relation.h,v 1.115 2005/06/13 23:14:49 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -328,6 +328,7 @@ typedef struct IndexOptInfo bool predOK; /* true if predicate matches query */ bool unique; /* true if a unique index */ + bool amoptionalkey; /* can query omit key for the first column? */ } IndexOptInfo; |