@@ -8103,6 +8103,7 @@ getTableAttrs(Archive *fout, TableInfo *tblinfo, int numTables)
8103
8103
inti_attoptions;
8104
8104
inti_attcollation;
8105
8105
inti_attfdwoptions;
8106
+ inti_attmissingval;
8106
8107
PGresult *res;
8107
8108
intntups;
8108
8109
boolhasdefaults;
@@ -8132,7 +8133,34 @@ getTableAttrs(Archive *fout, TableInfo *tblinfo, int numTables)
8132
8133
8133
8134
resetPQExpBuffer(q);
8134
8135
8135
- if (fout->remoteVersion >= 100000)
8136
+ if (fout->remoteVersion >= 110000)
8137
+ {
8138
+ /* atthasmissing and attmissingval are new in 11 */
8139
+ appendPQExpBuffer(q, "SELECT a.attnum, a.attname, a.atttypmod, "
8140
+ "a.attstattarget, a.attstorage, t.typstorage, "
8141
+ "a.attnotnull, a.atthasdef, a.attisdropped, "
8142
+ "a.attlen, a.attalign, a.attislocal, "
8143
+ "pg_catalog.format_type(t.oid,a.atttypmod) AS atttypname, "
8144
+ "array_to_string(a.attoptions, ', ') AS attoptions, "
8145
+ "CASE WHEN a.attcollation <> t.typcollation "
8146
+ "THEN a.attcollation ELSE 0 END AS attcollation, "
8147
+ "a.attidentity, "
8148
+ "pg_catalog.array_to_string(ARRAY("
8149
+ "SELECT pg_catalog.quote_ident(option_name) || "
8150
+ "' ' || pg_catalog.quote_literal(option_value) "
8151
+ "FROM pg_catalog.pg_options_to_table(attfdwoptions) "
8152
+ "ORDER BY option_name"
8153
+ "), E',\n ') AS attfdwoptions ,"
8154
+ "CASE WHEN a.atthasmissing AND NOT a.attisdropped "
8155
+ "THEN a.attmissingval ELSE null END AS attmissingval "
8156
+ "FROM pg_catalog.pg_attribute a LEFT JOIN pg_catalog.pg_type t "
8157
+ "ON a.atttypid = t.oid "
8158
+ "WHERE a.attrelid = '%u'::pg_catalog.oid "
8159
+ "AND a.attnum > 0::pg_catalog.int2 "
8160
+ "ORDER BY a.attnum",
8161
+ tbinfo->dobj.catId.oid);
8162
+ }
8163
+ else if (fout->remoteVersion >= 100000)
8136
8164
{
8137
8165
/*
8138
8166
* attidentity is new in version 10.
@@ -8151,7 +8179,8 @@ getTableAttrs(Archive *fout, TableInfo *tblinfo, int numTables)
8151
8179
"' ' || pg_catalog.quote_literal(option_value) "
8152
8180
"FROM pg_catalog.pg_options_to_table(attfdwoptions) "
8153
8181
"ORDER BY option_name"
8154
- "), E',\n ') AS attfdwoptions "
8182
+ "), E',\n ') AS attfdwoptions ,"
8183
+ "NULL as attmissingval "
8155
8184
"FROM pg_catalog.pg_attribute a LEFT JOIN pg_catalog.pg_type t "
8156
8185
"ON a.atttypid = t.oid "
8157
8186
"WHERE a.attrelid = '%u'::pg_catalog.oid "
@@ -8177,7 +8206,8 @@ getTableAttrs(Archive *fout, TableInfo *tblinfo, int numTables)
8177
8206
"' ' || pg_catalog.quote_literal(option_value) "
8178
8207
"FROM pg_catalog.pg_options_to_table(attfdwoptions) "
8179
8208
"ORDER BY option_name"
8180
- "), E',\n ') AS attfdwoptions "
8209
+ "), E',\n ') AS attfdwoptions, "
8210
+ "NULL as attmissingval "
8181
8211
"FROM pg_catalog.pg_attribute a LEFT JOIN pg_catalog.pg_type t "
8182
8212
"ON a.atttypid = t.oid "
8183
8213
"WHERE a.attrelid = '%u'::pg_catalog.oid "
@@ -8201,7 +8231,8 @@ getTableAttrs(Archive *fout, TableInfo *tblinfo, int numTables)
8201
8231
"array_to_string(a.attoptions, ', ') AS attoptions, "
8202
8232
"CASE WHEN a.attcollation <> t.typcollation "
8203
8233
"THEN a.attcollation ELSE 0 END AS attcollation, "
8204
- "NULL AS attfdwoptions "
8234
+ "NULL AS attfdwoptions, "
8235
+ "NULL as attmissingval "
8205
8236
"FROM pg_catalog.pg_attribute a LEFT JOIN pg_catalog.pg_type t "
8206
8237
"ON a.atttypid = t.oid "
8207
8238
"WHERE a.attrelid = '%u'::pg_catalog.oid "
@@ -8219,7 +8250,8 @@ getTableAttrs(Archive *fout, TableInfo *tblinfo, int numTables)
8219
8250
"pg_catalog.format_type(t.oid,a.atttypmod) AS atttypname, "
8220
8251
"array_to_string(a.attoptions, ', ') AS attoptions, "
8221
8252
"0 AS attcollation, "
8222
- "NULL AS attfdwoptions "
8253
+ "NULL AS attfdwoptions, "
8254
+ "NULL as attmissingval "
8223
8255
"FROM pg_catalog.pg_attribute a LEFT JOIN pg_catalog.pg_type t "
8224
8256
"ON a.atttypid = t.oid "
8225
8257
"WHERE a.attrelid = '%u'::pg_catalog.oid "
@@ -8236,7 +8268,8 @@ getTableAttrs(Archive *fout, TableInfo *tblinfo, int numTables)
8236
8268
"a.attlen, a.attalign, a.attislocal, "
8237
8269
"pg_catalog.format_type(t.oid,a.atttypmod) AS atttypname, "
8238
8270
"'' AS attoptions, 0 AS attcollation, "
8239
- "NULL AS attfdwoptions "
8271
+ "NULL AS attfdwoptions, "
8272
+ "NULL as attmissingval "
8240
8273
"FROM pg_catalog.pg_attribute a LEFT JOIN pg_catalog.pg_type t "
8241
8274
"ON a.atttypid = t.oid "
8242
8275
"WHERE a.attrelid = '%u'::pg_catalog.oid "
@@ -8266,6 +8299,7 @@ getTableAttrs(Archive *fout, TableInfo *tblinfo, int numTables)
8266
8299
i_attoptions = PQfnumber(res, "attoptions");
8267
8300
i_attcollation = PQfnumber(res, "attcollation");
8268
8301
i_attfdwoptions = PQfnumber(res, "attfdwoptions");
8302
+ i_attmissingval = PQfnumber(res, "attmissingval");
8269
8303
8270
8304
tbinfo->numatts = ntups;
8271
8305
tbinfo->attnames = (char **) pg_malloc(ntups * sizeof(char *));
@@ -8282,6 +8316,7 @@ getTableAttrs(Archive *fout, TableInfo *tblinfo, int numTables)
8282
8316
tbinfo->attoptions = (char **) pg_malloc(ntups * sizeof(char *));
8283
8317
tbinfo->attcollation = (Oid *) pg_malloc(ntups * sizeof(Oid));
8284
8318
tbinfo->attfdwoptions = (char **) pg_malloc(ntups * sizeof(char *));
8319
+ tbinfo->attmissingval = (char **) pg_malloc(ntups * sizeof(char *));
8285
8320
tbinfo->notnull = (bool *) pg_malloc(ntups * sizeof(bool));
8286
8321
tbinfo->inhNotNull = (bool *) pg_malloc(ntups * sizeof(bool));
8287
8322
tbinfo->attrdefs = (AttrDefInfo **) pg_malloc(ntups * sizeof(AttrDefInfo *));
@@ -8309,6 +8344,7 @@ getTableAttrs(Archive *fout, TableInfo *tblinfo, int numTables)
8309
8344
tbinfo->attoptions[j] = pg_strdup(PQgetvalue(res, j, i_attoptions));
8310
8345
tbinfo->attcollation[j] = atooid(PQgetvalue(res, j, i_attcollation));
8311
8346
tbinfo->attfdwoptions[j] = pg_strdup(PQgetvalue(res, j, i_attfdwoptions));
8347
+ tbinfo->attmissingval[j] = pg_strdup(PQgetvalue(res, j, i_attmissingval));
8312
8348
tbinfo->attrdefs[j] = NULL; /* fix below */
8313
8349
if (PQgetvalue(res, j, i_atthasdef)[0] == 't')
8314
8350
hasdefaults = true;
@@ -15658,6 +15694,29 @@ dumpTableSchema(Archive *fout, TableInfo *tbinfo)
15658
15694
else
15659
15695
appendPQExpBufferStr(q, ";\n");
15660
15696
15697
+ /*
15698
+ * in binary upgrade mode, update the catalog with any missing values
15699
+ * that might be present.
15700
+ */
15701
+ if (dopt->binary_upgrade)
15702
+ {
15703
+ for (j = 0; j < tbinfo->numatts; j++)
15704
+ {
15705
+ if (tbinfo->attmissingval[j][0] != '\0')
15706
+ {
15707
+ appendPQExpBufferStr(q, "\n-- set missing value.\n");
15708
+ appendPQExpBufferStr(q,
15709
+ "SELECT pg_catalog.binary_upgrade_set_missing_value(");
15710
+ appendStringLiteralAH(q, qualrelname, fout);
15711
+ appendPQExpBufferStr(q, "::pg_catalog.regclass,");
15712
+ appendStringLiteralAH(q, tbinfo->attnames[j], fout);
15713
+ appendPQExpBufferStr(q, ",");
15714
+ appendStringLiteralAH(q, tbinfo->attmissingval[j], fout);
15715
+ appendPQExpBufferStr(q, ");\n\n");
15716
+ }
15717
+ }
15718
+ }
15719
+
15661
15720
/*
15662
15721
* To create binary-compatible heap files, we have to ensure the same
15663
15722
* physical column order, including dropped columns, as in the