diff --git a/bin/pg_repack.c b/bin/pg_repack.c index 3acdccd..c8291d9 100644 --- a/bin/pg_repack.c +++ b/bin/pg_repack.c @@ -681,7 +681,7 @@ static bool rebuild_indexes(const repack_table *table) { PGresult *res; - const char *params[1]; + const char *params[2]; int num_indexes; int i; int num_active_workers; @@ -693,6 +693,7 @@ rebuild_indexes(const repack_table *table) elog(DEBUG2, "---- create indexes ----"); params[0] = utoa(table->target_oid, buffer); + params[1] = moveidx ? tablespace : NULL; /* First, just display a warning message for any invalid indexes * which may be on the table (mostly to match the behavior of 1.1.8). @@ -708,8 +709,9 @@ rebuild_indexes(const repack_table *table) } res = execute("SELECT indexrelid," - " repack.repack_indexdef(indexrelid, indrelid) " - " FROM pg_index WHERE indrelid = $1 AND indisvalid", 1, params); + " repack.repack_indexdef(indexrelid, indrelid, $2) " + " FROM pg_index WHERE indrelid = $1 AND indisvalid", + 2, params); num_indexes = PQntuples(res); diff --git a/lib/pg_repack.sql.in b/lib/pg_repack.sql.in index 348fa95..7601008 100644 --- a/lib/pg_repack.sql.in +++ b/lib/pg_repack.sql.in @@ -207,9 +207,9 @@ CREATE VIEW repack.tables AS AND N.nspname NOT IN ('pg_catalog', 'information_schema') AND N.nspname NOT LIKE E'pg\\_temp\\_%'; -CREATE FUNCTION repack.repack_indexdef(oid, oid) RETURNS text AS +CREATE FUNCTION repack.repack_indexdef(oid, oid, name) RETURNS text AS 'MODULE_PATHNAME', 'repack_indexdef' -LANGUAGE C STABLE STRICT; +LANGUAGE C STABLE; CREATE FUNCTION repack.repack_trigger() RETURNS trigger AS 'MODULE_PATHNAME', 'repack_trigger' diff --git a/lib/repack.c b/lib/repack.c index 1bfec43..d315bbf 100644 --- a/lib/repack.c +++ b/lib/repack.c @@ -618,20 +618,62 @@ repack_get_order_by(PG_FUNCTION_ARGS) * * @param index Oid of target index. * @param table Oid of table of the index. + * @param tablespace Namespace for the index. If NULL keep the original. * @retval Create index DDL for temp table. */ Datum repack_indexdef(PG_FUNCTION_ARGS) { - Oid index = PG_GETARG_OID(0); - Oid table = PG_GETARG_OID(1); + Oid index; + Oid table; + Name tablespace = NULL; IndexDef stmt; StringInfoData str; + if (PG_ARGISNULL(0) || PG_ARGISNULL(1)) + PG_RETURN_NULL(); + + index = PG_GETARG_OID(0); + table = PG_GETARG_OID(1); + + if (!PG_ARGISNULL(2)) + tablespace = PG_GETARG_NAME(2); + parse_indexdef(&stmt, index, table); + initStringInfo(&str); - appendStringInfo(&str, "%s index_%u ON repack.table_%u USING %s (%s)%s", - stmt.create, index, table, stmt.type, stmt.columns, stmt.options); + appendStringInfo(&str, "%s index_%u ON repack.table_%u USING %s (%s)", + stmt.create, index, table, stmt.type, stmt.columns); + + /* Replace the tablespace in the index options */ + if (tablespace == NULL) + { + /* tablespace is just fine */ + appendStringInfoString(&str, stmt.options); + } + else + { + const char *pos; + if (NULL == (pos = strstr(stmt.options, " TABLESPACE "))) + { + /* tablespace is to append */ + appendStringInfoString(&str, " TABLESPACE "); + appendStringInfoString(&str, NameStr(*tablespace)); + } + else + { + char *tmp; + + /* tablespace is to replace */ + tmp = skip_const(index, stmt.options, " TABLESPACE ", NULL); + appendStringInfoString(&str, stmt.options); + appendStringInfoString(&str, NameStr(*tablespace)); + /* FIXME: not working if original ts has a space. But skip_ident + * should deal with that. Stupid mistake somewhere? */ + tmp = skip_ident(index, tmp); + appendStringInfoString(&str, tmp); + } + } PG_RETURN_TEXT_P(cstring_to_text(str.data)); }