diff options
author | Alvaro Herrera <alvherre@alvh.no-ip.org> | 2016-03-23 23:01:35 -0300 |
---|---|---|
committer | Alvaro Herrera <alvherre@alvh.no-ip.org> | 2016-03-23 23:01:35 -0300 |
commit | 473b93287040b20017cc25a157cffdc5b978c254 (patch) | |
tree | 58f662a65247525b2e5e178b9050feb3f3056590 /src/include | |
parent | 2c6af4f44228d76d3351fe26f68b00b55cdd239a (diff) |
Support CREATE ACCESS METHOD
This enables external code to create access methods. This is useful so
that extensions can add their own access methods which can be formally
tracked for dependencies, so that DROP operates correctly. Also, having
explicit support makes pg_dump work correctly.
Currently only index AMs are supported, but we expect different types to
be added in the future.
Authors: Alexander Korotkov, Petr Jelínek
Reviewed-By: Teodor Sigaev, Petr Jelínek, Jim Nasby
Commitfest-URL: https://commitfest.postgresql.org/9/353/
Discussion: https://www.postgresql.org/message-id/CAPpHfdsXwZmojm6Dx+TJnpYk27kT4o7Ri6X_4OSWcByu1Rm+VA@mail.gmail.com
Diffstat (limited to 'src/include')
-rw-r--r-- | src/include/catalog/catversion.h | 2 | ||||
-rw-r--r-- | src/include/catalog/dependency.h | 1 | ||||
-rw-r--r-- | src/include/catalog/pg_am.h | 22 | ||||
-rw-r--r-- | src/include/commands/defrem.h | 9 | ||||
-rw-r--r-- | src/include/nodes/nodes.h | 1 | ||||
-rw-r--r-- | src/include/nodes/parsenodes.h | 13 | ||||
-rw-r--r-- | src/include/parser/kwlist.h | 1 | ||||
-rw-r--r-- | src/include/utils/selfuncs.h | 48 |
8 files changed, 87 insertions, 10 deletions
diff --git a/src/include/catalog/catversion.h b/src/include/catalog/catversion.h index 3568cb27e81..b690dc6b34f 100644 --- a/src/include/catalog/catversion.h +++ b/src/include/catalog/catversion.h @@ -53,6 +53,6 @@ */ /* yyyymmddN */ -#define CATALOG_VERSION_NO 201603211 +#define CATALOG_VERSION_NO 201603231 #endif diff --git a/src/include/catalog/dependency.h b/src/include/catalog/dependency.h index 049bf9f5a2e..d41abc4e480 100644 --- a/src/include/catalog/dependency.h +++ b/src/include/catalog/dependency.h @@ -134,6 +134,7 @@ typedef enum ObjectClass OCLASS_OPERATOR, /* pg_operator */ OCLASS_OPCLASS, /* pg_opclass */ OCLASS_OPFAMILY, /* pg_opfamily */ + OCLASS_AM, /* pg_am */ OCLASS_AMOP, /* pg_amop */ OCLASS_AMPROC, /* pg_amproc */ OCLASS_REWRITE, /* pg_rewrite */ diff --git a/src/include/catalog/pg_am.h b/src/include/catalog/pg_am.h index f801c3ee577..11169237991 100644 --- a/src/include/catalog/pg_am.h +++ b/src/include/catalog/pg_am.h @@ -35,6 +35,7 @@ CATALOG(pg_am,2601) { NameData amname; /* access method name */ regproc amhandler; /* handler function */ + char amtype; /* see AMTYPE_xxx constants below */ } FormData_pg_am; /* ---------------- @@ -48,31 +49,38 @@ typedef FormData_pg_am *Form_pg_am; * compiler constants for pg_am * ---------------- */ -#define Natts_pg_am 2 +#define Natts_pg_am 3 #define Anum_pg_am_amname 1 #define Anum_pg_am_amhandler 2 +#define Anum_pg_am_amtype 3 + +/* ---------------- + * compiler constant for amtype + * ---------------- + */ +#define AMTYPE_INDEX 'i' /* index access method */ /* ---------------- * initial contents of pg_am * ---------------- */ -DATA(insert OID = 403 ( btree bthandler )); +DATA(insert OID = 403 ( btree bthandler i )); DESCR("b-tree index access method"); #define BTREE_AM_OID 403 -DATA(insert OID = 405 ( hash hashhandler )); +DATA(insert OID = 405 ( hash hashhandler i )); DESCR("hash index access method"); #define HASH_AM_OID 405 -DATA(insert OID = 783 ( gist gisthandler )); +DATA(insert OID = 783 ( gist gisthandler i )); DESCR("GiST index access method"); #define GIST_AM_OID 783 -DATA(insert OID = 2742 ( gin ginhandler )); +DATA(insert OID = 2742 ( gin ginhandler i )); DESCR("GIN index access method"); #define GIN_AM_OID 2742 -DATA(insert OID = 4000 ( spgist spghandler )); +DATA(insert OID = 4000 ( spgist spghandler i )); DESCR("SP-GiST index access method"); #define SPGIST_AM_OID 4000 -DATA(insert OID = 3580 ( brin brinhandler )); +DATA(insert OID = 3580 ( brin brinhandler i )); DESCR("block range index (BRIN) access method"); #define BRIN_AM_OID 3580 diff --git a/src/include/commands/defrem.h b/src/include/commands/defrem.h index 54f67e9eea6..b064eb4836a 100644 --- a/src/include/commands/defrem.h +++ b/src/include/commands/defrem.h @@ -91,8 +91,6 @@ extern void IsThereOpClassInNamespace(const char *opcname, Oid opcmethod, Oid opcnamespace); extern void IsThereOpFamilyInNamespace(const char *opfname, Oid opfmethod, Oid opfnamespace); -extern Oid get_am_oid(const char *amname, bool missing_ok); -extern char *get_am_name(Oid amOid); extern Oid get_opclass_oid(Oid amID, List *opclassname, bool missing_ok); extern Oid get_opfamily_oid(Oid amID, List *opfamilyname, bool missing_ok); @@ -137,6 +135,13 @@ extern Datum transformGenericOptions(Oid catalogId, List *options, Oid fdwvalidator); +/* commands/amcmds.c */ +extern ObjectAddress CreateAccessMethod(CreateAmStmt *stmt); +extern void RemoveAccessMethodById(Oid amOid); +extern Oid get_index_am_oid(const char *amname, bool missing_ok); +extern Oid get_am_oid(const char *amname, bool missing_ok); +extern char *get_am_name(Oid amOid); + /* support routines in commands/define.c */ extern char *defGetString(DefElem *def); diff --git a/src/include/nodes/nodes.h b/src/include/nodes/nodes.h index 42c958258b6..734df771eb2 100644 --- a/src/include/nodes/nodes.h +++ b/src/include/nodes/nodes.h @@ -402,6 +402,7 @@ typedef enum NodeTag T_CreatePolicyStmt, T_AlterPolicyStmt, T_CreateTransformStmt, + T_CreateAmStmt, /* * TAGS FOR PARSE TREE NODES (parsenodes.h) diff --git a/src/include/nodes/parsenodes.h b/src/include/nodes/parsenodes.h index 2fd06295e5c..8b958b422cb 100644 --- a/src/include/nodes/parsenodes.h +++ b/src/include/nodes/parsenodes.h @@ -1379,6 +1379,7 @@ typedef struct SetOperationStmt typedef enum ObjectType { + OBJECT_ACCESS_METHOD, OBJECT_AGGREGATE, OBJECT_AMOP, OBJECT_AMPROC, @@ -2070,6 +2071,18 @@ typedef struct AlterPolicyStmt Node *with_check; /* the policy's WITH CHECK condition. */ } AlterPolicyStmt; +/*---------------------- + * Create ACCESS METHOD Statement + *---------------------- + */ +typedef struct CreateAmStmt +{ + NodeTag type; + char *amname; /* access method name */ + List *handler_name; /* handler function name */ + char amtype; /* type of access method */ +} CreateAmStmt; + /* ---------------------- * Create TRIGGER Statement * ---------------------- diff --git a/src/include/parser/kwlist.h b/src/include/parser/kwlist.h index 6e1e82027cb..7de3404aa22 100644 --- a/src/include/parser/kwlist.h +++ b/src/include/parser/kwlist.h @@ -239,6 +239,7 @@ PG_KEYWORD("mapping", MAPPING, UNRESERVED_KEYWORD) PG_KEYWORD("match", MATCH, UNRESERVED_KEYWORD) PG_KEYWORD("materialized", MATERIALIZED, UNRESERVED_KEYWORD) PG_KEYWORD("maxvalue", MAXVALUE, UNRESERVED_KEYWORD) +PG_KEYWORD("method", METHOD, UNRESERVED_KEYWORD) PG_KEYWORD("minute", MINUTE_P, UNRESERVED_KEYWORD) PG_KEYWORD("minvalue", MINVALUE, UNRESERVED_KEYWORD) PG_KEYWORD("mode", MODE, UNRESERVED_KEYWORD) diff --git a/src/include/utils/selfuncs.h b/src/include/utils/selfuncs.h index 06fbca719b5..8e0d3174687 100644 --- a/src/include/utils/selfuncs.h +++ b/src/include/utils/selfuncs.h @@ -95,6 +95,48 @@ typedef enum Pattern_Prefix_None, Pattern_Prefix_Partial, Pattern_Prefix_Exact } Pattern_Prefix_Status; +/* + * deconstruct_indexquals is a simple function to examine the indexquals + * attached to a proposed IndexPath. It returns a list of IndexQualInfo + * structs, one per qual expression. + */ +typedef struct +{ + RestrictInfo *rinfo; /* the indexqual itself */ + int indexcol; /* zero-based index column number */ + bool varonleft; /* true if index column is on left of qual */ + Oid clause_op; /* qual's operator OID, if relevant */ + Node *other_operand; /* non-index operand of qual's operator */ +} IndexQualInfo; + +/* + * genericcostestimate is a general-purpose estimator that can be used for + * most index types. In some cases we use genericcostestimate as the base + * code and then incorporate additional index-type-specific knowledge in + * the type-specific calling function. To avoid code duplication, we make + * genericcostestimate return a number of intermediate values as well as + * its preliminary estimates of the output cost values. The GenericCosts + * struct includes all these values. + * + * Callers should initialize all fields of GenericCosts to zero. In addition, + * they can set numIndexTuples to some positive value if they have a better + * than default way of estimating the number of leaf index tuples visited. + */ +typedef struct +{ + /* These are the values the cost estimator must return to the planner */ + Cost indexStartupCost; /* index-related startup cost */ + Cost indexTotalCost; /* total index-related scan cost */ + Selectivity indexSelectivity; /* selectivity of index */ + double indexCorrelation; /* order correlation of index */ + + /* Intermediate values we obtain along the way */ + double numIndexPages; /* number of leaf pages visited */ + double numIndexTuples; /* number of leaf tuples visited */ + double spc_random_page_cost; /* relevant random_page_cost value */ + double num_sa_scans; /* # indexscans from ScalarArrayOps */ +} GenericCosts; + /* Hooks for plugins to get control when we ask for stats */ typedef bool (*get_relation_stats_hook_type) (PlannerInfo *root, RangeTblEntry *rte, @@ -191,6 +233,12 @@ extern double estimate_num_groups(PlannerInfo *root, List *groupExprs, extern Selectivity estimate_hash_bucketsize(PlannerInfo *root, Node *hashkey, double nbuckets); +extern List *deconstruct_indexquals(IndexPath *path); +extern void genericcostestimate(PlannerInfo *root, IndexPath *path, + double loop_count, + List *qinfos, + GenericCosts *costs); + /* Functions in array_selfuncs.c */ extern Selectivity scalararraysel_containment(PlannerInfo *root, |