diff --git a/bin/expected/tablespace.out b/bin/expected/tablespace.out index 15f69c2..2a51bc9 100644 --- a/bin/expected/tablespace.out +++ b/bin/expected/tablespace.out @@ -17,6 +17,31 @@ CREATE INDEX testts1_with_idx on testts1 (id) with (fillfactor=80); INSERT INTO testts1 (data) values ('a'); INSERT INTO testts1 (data) values ('b'); INSERT INTO testts1 (data) values ('c'); +-- check the indexes definitions +SELECT regexp_replace( + repack.repack_indexdef(indexrelid, 'testts1'::regclass, NULL), + '_[0-9]+', '_OID', 'g') +FROM pg_index i join pg_class c ON c.oid = indexrelid +WHERE indrelid = 'testts1'::regclass ORDER BY relname; + regexp_replace +---------------------------------------------------------------------------------- + CREATE INDEX index_OID ON repack.table_OID USING btree (id) WHERE (id > 0) + CREATE UNIQUE INDEX index_OID ON repack.table_OID USING btree (id) + CREATE INDEX index_OID ON repack.table_OID USING btree (id) WITH (fillfactor=80) +(3 rows) + +SELECT regexp_replace( + repack.repack_indexdef(indexrelid, 'testts1'::regclass, 'foo'), + '_[0-9]+', '_OID', 'g') +FROM pg_index i join pg_class c ON c.oid = indexrelid +WHERE indrelid = 'testts1'::regclass ORDER BY relname; + regexp_replace +------------------------------------------------------------------------------------------------- + CREATE INDEX index_OID ON repack.table_OID USING btree (id) TABLESPACE foo WHERE (id > 0) + CREATE UNIQUE INDEX index_OID ON repack.table_OID USING btree (id) TABLESPACE foo + CREATE INDEX index_OID ON repack.table_OID USING btree (id) WITH (fillfactor=80) TABLESPACE foo +(3 rows) + -- can move the tablespace from default \! pg_repack --dbname=contrib_regression --no-order --table=testts1 --tablespace testts INFO: repacking table "testts1" diff --git a/bin/sql/tablespace.sql b/bin/sql/tablespace.sql index 7fa2ce8..60b9390 100644 --- a/bin/sql/tablespace.sql +++ b/bin/sql/tablespace.sql @@ -16,6 +16,19 @@ INSERT INTO testts1 (data) values ('a'); INSERT INTO testts1 (data) values ('b'); INSERT INTO testts1 (data) values ('c'); +-- check the indexes definitions +SELECT regexp_replace( + repack.repack_indexdef(indexrelid, 'testts1'::regclass, NULL), + '_[0-9]+', '_OID', 'g') +FROM pg_index i join pg_class c ON c.oid = indexrelid +WHERE indrelid = 'testts1'::regclass ORDER BY relname; + +SELECT regexp_replace( + repack.repack_indexdef(indexrelid, 'testts1'::regclass, 'foo'), + '_[0-9]+', '_OID', 'g') +FROM pg_index i join pg_class c ON c.oid = indexrelid +WHERE indrelid = 'testts1'::regclass ORDER BY relname; + -- can move the tablespace from default \! pg_repack --dbname=contrib_regression --no-order --table=testts1 --tablespace testts diff --git a/lib/repack.c b/lib/repack.c index 34fdcf9..a74de05 100644 --- a/lib/repack.c +++ b/lib/repack.c @@ -305,7 +305,9 @@ typedef struct IndexDef char *table; /* table name including schema */ char *type; /* btree, hash, gist or gin */ char *columns; /* column definition */ - char *options; /* options after columns. WITH, TABLESPACE and WHERE */ + char *options; /* options after columns, before TABLESPACE (e.g. COLLATE) */ + char *tablespace; /* tablespace if specified */ + char *where; /* WHERE content if specified */ } IndexDef; static char * @@ -349,14 +351,14 @@ skip_const(Oid index, char *sql, const char *arg1, const char *arg2) static char * skip_until_const(Oid index, char *sql, const char *what) { - char *pos; + char *pos; if ((pos = strstr(sql, what))) { - size_t len; + size_t len; - len = strlen(what); - pos[len] = '\0'; + len = strlen(what); + pos[-1] = '\0'; return pos + len + 1; } @@ -462,6 +464,7 @@ parse_indexdef(IndexDef *stmt, Oid index, Oid table) char *sql = pg_get_indexdef_string(index); const char *idxname = get_quoted_relname(index); const char *tblname = get_relation_name(table); + const char *limit = strchr(sql, '\0'); /* CREATE [UNIQUE] INDEX */ stmt->create = sql; @@ -486,8 +489,36 @@ parse_indexdef(IndexDef *stmt, Oid index, Oid table) stmt->columns = sql; if ((sql = skip_until(index, sql, ')')) == NULL) parse_error(index); + /* options */ stmt->options = sql; + stmt->tablespace = NULL; + stmt->where = NULL; + + /* Is there a tablespace? Note that apparently there is never, but + * if there was one it would appear here. */ + if (sql < limit && strstr(sql, "TABLESPACE")) + { + sql = skip_until_const(index, sql, "TABLESPACE"); + stmt->tablespace = sql; + sql = skip_ident(index, sql); + } + + /* Note: assuming WHERE is the only clause allowed after TABLESPACE */ + if (sql < limit && strstr(sql, "WHERE")) + { + sql = skip_until_const(index, sql, "WHERE"); + stmt->where = sql; + } + + elog(DEBUG2, "indexdef.create = %s", stmt->create); + elog(DEBUG2, "indexdef.index = %s", stmt->index); + elog(DEBUG2, "indexdef.table = %s", stmt->table); + elog(DEBUG2, "indexdef.type = %s", stmt->type); + elog(DEBUG2, "indexdef.columns = %s", stmt->columns); + elog(DEBUG2, "indexdef.options = %s", stmt->options); + elog(DEBUG2, "indexdef.tspace = %s", stmt->tablespace); + elog(DEBUG2, "indexdef.where = %s", stmt->where); } /* @@ -546,12 +577,6 @@ repack_get_order_by(PG_FUNCTION_ARGS) int nattr; parse_indexdef(&stmt, index, table); - elog(DEBUG2, "indexdef.create = %s", stmt.create); - elog(DEBUG2, "indexdef.index = %s", stmt.index); - elog(DEBUG2, "indexdef.table = %s", stmt.table); - elog(DEBUG2, "indexdef.type = %s", stmt.type); - elog(DEBUG2, "indexdef.columns = %s", stmt.columns); - elog(DEBUG2, "indexdef.options = %s", stmt.options); /* * FIXME: this is very unreliable implementation but I don't want to @@ -660,36 +685,16 @@ repack_indexdef(PG_FUNCTION_ARGS) parse_indexdef(&stmt, index, table); initStringInfo(&str); - appendStringInfo(&str, "%s index_%u ON repack.table_%u USING %s (%s)", - stmt.create, index, table, stmt.type, stmt.columns); + appendStringInfo(&str, "%s index_%u ON repack.table_%u USING %s (%s)%s", + stmt.create, index, table, stmt.type, stmt.columns, stmt.options); - /* Replace the tablespace in the index options */ - if (tablespace == NULL) - { - /* tablespace is just fine */ - appendStringInfoString(&str, stmt.options); - } - else - { - if (NULL == strstr(stmt.options, "TABLESPACE")) - { - /* tablespace is to append */ - appendStringInfoString(&str, " TABLESPACE "); - appendStringInfoString(&str, NameStr(*tablespace)); - } - else - { - /* tablespace is to replace */ - char *tmp, *limit; - limit = strchr(stmt.options, '\0'); - tmp = skip_until_const(index, stmt.options, " TABLESPACE"); - appendStringInfoString(&str, stmt.options); - appendStringInfo(&str, " %s", NameStr(*tablespace)); - tmp = skip_ident(index, tmp); - if (tmp < limit) - appendStringInfo(&str, " %s", tmp); - } - } + /* specify the new tablespace or the original one if any */ + if (tablespace || stmt.tablespace) + appendStringInfo(&str, " TABLESPACE %s", + (tablespace ? NameStr(*tablespace) : stmt.tablespace)); + + if (stmt.where) + appendStringInfo(&str, " WHERE %s", stmt.where); PG_RETURN_TEXT_P(cstring_to_text(str.data)); }