* --rows-per-insert were specified.
*/
if (dopt.do_nothing && dopt.dump_inserts == 0)
- fatal("option --on-conflict-do-nothing requires option --inserts, --rows-per-insert or --column-inserts");
+ fatal("option --on-conflict-do-nothing requires option --inserts, --rows-per-insert, or --column-inserts");
/* Identify archive format to emit */
archiveFormat = parseArchiveFormat(format, &archiveMode);
{
PQExpBuffer query = createPQExpBuffer();
- appendPQExpBuffer(query, "SET TRANSACTION SNAPSHOT ");
+ appendPQExpBufferStr(query, "SET TRANSACTION SNAPSHOT ");
appendStringLiteralConn(query, AH->sync_snapshot_id, conn);
ExecuteSqlStatement(AH, query->data);
destroyPQExpBuffer(query);
for (cell = patterns->head; cell; cell = cell->next)
{
- appendPQExpBuffer(query,
- "SELECT oid FROM pg_catalog.pg_namespace n\n");
+ appendPQExpBufferStr(query,
+ "SELECT oid FROM pg_catalog.pg_namespace n\n");
processSQLNamePattern(GetConnection(fout), query, cell->val, false,
false, NULL, "n.nspname", NULL, NULL);
appendPQExpBufferStr(creaQry, " ENCODING = ");
appendStringLiteralAH(creaQry, encoding, fout);
}
- if (strlen(collate) > 0)
+ if (strlen(collate) > 0 && strcmp(collate, ctype) == 0)
{
- appendPQExpBufferStr(creaQry, " LC_COLLATE = ");
+ appendPQExpBufferStr(creaQry, " LOCALE = ");
appendStringLiteralAH(creaQry, collate, fout);
}
- if (strlen(ctype) > 0)
+ else
{
- appendPQExpBufferStr(creaQry, " LC_CTYPE = ");
- appendStringLiteralAH(creaQry, ctype, fout);
+ if (strlen(collate) > 0)
+ {
+ appendPQExpBufferStr(creaQry, " LC_COLLATE = ");
+ appendStringLiteralAH(creaQry, collate, fout);
+ }
+ if (strlen(ctype) > 0)
+ {
+ appendPQExpBufferStr(creaQry, " LC_CTYPE = ");
+ appendStringLiteralAH(creaQry, ctype, fout);
+ }
}
/*
if (polinfo->polwithcheck != NULL)
appendPQExpBuffer(query, " WITH CHECK (%s)", polinfo->polwithcheck);
- appendPQExpBuffer(query, ";\n");
+ appendPQExpBufferStr(query, ";\n");
appendPQExpBuffer(delqry, "DROP POLICY %s", fmtId(polinfo->polname));
appendPQExpBuffer(delqry, " ON %s;\n", fmtQualifiedDumpable(tbinfo));
fmtQualifiedDumpable(tbinfo));
/*
- * There is no point in creating drop query as drop query as the drop is
- * done by table drop.
+ * There is no point in creating drop query as the drop is done by table
+ * drop.
*/
ArchiveEntry(fout, pubrinfo->dobj.catId, pubrinfo->dobj.dumpId,
ARCHIVE_OPTS(.tag = tag,
init_acl_subquery->data,
init_racl_subquery->data);
- appendPQExpBuffer(query, ") ");
+ appendPQExpBufferStr(query, ") ");
destroyPQExpBuffer(acl_subquery);
destroyPQExpBuffer(racl_subquery);
query = createPQExpBuffer();
/* Select all access methods from pg_am table */
- appendPQExpBuffer(query, "SELECT tableoid, oid, amname, amtype, "
- "amhandler::pg_catalog.regproc AS amhandler "
- "FROM pg_am");
+ appendPQExpBufferStr(query, "SELECT tableoid, oid, amname, amtype, "
+ "amhandler::pg_catalog.regproc AS amhandler "
+ "FROM pg_am");
res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
"tc.relminmxid AS tminmxid, "
"c.relpersistence, c.relispopulated, "
"c.relreplident, c.relpages, "
+ "NULL AS amname, "
"CASE WHEN c.reloftype <> 0 THEN c.reloftype::pg_catalog.regtype ELSE NULL END AS reloftype, "
"d.refobjid AS owning_tab, "
"d.refobjsubid AS owning_col, "
"tc.relminmxid AS tminmxid, "
"c.relpersistence, c.relispopulated, "
"c.relreplident, c.relpages, "
+ "NULL AS amname, "
"CASE WHEN c.reloftype <> 0 THEN c.reloftype::pg_catalog.regtype ELSE NULL END AS reloftype, "
"d.refobjid AS owning_tab, "
"d.refobjsubid AS owning_col, "
"tc.relminmxid AS tminmxid, "
"c.relpersistence, c.relispopulated, "
"'d' AS relreplident, c.relpages, "
+ "NULL AS amname, "
"CASE WHEN c.reloftype <> 0 THEN c.reloftype::pg_catalog.regtype ELSE NULL END AS reloftype, "
"d.refobjid AS owning_tab, "
"d.refobjsubid AS owning_col, "
"0 AS tminmxid, "
"c.relpersistence, 't' as relispopulated, "
"'d' AS relreplident, c.relpages, "
+ "NULL AS amname, "
"CASE WHEN c.reloftype <> 0 THEN c.reloftype::pg_catalog.regtype ELSE NULL END AS reloftype, "
"d.refobjid AS owning_tab, "
"d.refobjsubid AS owning_col, "
"0 AS tminmxid, "
"'p' AS relpersistence, 't' as relispopulated, "
"'d' AS relreplident, c.relpages, "
+ "NULL AS amname, "
"CASE WHEN c.reloftype <> 0 THEN c.reloftype::pg_catalog.regtype ELSE NULL END AS reloftype, "
"d.refobjid AS owning_tab, "
"d.refobjsubid AS owning_col, "
"0 AS tminmxid, "
"'p' AS relpersistence, 't' as relispopulated, "
"'d' AS relreplident, c.relpages, "
+ "NULL AS amname, "
"NULL AS reloftype, "
"d.refobjid AS owning_tab, "
"d.refobjsubid AS owning_col, "
"0 AS tminmxid, "
"'p' AS relpersistence, 't' as relispopulated, "
"'d' AS relreplident, c.relpages, "
+ "NULL AS amname, "
"NULL AS reloftype, "
"d.refobjid AS owning_tab, "
"d.refobjsubid AS owning_col, "
"0 AS tfrozenxid, 0 AS tminmxid,"
"'p' AS relpersistence, 't' as relispopulated, "
"'d' AS relreplident, relpages, "
+ "NULL AS amname, "
"NULL AS reloftype, "
"d.refobjid AS owning_tab, "
"d.refobjsubid AS owning_col, "
/*
* Find all the inheritance information, excluding implicit inheritance
- * via partitioning. We handle that case using getPartitions(), because
- * we want more information about partitions than just the parent-child
- * relationship.
+ * via partitioning.
*/
appendPQExpBufferStr(query, "SELECT inhrelid, inhparent FROM pg_inherits");
query = createPQExpBuffer();
- appendPQExpBuffer(query, "SELECT tableoid, oid, "
- "trftype, trflang, trffromsql::oid, trftosql::oid "
- "FROM pg_transform "
- "ORDER BY 3,4");
+ appendPQExpBufferStr(query, "SELECT tableoid, oid, "
+ "trftype, trflang, trffromsql::oid, trftosql::oid "
+ "FROM pg_transform "
+ "ORDER BY 3,4");
res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
resetPQExpBuffer(q);
- appendPQExpBuffer(q,
- "SELECT\n"
- "a.attnum,\n"
- "a.attname,\n"
- "a.atttypmod,\n"
- "a.attstattarget,\n"
- "a.attstorage,\n"
- "t.typstorage,\n"
- "a.attnotnull,\n"
- "a.atthasdef,\n"
- "a.attisdropped,\n"
- "a.attlen,\n"
- "a.attalign,\n"
- "a.attislocal,\n"
- "pg_catalog.format_type(t.oid, a.atttypmod) AS atttypname,\n");
+ appendPQExpBufferStr(q,
+ "SELECT\n"
+ "a.attnum,\n"
+ "a.attname,\n"
+ "a.atttypmod,\n"
+ "a.attstattarget,\n"
+ "a.attstorage,\n"
+ "t.typstorage,\n"
+ "a.attnotnull,\n"
+ "a.atthasdef,\n"
+ "a.attisdropped,\n"
+ "a.attlen,\n"
+ "a.attalign,\n"
+ "a.attislocal,\n"
+ "pg_catalog.format_type(t.oid, a.atttypmod) AS atttypname,\n");
if (fout->remoteVersion >= 120000)
- appendPQExpBuffer(q,
- "a.attgenerated,\n");
+ appendPQExpBufferStr(q,
+ "a.attgenerated,\n");
else
- appendPQExpBuffer(q,
- "'' AS attgenerated,\n");
+ appendPQExpBufferStr(q,
+ "'' AS attgenerated,\n");
if (fout->remoteVersion >= 110000)
- appendPQExpBuffer(q,
- "CASE WHEN a.atthasmissing AND NOT a.attisdropped "
- "THEN a.attmissingval ELSE null END AS attmissingval,\n");
+ appendPQExpBufferStr(q,
+ "CASE WHEN a.atthasmissing AND NOT a.attisdropped "
+ "THEN a.attmissingval ELSE null END AS attmissingval,\n");
else
- appendPQExpBuffer(q,
- "NULL AS attmissingval,\n");
+ appendPQExpBufferStr(q,
+ "NULL AS attmissingval,\n");
if (fout->remoteVersion >= 100000)
- appendPQExpBuffer(q,
- "a.attidentity,\n");
+ appendPQExpBufferStr(q,
+ "a.attidentity,\n");
else
- appendPQExpBuffer(q,
- "'' AS attidentity,\n");
+ appendPQExpBufferStr(q,
+ "'' AS attidentity,\n");
if (fout->remoteVersion >= 90200)
- appendPQExpBuffer(q,
- "pg_catalog.array_to_string(ARRAY("
- "SELECT pg_catalog.quote_ident(option_name) || "
- "' ' || pg_catalog.quote_literal(option_value) "
- "FROM pg_catalog.pg_options_to_table(attfdwoptions) "
- "ORDER BY option_name"
- "), E',\n ') AS attfdwoptions,\n");
+ appendPQExpBufferStr(q,
+ "pg_catalog.array_to_string(ARRAY("
+ "SELECT pg_catalog.quote_ident(option_name) || "
+ "' ' || pg_catalog.quote_literal(option_value) "
+ "FROM pg_catalog.pg_options_to_table(attfdwoptions) "
+ "ORDER BY option_name"
+ "), E',\n ') AS attfdwoptions,\n");
else
- appendPQExpBuffer(q,
- "'' AS attfdwoptions,\n");
+ appendPQExpBufferStr(q,
+ "'' AS attfdwoptions,\n");
if (fout->remoteVersion >= 90100)
{
* collation is different from their type's default, we use a CASE
* here to suppress uninteresting attcollations cheaply.
*/
- appendPQExpBuffer(q,
- "CASE WHEN a.attcollation <> t.typcollation "
- "THEN a.attcollation ELSE 0 END AS attcollation,\n");
+ appendPQExpBufferStr(q,
+ "CASE WHEN a.attcollation <> t.typcollation "
+ "THEN a.attcollation ELSE 0 END AS attcollation,\n");
}
else
- appendPQExpBuffer(q,
- "0 AS attcollation,\n");
+ appendPQExpBufferStr(q,
+ "0 AS attcollation,\n");
if (fout->remoteVersion >= 90000)
- appendPQExpBuffer(q,
- "array_to_string(a.attoptions, ', ') AS attoptions\n");
+ appendPQExpBufferStr(q,
+ "array_to_string(a.attoptions, ', ') AS attoptions\n");
else
- appendPQExpBuffer(q,
- "'' AS attoptions\n");
+ appendPQExpBufferStr(q,
+ "'' AS attoptions\n");
/* need left join here to not fail on dropped columns ... */
appendPQExpBuffer(q,
* Normally this is always true, but it's false for dropped columns, as well
* as those that were inherited without any local definition. (If we print
* such a column it will mistakenly get pg_attribute.attislocal set to true.)
- * However, in binary_upgrade mode, we must print all such columns anyway and
- * fix the attislocal/attisdropped state later, so as to keep control of the
- * physical column order.
+ * For partitions, it's always true, because we want the partitions to be
+ * created independently and ATTACH PARTITION used afterwards.
+ *
+ * In binary_upgrade mode, we must print all columns and fix the attislocal/
+ * attisdropped state later, so as to keep control of the physical column
+ * order.
*
* This function exists because there are scattered nonobvious places that
* must be kept in sync with this decision.
{
if (dopt->binary_upgrade)
return true;
- return (tbinfo->attislocal[colno] && !tbinfo->attisdropped[colno]);
+ if (tbinfo->attisdropped[colno])
+ return false;
+ return (tbinfo->attislocal[colno] || tbinfo->ispartition);
}
if (transform->trftosql)
{
if (transform->trffromsql)
- appendPQExpBuffer(defqry, ", ");
+ appendPQExpBufferStr(defqry, ", ");
if (tosqlFuncInfo)
{
pg_log_warning("bogus value in pg_transform.trftosql field");
}
- appendPQExpBuffer(defqry, ");\n");
+ appendPQExpBufferStr(defqry, ");\n");
appendPQExpBuffer(labelq, "TRANSFORM FOR %s LANGUAGE %s",
transformType, lanname);
switch (aminfo->amtype)
{
case AMTYPE_INDEX:
- appendPQExpBuffer(q, "TYPE INDEX ");
+ appendPQExpBufferStr(q, "TYPE INDEX ");
break;
case AMTYPE_TABLE:
- appendPQExpBuffer(q, "TYPE TABLE ");
+ appendPQExpBufferStr(q, "TYPE TABLE ");
break;
default:
pg_log_warning("invalid type \"%c\" of access method \"%s\"",
qcollname = pg_strdup(fmtId(collinfo->dobj.name));
/* Get collation-specific details */
- appendPQExpBuffer(query, "SELECT ");
+ appendPQExpBufferStr(query, "SELECT ");
if (fout->remoteVersion >= 100000)
- appendPQExpBuffer(query,
- "collprovider, "
- "collversion, ");
+ appendPQExpBufferStr(query,
+ "collprovider, "
+ "collversion, ");
else
- appendPQExpBuffer(query,
- "'c' AS collprovider, "
- "NULL AS collversion, ");
+ appendPQExpBufferStr(query,
+ "'c' AS collprovider, "
+ "NULL AS collversion, ");
if (fout->remoteVersion >= 120000)
- appendPQExpBuffer(query,
- "collisdeterministic, ");
+ appendPQExpBufferStr(query,
+ "collisdeterministic, ");
else
- appendPQExpBuffer(query,
- "true AS collisdeterministic, ");
+ appendPQExpBufferStr(query,
+ "true AS collisdeterministic, ");
appendPQExpBuffer(query,
"collcollate, "
/* to allow dumping pg_catalog; not accepted on input */
appendPQExpBufferStr(q, "default");
else
- fatal("unrecognized collation provider: %s\n",
+ fatal("unrecognized collation provider: %s",
collprovider);
if (strcmp(PQgetvalue(res, 0, i_collisdeterministic), "f") == 0)
appendPQExpBufferStr(&buf, agginfo->aggfn.dobj.name);
if (agginfo->aggfn.nargs == 0)
- appendPQExpBuffer(&buf, "(*)");
+ appendPQExpBufferStr(&buf, "(*)");
else
{
appendPQExpBufferChar(&buf, '(');
*/
if (strlen(initacls) != 0 || strlen(initracls) != 0)
{
- appendPQExpBuffer(sql, "SELECT pg_catalog.binary_upgrade_set_record_init_privs(true);\n");
+ appendPQExpBufferStr(sql, "SELECT pg_catalog.binary_upgrade_set_record_init_privs(true);\n");
if (!buildACLCommands(name, subname, nspname, type,
initacls, initracls, owner,
"", fout->remoteVersion, sql))
fatal("could not parse initial GRANT ACL list (%s) or initial REVOKE ACL list (%s) for object \"%s\" (%s)",
initacls, initracls, name, type);
- appendPQExpBuffer(sql, "SELECT pg_catalog.binary_upgrade_set_record_init_privs(false);\n");
+ appendPQExpBufferStr(sql, "SELECT pg_catalog.binary_upgrade_set_record_init_privs(false);\n");
}
if (!buildACLCommands(name, subname, nspname, type,
if (tbinfo->reloftype && !dopt->binary_upgrade)
appendPQExpBuffer(q, " OF %s", tbinfo->reloftype);
- /*
- * If the table is a partition, dump it as such; except in the case of
- * a binary upgrade, we dump the table normally and attach it to the
- * parent afterward.
- */
- if (tbinfo->ispartition && !dopt->binary_upgrade)
- {
- TableInfo *parentRel = tbinfo->parents[0];
-
- /*
- * With partitions, unlike inheritance, there can only be one
- * parent.
- */
- if (tbinfo->numParents != 1)
- fatal("invalid number of parents %d for table \"%s\"",
- tbinfo->numParents, tbinfo->dobj.name);
-
- appendPQExpBuffer(q, " PARTITION OF %s",
- fmtQualifiedDumpable(parentRel));
- }
-
if (tbinfo->relkind != RELKIND_MATVIEW)
{
/* Dump the attributes */
*/
if (shouldPrintColumn(dopt, tbinfo, j))
{
+ bool print_default;
+ bool print_notnull;
+
/*
* Default value --- suppress if to be printed separately.
*/
- bool has_default = (tbinfo->attrdefs[j] != NULL &&
- !tbinfo->attrdefs[j]->separate);
+ print_default = (tbinfo->attrdefs[j] != NULL &&
+ !tbinfo->attrdefs[j]->separate);
/*
* Not Null constraint --- suppress if inherited, except
- * in binary-upgrade case where that won't work.
+ * if partition, or in binary-upgrade case where that
+ * won't work.
*/
- bool has_notnull = (tbinfo->notnull[j] &&
- (!tbinfo->inhNotNull[j] ||
- dopt->binary_upgrade));
+ print_notnull = (tbinfo->notnull[j] &&
+ (!tbinfo->inhNotNull[j] ||
+ tbinfo->ispartition || dopt->binary_upgrade));
/*
- * Skip column if fully defined by reloftype or the
- * partition parent.
+ * Skip column if fully defined by reloftype, except in
+ * binary upgrade
*/
- if ((tbinfo->reloftype || tbinfo->ispartition) &&
- !has_default && !has_notnull && !dopt->binary_upgrade)
+ if (tbinfo->reloftype && !print_default && !print_notnull &&
+ !dopt->binary_upgrade)
continue;
/* Format properly if not first attr */
* clean things up later.
*/
appendPQExpBufferStr(q, " INTEGER /* dummy */");
- /* Skip all the rest, too */
+ /* and skip to the next column */
continue;
}
/*
- * Attribute type
- *
- * In binary-upgrade mode, we always include the type. If
- * we aren't in binary-upgrade mode, then we skip the type
- * when creating a typed table ('OF type_name') or a
- * partition ('PARTITION OF'), since the type comes from
- * the parent/partitioned table.
+ * Attribute type; print it except when creating a typed
+ * table ('OF type_name'), but in binary-upgrade mode,
+ * print it in that case too.
*/
- if (dopt->binary_upgrade || (!tbinfo->reloftype && !tbinfo->ispartition))
+ if (dopt->binary_upgrade || !tbinfo->reloftype)
{
appendPQExpBuffer(q, " %s",
tbinfo->atttypnames[j]);
}
- if (has_default)
+ if (print_default)
{
if (tbinfo->attgenerated[j] == ATTRIBUTE_GENERATED_STORED)
appendPQExpBuffer(q, " GENERATED ALWAYS AS (%s) STORED",
}
- if (has_notnull)
+ if (print_notnull)
appendPQExpBufferStr(q, " NOT NULL");
/* Add collation if not default for the type */
/*
* Add non-inherited CHECK constraints, if any.
+ *
+ * For partitions, we need to include check constraints even if
+ * they're not defined locally, because the ALTER TABLE ATTACH
+ * PARTITION that we'll emit later expects the constraint to be
+ * there. (No need to fix conislocal: ATTACH PARTITION does that)
*/
for (j = 0; j < tbinfo->ncheck; j++)
{
ConstraintInfo *constr = &(tbinfo->checkexprs[j]);
- if (constr->separate || !constr->conislocal)
+ if (constr->separate ||
+ (!constr->conislocal && !tbinfo->ispartition))
continue;
if (actual_atts == 0)
if (actual_atts)
appendPQExpBufferStr(q, "\n)");
- else if (!((tbinfo->reloftype || tbinfo->ispartition) &&
- !dopt->binary_upgrade))
+ else if (!(tbinfo->reloftype && !dopt->binary_upgrade))
{
/*
- * We must have a parenthesized attribute list, even though
- * empty, when not using the OF TYPE or PARTITION OF syntax.
+ * No attributes? we must have a parenthesized attribute list,
+ * even though empty, when not using the OF TYPE syntax.
*/
appendPQExpBufferStr(q, " (\n)");
}
- if (tbinfo->ispartition && !dopt->binary_upgrade)
- {
- appendPQExpBufferChar(q, '\n');
- appendPQExpBufferStr(q, tbinfo->partbound);
- }
-
- /* Emit the INHERITS clause, except if this is a partition. */
- if (numParents > 0 &&
- !tbinfo->ispartition &&
+ /*
+ * Emit the INHERITS clause (not for partitions), except in
+ * binary-upgrade mode.
+ */
+ if (numParents > 0 && !tbinfo->ispartition &&
!dopt->binary_upgrade)
{
appendPQExpBufferStr(q, "\nINHERITS (");
}
}
+ /*
+ * Add inherited CHECK constraints, if any.
+ *
+ * For partitions, they were already dumped, and conislocal
+ * doesn't need fixing.
+ */
for (k = 0; k < tbinfo->ncheck; k++)
{
ConstraintInfo *constr = &(tbinfo->checkexprs[k]);
- if (constr->separate || constr->conislocal)
+ if (constr->separate || constr->conislocal || tbinfo->ispartition)
continue;
appendPQExpBufferStr(q, "\n-- For binary upgrade, set up inherited constraint.\n");
appendPQExpBufferStr(q, "::pg_catalog.regclass;\n");
}
- if (numParents > 0)
+ if (numParents > 0 && !tbinfo->ispartition)
{
- appendPQExpBufferStr(q, "\n-- For binary upgrade, set up inheritance and partitioning this way.\n");
+ appendPQExpBufferStr(q, "\n-- For binary upgrade, set up inheritance this way.\n");
for (k = 0; k < numParents; k++)
{
TableInfo *parentRel = parents[k];
- /* In the partitioning case, we alter the parent */
- if (tbinfo->ispartition)
- appendPQExpBuffer(q,
- "ALTER TABLE ONLY %s ATTACH PARTITION ",
- fmtQualifiedDumpable(parentRel));
- else
- appendPQExpBuffer(q, "ALTER TABLE ONLY %s INHERIT ",
- qualrelname);
-
- /* Partition needs specifying the bounds */
- if (tbinfo->ispartition)
- appendPQExpBuffer(q, "%s %s;\n",
- qualrelname,
- tbinfo->partbound);
- else
- appendPQExpBuffer(q, "%s;\n",
- fmtQualifiedDumpable(parentRel));
+ appendPQExpBuffer(q, "ALTER TABLE ONLY %s INHERIT %s;\n",
+ qualrelname,
+ fmtQualifiedDumpable(parentRel));
}
}
}
}
+ /*
+ * For partitioned tables, emit the ATTACH PARTITION clause. Note
+ * that we always want to create partitions this way instead of using
+ * CREATE TABLE .. PARTITION OF, mainly to preserve a possible column
+ * layout discrepancy with the parent, but also to ensure it gets the
+ * correct tablespace setting if it differs from the parent's.
+ */
+ if (tbinfo->ispartition)
+ {
+ /* With partitions there can only be one parent */
+ if (tbinfo->numParents != 1)
+ fatal("invalid number of parents %d for table \"%s\"",
+ tbinfo->numParents, tbinfo->dobj.name);
+
+ /* Perform ALTER TABLE on the parent */
+ appendPQExpBuffer(q,
+ "ALTER TABLE ONLY %s ATTACH PARTITION %s %s;\n",
+ fmtQualifiedDumpable(parents[0]),
+ qualrelname, tbinfo->partbound);
+ }
+
/*
* In binary_upgrade mode, arrange to restore the old relfrozenxid and
* relminmxid of all vacuumable relations. (While vacuum.c processes
}
if (indxinfo->indnkeyattrs < indxinfo->indnattrs)
- appendPQExpBuffer(q, ") INCLUDE (");
+ appendPQExpBufferStr(q, ") INCLUDE (");
for (k = indxinfo->indnkeyattrs; k < indxinfo->indnattrs; k++)
{
"ALTER COLUMN %s ADD GENERATED ",
fmtId(owning_tab->attnames[tbinfo->owning_col - 1]));
if (owning_tab->attidentity[tbinfo->owning_col - 1] == ATTRIBUTE_IDENTITY_ALWAYS)
- appendPQExpBuffer(query, "ALWAYS");
+ appendPQExpBufferStr(query, "ALWAYS");
else if (owning_tab->attidentity[tbinfo->owning_col - 1] == ATTRIBUTE_IDENTITY_BY_DEFAULT)
- appendPQExpBuffer(query, "BY DEFAULT");
+ appendPQExpBufferStr(query, "BY DEFAULT");
appendPQExpBuffer(query, " AS IDENTITY (\n SEQUENCE NAME %s\n",
fmtQualifiedDumpable(tbinfo));
}
query = createPQExpBuffer();
/*
+ * Messy query to collect the dependency data we need. Note that we
+ * ignore the sub-object column, so that dependencies of or on a column
+ * look the same as dependencies of or on a whole table.
+ *
* PIN dependencies aren't interesting, and EXTENSION dependencies were
* already processed by getExtensionMembership.
*/
appendPQExpBufferStr(query, "SELECT "
"classid, objid, refclassid, refobjid, deptype "
"FROM pg_depend "
- "WHERE deptype != 'p' AND deptype != 'e' "
- "ORDER BY 1,2");
+ "WHERE deptype != 'p' AND deptype != 'e'\n");
+
+ /*
+ * Since we don't treat pg_amop entries as separate DumpableObjects, we
+ * have to translate their dependencies into dependencies of their parent
+ * opfamily. Ignore internal dependencies though, as those will point to
+ * their parent opclass, which we needn't consider here (and if we did,
+ * it'd just result in circular dependencies). Also, "loose" opfamily
+ * entries will have dependencies on their parent opfamily, which we
+ * should drop since they'd likewise become useless self-dependencies.
+ * (But be sure to keep deps on *other* opfamilies; see amopsortfamily.)
+ *
+ * Skip this for pre-8.3 source servers: pg_opfamily doesn't exist there,
+ * and the (known) cases where it would matter to have these dependencies
+ * can't arise anyway.
+ */
+ if (fout->remoteVersion >= 80300)
+ {
+ appendPQExpBufferStr(query, "UNION ALL\n"
+ "SELECT 'pg_opfamily'::regclass AS classid, amopfamily AS objid, refclassid, refobjid, deptype "
+ "FROM pg_depend d, pg_amop o "
+ "WHERE deptype NOT IN ('p', 'e', 'i') AND "
+ "classid = 'pg_amop'::regclass AND objid = o.oid "
+ "AND NOT (refclassid = 'pg_opfamily'::regclass AND amopfamily = refobjid)\n");
+
+ /* Likewise for pg_amproc entries */
+ appendPQExpBufferStr(query, "UNION ALL\n"
+ "SELECT 'pg_opfamily'::regclass AS classid, amprocfamily AS objid, refclassid, refobjid, deptype "
+ "FROM pg_depend d, pg_amproc p "
+ "WHERE deptype NOT IN ('p', 'e', 'i') AND "
+ "classid = 'pg_amproc'::regclass AND objid = p.oid "
+ "AND NOT (refclassid = 'pg_opfamily'::regclass AND amprocfamily = refobjid)\n");
+ }
+
+ /* Sort the output for efficiency below */
+ appendPQExpBufferStr(query, "ORDER BY 1,2");
res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);