Commit e90710f3 authored by Alvaro Herrera's avatar Alvaro Herrera

Dump an unvalidated constraint separately from its table

This allows possibly violating data to be imported before the constraint
is installed.

Bug reported by Thom Brown
parent f21fc7f9
...@@ -5953,11 +5953,22 @@ getTableAttrs(TableInfo *tblinfo, int numTables) ...@@ -5953,11 +5953,22 @@ getTableAttrs(TableInfo *tblinfo, int numTables)
tbinfo->dobj.name); tbinfo->dobj.name);
resetPQExpBuffer(q); resetPQExpBuffer(q);
if (g_fout->remoteVersion >= 80400) if (g_fout->remoteVersion >= 90100)
{ {
appendPQExpBuffer(q, "SELECT tableoid, oid, conname, " appendPQExpBuffer(q, "SELECT tableoid, oid, conname, "
"pg_catalog.pg_get_constraintdef(oid) AS consrc, " "pg_catalog.pg_get_constraintdef(oid) AS consrc, "
"conislocal " "conislocal, convalidated "
"FROM pg_catalog.pg_constraint "
"WHERE conrelid = '%u'::pg_catalog.oid "
" AND contype = 'c' "
"ORDER BY conname",
tbinfo->dobj.catId.oid);
}
else if (g_fout->remoteVersion >= 80400)
{
appendPQExpBuffer(q, "SELECT tableoid, oid, conname, "
"pg_catalog.pg_get_constraintdef(oid) AS consrc, "
"conislocal, true AS convalidated "
"FROM pg_catalog.pg_constraint " "FROM pg_catalog.pg_constraint "
"WHERE conrelid = '%u'::pg_catalog.oid " "WHERE conrelid = '%u'::pg_catalog.oid "
" AND contype = 'c' " " AND contype = 'c' "
...@@ -5968,7 +5979,7 @@ getTableAttrs(TableInfo *tblinfo, int numTables) ...@@ -5968,7 +5979,7 @@ getTableAttrs(TableInfo *tblinfo, int numTables)
{ {
appendPQExpBuffer(q, "SELECT tableoid, oid, conname, " appendPQExpBuffer(q, "SELECT tableoid, oid, conname, "
"pg_catalog.pg_get_constraintdef(oid) AS consrc, " "pg_catalog.pg_get_constraintdef(oid) AS consrc, "
"true AS conislocal " "true AS conislocal, true AS convalidated "
"FROM pg_catalog.pg_constraint " "FROM pg_catalog.pg_constraint "
"WHERE conrelid = '%u'::pg_catalog.oid " "WHERE conrelid = '%u'::pg_catalog.oid "
" AND contype = 'c' " " AND contype = 'c' "
...@@ -5980,7 +5991,7 @@ getTableAttrs(TableInfo *tblinfo, int numTables) ...@@ -5980,7 +5991,7 @@ getTableAttrs(TableInfo *tblinfo, int numTables)
/* no pg_get_constraintdef, must use consrc */ /* no pg_get_constraintdef, must use consrc */
appendPQExpBuffer(q, "SELECT tableoid, oid, conname, " appendPQExpBuffer(q, "SELECT tableoid, oid, conname, "
"'CHECK (' || consrc || ')' AS consrc, " "'CHECK (' || consrc || ')' AS consrc, "
"true AS conislocal " "true AS conislocal, true AS convalidated "
"FROM pg_catalog.pg_constraint " "FROM pg_catalog.pg_constraint "
"WHERE conrelid = '%u'::pg_catalog.oid " "WHERE conrelid = '%u'::pg_catalog.oid "
" AND contype = 'c' " " AND contype = 'c' "
...@@ -5993,7 +6004,7 @@ getTableAttrs(TableInfo *tblinfo, int numTables) ...@@ -5993,7 +6004,7 @@ getTableAttrs(TableInfo *tblinfo, int numTables)
appendPQExpBuffer(q, "SELECT tableoid, 0 AS oid, " appendPQExpBuffer(q, "SELECT tableoid, 0 AS oid, "
"rcname AS conname, " "rcname AS conname, "
"'CHECK (' || rcsrc || ')' AS consrc, " "'CHECK (' || rcsrc || ')' AS consrc, "
"true AS conislocal " "true AS conislocal, true AS convalidated "
"FROM pg_relcheck " "FROM pg_relcheck "
"WHERE rcrelid = '%u'::oid " "WHERE rcrelid = '%u'::oid "
"ORDER BY rcname", "ORDER BY rcname",
...@@ -6004,7 +6015,7 @@ getTableAttrs(TableInfo *tblinfo, int numTables) ...@@ -6004,7 +6015,7 @@ getTableAttrs(TableInfo *tblinfo, int numTables)
appendPQExpBuffer(q, "SELECT tableoid, oid, " appendPQExpBuffer(q, "SELECT tableoid, oid, "
"rcname AS conname, " "rcname AS conname, "
"'CHECK (' || rcsrc || ')' AS consrc, " "'CHECK (' || rcsrc || ')' AS consrc, "
"true AS conislocal " "true AS conislocal, true AS convalidated "
"FROM pg_relcheck " "FROM pg_relcheck "
"WHERE rcrelid = '%u'::oid " "WHERE rcrelid = '%u'::oid "
"ORDER BY rcname", "ORDER BY rcname",
...@@ -6017,7 +6028,7 @@ getTableAttrs(TableInfo *tblinfo, int numTables) ...@@ -6017,7 +6028,7 @@ getTableAttrs(TableInfo *tblinfo, int numTables)
"(SELECT oid FROM pg_class WHERE relname = 'pg_relcheck') AS tableoid, " "(SELECT oid FROM pg_class WHERE relname = 'pg_relcheck') AS tableoid, "
"oid, rcname AS conname, " "oid, rcname AS conname, "
"'CHECK (' || rcsrc || ')' AS consrc, " "'CHECK (' || rcsrc || ')' AS consrc, "
"true AS conislocal " "true AS conislocal, true AS convalidated "
"FROM pg_relcheck " "FROM pg_relcheck "
"WHERE rcrelid = '%u'::oid " "WHERE rcrelid = '%u'::oid "
"ORDER BY rcname", "ORDER BY rcname",
...@@ -6042,6 +6053,8 @@ getTableAttrs(TableInfo *tblinfo, int numTables) ...@@ -6042,6 +6053,8 @@ getTableAttrs(TableInfo *tblinfo, int numTables)
for (j = 0; j < numConstrs; j++) for (j = 0; j < numConstrs; j++)
{ {
bool validated = PQgetvalue(res, j, 5)[0] == 't';
constrs[j].dobj.objType = DO_CONSTRAINT; constrs[j].dobj.objType = DO_CONSTRAINT;
constrs[j].dobj.catId.tableoid = atooid(PQgetvalue(res, j, 0)); constrs[j].dobj.catId.tableoid = atooid(PQgetvalue(res, j, 0));
constrs[j].dobj.catId.oid = atooid(PQgetvalue(res, j, 1)); constrs[j].dobj.catId.oid = atooid(PQgetvalue(res, j, 1));
...@@ -6057,7 +6070,12 @@ getTableAttrs(TableInfo *tblinfo, int numTables) ...@@ -6057,7 +6070,12 @@ getTableAttrs(TableInfo *tblinfo, int numTables)
constrs[j].condeferrable = false; constrs[j].condeferrable = false;
constrs[j].condeferred = false; constrs[j].condeferred = false;
constrs[j].conislocal = (PQgetvalue(res, j, 4)[0] == 't'); constrs[j].conislocal = (PQgetvalue(res, j, 4)[0] == 't');
constrs[j].separate = false; /*
* An unvalidated constraint needs to be dumped separately, so
* that potentially-violating existing data is loaded before
* the constraint.
*/
constrs[j].separate = !validated;
constrs[j].dobj.dump = tbinfo->dobj.dump; constrs[j].dobj.dump = tbinfo->dobj.dump;
...@@ -6065,8 +6083,12 @@ getTableAttrs(TableInfo *tblinfo, int numTables) ...@@ -6065,8 +6083,12 @@ getTableAttrs(TableInfo *tblinfo, int numTables)
* Mark the constraint as needing to appear before the table * Mark the constraint as needing to appear before the table
* --- this is so that any other dependencies of the * --- this is so that any other dependencies of the
* constraint will be emitted before we try to create the * constraint will be emitted before we try to create the
* table. * table. If the constraint is not validated, it will be
* dumped after data is loaded anyway, so don't do it. (There's
* an automatic dependency in the opposite direction anyway, so
* don't need to add one manually here.)
*/ */
if (validated)
addObjectDependency(&tbinfo->dobj, addObjectDependency(&tbinfo->dobj,
constrs[j].dobj.dumpId); constrs[j].dobj.dumpId);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment