diff options
| author | Teodor Sigaev | 2016-04-08 16:31:49 +0000 |
|---|---|---|
| committer | Teodor Sigaev | 2016-04-08 16:45:59 +0000 |
| commit | 386e3d7609c49505e079c40c65919d99feb82505 (patch) | |
| tree | dd8f434e5401588c2b4f9e2068f396c5ce198cf6 /src/bin | |
| parent | 339025c68f95d3cb2c42478109cafeaf414c7fe0 (diff) | |
CREATE INDEX ... INCLUDING (column[, ...])
Now indexes (but only B-tree for now) can contain "extra" column(s) which
doesn't participate in index structure, they are just stored in leaf
tuples. It allows to use index only scan by using single index instead
of two or more indexes.
Author: Anastasia Lubennikova with minor editorializing by me
Reviewers: David Rowley, Peter Geoghegan, Jeff Janes
Diffstat (limited to 'src/bin')
| -rw-r--r-- | src/bin/pg_dump/pg_dump.c | 65 | ||||
| -rw-r--r-- | src/bin/pg_dump/pg_dump.h | 6 |
2 files changed, 64 insertions, 7 deletions
diff --git a/src/bin/pg_dump/pg_dump.c b/src/bin/pg_dump/pg_dump.c index 33cd6651d12..7e6abd762c2 100644 --- a/src/bin/pg_dump/pg_dump.c +++ b/src/bin/pg_dump/pg_dump.c @@ -5991,7 +5991,8 @@ getIndexes(Archive *fout, TableInfo tblinfo[], int numTables) i_oid, i_indexname, i_indexdef, - i_indnkeys, + i_indnnkeyatts, + i_indnatts, i_indkey, i_indisclustered, i_indisreplident, @@ -6042,7 +6043,42 @@ getIndexes(Archive *fout, TableInfo tblinfo[], int numTables) * is not. */ resetPQExpBuffer(query); - if (fout->remoteVersion >= 90400) + if (fout->remoteVersion >= 90600) + { + /* + * In 9.6 we add INCLUDING columns functionality + * that requires new fields to be added. + * i.indnkeyattrs is new, and besides we should use + * i.indnatts instead of t.relnatts for index relations. + * + */ + appendPQExpBuffer(query, + "SELECT t.tableoid, t.oid, " + "t.relname AS indexname, " + "pg_catalog.pg_get_indexdef(i.indexrelid) AS indexdef, " + "i.indnkeyatts AS indnkeyatts, " + "i.indnatts AS indnatts, " + "i.indkey, i.indisclustered, " + "i.indisreplident, t.relpages, " + "c.contype, c.conname, " + "c.condeferrable, c.condeferred, " + "c.tableoid AS contableoid, " + "c.oid AS conoid, " + "pg_catalog.pg_get_constraintdef(c.oid, false) AS condef, " + "(SELECT spcname FROM pg_catalog.pg_tablespace s WHERE s.oid = t.reltablespace) AS tablespace, " + "t.reloptions AS indreloptions " + "FROM pg_catalog.pg_index i " + "JOIN pg_catalog.pg_class t ON (t.oid = i.indexrelid) " + "LEFT JOIN pg_catalog.pg_constraint c " + "ON (i.indrelid = c.conrelid AND " + "i.indexrelid = c.conindid AND " + "c.contype IN ('p','u','x')) " + "WHERE i.indrelid = '%u'::pg_catalog.oid " + "AND i.indisvalid AND i.indisready " + "ORDER BY indexname", + tbinfo->dobj.catId.oid); + } + else if (fout->remoteVersion >= 90400) { /* * the test on indisready is necessary in 9.2, and harmless in @@ -6253,7 +6289,8 @@ getIndexes(Archive *fout, TableInfo tblinfo[], int numTables) i_oid = PQfnumber(res, "oid"); i_indexname = PQfnumber(res, "indexname"); i_indexdef = PQfnumber(res, "indexdef"); - i_indnkeys = PQfnumber(res, "indnkeys"); + i_indnnkeyatts = PQfnumber(res, "indnkeyatts"); + i_indnatts = PQfnumber(res, "indnatts"); i_indkey = PQfnumber(res, "indkey"); i_indisclustered = PQfnumber(res, "indisclustered"); i_indisreplident = PQfnumber(res, "indisreplident"); @@ -6283,7 +6320,8 @@ getIndexes(Archive *fout, TableInfo tblinfo[], int numTables) indxinfo[j].dobj.namespace = tbinfo->dobj.namespace; indxinfo[j].indextable = tbinfo; indxinfo[j].indexdef = pg_strdup(PQgetvalue(res, j, i_indexdef)); - indxinfo[j].indnkeys = atoi(PQgetvalue(res, j, i_indnkeys)); + indxinfo[j].indnkeyattrs = atoi(PQgetvalue(res, j, i_indnnkeyatts)); + indxinfo[j].indnattrs = atoi(PQgetvalue(res, j, i_indnatts)); indxinfo[j].tablespace = pg_strdup(PQgetvalue(res, j, i_tablespace)); indxinfo[j].indreloptions = pg_strdup(PQgetvalue(res, j, i_indreloptions)); @@ -15906,7 +15944,7 @@ dumpConstraint(Archive *fout, ConstraintInfo *coninfo) { appendPQExpBuffer(q, "%s (", coninfo->contype == 'p' ? "PRIMARY KEY" : "UNIQUE"); - for (k = 0; k < indxinfo->indnkeys; k++) + for (k = 0; k < indxinfo->indnkeyattrs; k++) { int indkey = (int) indxinfo->indkeys[k]; const char *attname; @@ -15920,6 +15958,23 @@ dumpConstraint(Archive *fout, ConstraintInfo *coninfo) fmtId(attname)); } + if (indxinfo->indnkeyattrs < indxinfo->indnattrs) + appendPQExpBuffer(q, ") INCLUDING ("); + + for (k = indxinfo->indnkeyattrs; k < indxinfo->indnattrs; k++) + { + int indkey = (int) indxinfo->indkeys[k]; + const char *attname; + + if (indkey == InvalidAttrNumber) + break; + attname = getAttrName(indkey, tbinfo); + + appendPQExpBuffer(q, "%s%s", + (k == indxinfo->indnkeyattrs) ? "" : ", ", + fmtId(attname)); + } + appendPQExpBufferChar(q, ')'); if (nonemptyReloptions(indxinfo->indreloptions)) diff --git a/src/bin/pg_dump/pg_dump.h b/src/bin/pg_dump/pg_dump.h index 7314cbeec80..95fa76d95a6 100644 --- a/src/bin/pg_dump/pg_dump.h +++ b/src/bin/pg_dump/pg_dump.h @@ -318,8 +318,10 @@ typedef struct _indxInfo char *indexdef; char *tablespace; /* tablespace in which index is stored */ char *indreloptions; /* options specified by WITH (...) */ - int indnkeys; - Oid *indkeys; + int indnkeyattrs; /* number of index key attributes*/ + int indnattrs; /* total number of index attributes*/ + Oid *indkeys; /* In spite of the name 'indkeys' this field + * contains both key and nonkey attributes*/ bool indisclustered; bool indisreplident; /* if there is an associated constraint object, its dumpId: */ |
