summaryrefslogtreecommitdiff
path: root/src/bin
diff options
context:
space:
mode:
authorTeodor Sigaev2016-04-08 16:31:49 +0000
committerTeodor Sigaev2016-04-08 16:45:59 +0000
commit386e3d7609c49505e079c40c65919d99feb82505 (patch)
treedd8f434e5401588c2b4f9e2068f396c5ce198cf6 /src/bin
parent339025c68f95d3cb2c42478109cafeaf414c7fe0 (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.c65
-rw-r--r--src/bin/pg_dump/pg_dump.h6
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: */