On 2019-Apr-10, Alvaro Herrera wrote:
> but the test immediately does this:
>
> alter table at_partitioned alter column b type numeric using b::numeric;
>
> and watch what happens! (1663 is pg_default)
>
> alvherre=# select relname, reltablespace from pg_class where relname like
> 'at_partitioned%';
> relname | reltablespace
> ----------------------+---------------
> at_partitioned | 0
> at_partitioned_a_idx | 0
> at_partitioned_b_idx | 1663
> (3 filas)
>
> Outrageous!
This is because ruleutils.c attaches a TABLESPACE clause when asked to
dump an index definition; and tablecmds.c uses ruleutils to deparse the
index definition into something that can be replayed via CREATE INDEX
commands (or ALTER TABLE ADD CONSTRAINT UNIQUE/PRIMARY KEY, if that's
the case.)
This patch (PoC quality) fixes that behavior, but I'm looking to see
what else it breaks.
--
Álvaro Herrera https://www.2ndQuadrant.com/
PostgreSQL Development, 24x7 Support, Remote DBA, Training & Services
diff --git a/src/backend/commands/tablecmds.c b/src/backend/commands/tablecmds.c
index 83f72470b10..acb6b09a576 100644
--- a/src/backend/commands/tablecmds.c
+++ b/src/backend/commands/tablecmds.c
@@ -10567,7 +10567,13 @@ ATExecAlterColumnType(AlteredTableInfo *tab, Relation rel,
tab->changedIndexOids = lappend_oid(tab->changedIndexOids,
foundObject.objectId);
tab->changedIndexDefs = lappend(tab->changedIndexDefs,
- pg_get_indexdef_string(foundObject.objectId));
+ /*
+ * we include a tablespace clause
+ * only if it's a plain index.
+ * This likely breaks some stuff.
+ */
+ pg_get_indexdef_string(foundObject.objectId,
+ relKind == RELKIND_INDEX));
}
}
else if (relKind == RELKIND_SEQUENCE)
diff --git a/src/backend/utils/adt/ruleutils.c b/src/backend/utils/adt/ruleutils.c
index 0c7a533e697..41144d84a76 100644
--- a/src/backend/utils/adt/ruleutils.c
+++ b/src/backend/utils/adt/ruleutils.c
@@ -1142,11 +1142,11 @@ pg_get_indexdef_ext(PG_FUNCTION_ARGS)
* Returns a palloc'd C string; no pretty-printing.
*/
char *
-pg_get_indexdef_string(Oid indexrelid)
+pg_get_indexdef_string(Oid indexrelid, bool tablespace)
{
return pg_get_indexdef_worker(indexrelid, 0, NULL,
false, false,
- true, true,
+ tablespace, true,
0, false);
}
@@ -2170,6 +2170,7 @@ pg_get_constraintdef_worker(Oid constraintId, bool fullCommand,
pfree(options);
}
+ /* XXX this tablespace works even if it's 0 */
tblspc = get_rel_tablespace(indexId);
if (OidIsValid(tblspc))
appendStringInfo(&buf, " USING INDEX TABLESPACE %s",
diff --git a/src/include/utils/ruleutils.h b/src/include/utils/ruleutils.h
index 7c49e9d0a83..6ff3b841057 100644
--- a/src/include/utils/ruleutils.h
+++ b/src/include/utils/ruleutils.h
@@ -18,7 +18,7 @@
#include "nodes/pg_list.h"
-extern char *pg_get_indexdef_string(Oid indexrelid);
+extern char *pg_get_indexdef_string(Oid indexrelid, bool tablespace);
extern char *pg_get_indexdef_columns(Oid indexrelid, bool pretty);
extern char *pg_get_partkeydef_columns(Oid relid, bool pretty);