From 096f95f79bcb74a3b4996161fc16e5dea3abce7f Mon Sep 17 00:00:00 2001 From: tanin <@tanin> Date: Fri, 2 May 2025 22:56:51 -0700 Subject: [PATCH] pg_dump to support 'on conflict update' --- doc/src/sgml/ref/pg_dump.sgml | 26 ++++++++++++++++++++++++++ src/bin/pg_dump/pg_dump.c | 24 ++++++++++++++++++++++++ 2 files changed, 50 insertions(+) diff --git a/doc/src/sgml/ref/pg_dump.sgml b/doc/src/sgml/ref/pg_dump.sgml index c10bca63e55..b9f4bedc812 100644 --- a/doc/src/sgml/ref/pg_dump.sgml +++ b/doc/src/sgml/ref/pg_dump.sgml @@ -1234,6 +1234,32 @@ PostgreSQL documentation + + + + + Add ON CONFLICT (target-columns) DO UPDATE ... to + INSERT commands. + This option must be used with , and with + , or . + The option cannot be used with . + + + + + + + + + Add ON CONFLICT ... DO UPDATE update-clause to + INSERT commands. + This option must be used with , and with + , or . + The option cannot be used with . + + + + diff --git a/src/bin/pg_dump/pg_dump.c b/src/bin/pg_dump/pg_dump.c index e2e7975b34e..1efcc491d58 100644 --- a/src/bin/pg_dump/pg_dump.c +++ b/src/bin/pg_dump/pg_dump.c @@ -183,6 +183,9 @@ static SimpleOidList extension_include_oids = {NULL, NULL}; static SimpleStringList extension_exclude_patterns = {NULL, NULL}; static SimpleOidList extension_exclude_oids = {NULL, NULL}; +static const char *on_conflict_target_columns = NULL; +static const char *on_conflict_update_clause = NULL; + static const CatalogId nilCatalogId = {0, 0}; /* override for standard extra_float_digits setting */ @@ -521,6 +524,8 @@ main(int argc, char **argv) {"with-schema", no_argument, NULL, 23}, {"with-statistics", no_argument, NULL, 24}, {"on-conflict-do-nothing", no_argument, &dopt.do_nothing, 1}, + {"on-conflict-target-columns", required_argument, NULL, 25}, + {"on-conflict-update-clause", required_argument, NULL, 26}, {"rows-per-insert", required_argument, NULL, 10}, {"include-foreign-data", required_argument, NULL, 11}, {"table-and-children", required_argument, NULL, 12}, @@ -796,6 +801,13 @@ main(int argc, char **argv) case 24: with_statistics = true; + + case 25: + on_conflict_target_columns = pg_strdup(optarg); + break; + + case 26: + on_conflict_update_clause = pg_strdup(optarg); break; default: @@ -883,6 +895,12 @@ main(int argc, char **argv) if (dopt.do_nothing && dopt.dump_inserts == 0) pg_fatal("option --on-conflict-do-nothing requires option --inserts, --rows-per-insert, or --column-inserts"); + if (dopt.do_nothing && (on_conflict_target_columns != NULL || on_conflict_update_clause != NULL)) + pg_fatal("option --on-conflict-do-nothing cannot be used with --on-conflict-target-columns and --on-conflict-do-update-clause"); + + if ((on_conflict_target_columns != NULL) ^ (on_conflict_update_clause != NULL)) + pg_fatal("option --on-conflict-target-columns and --on-conflict-update-clause must be provided together."); + /* Identify archive format to emit */ archiveFormat = parseArchiveFormat(format, &archiveMode); @@ -1308,6 +1326,8 @@ help(const char *progname) printf(_(" --no-toast-compression do not dump TOAST compression methods\n")); printf(_(" --no-unlogged-table-data do not dump unlogged table data\n")); printf(_(" --on-conflict-do-nothing add ON CONFLICT DO NOTHING to INSERT commands\n")); + printf(_(" --on-conflict-target-columns add ON CONFLICT (target-columns) DO UPDATE ... to INSERT commands. A comma-separated list of columns\n")); + printf(_(" --on-conflict-update-clause add the clause ON CONFLICT ... DO UPDATE (clause) to INSERT commands\n")); printf(_(" --quote-all-identifiers quote all identifiers, even if not key words\n")); printf(_(" --rows-per-insert=NROWS number of rows per INSERT; implies --inserts\n")); printf(_(" --section=SECTION dump named section (pre-data, data, or post-data)\n")); @@ -2681,6 +2701,8 @@ dumpTableData_insert(Archive *fout, const void *dcontext) { if (dopt->do_nothing) archputs(" ON CONFLICT DO NOTHING;\n", fout); + else if (on_conflict_target_columns != NULL && on_conflict_update_clause != NULL) + archprintf(fout, " ON CONFLICT (%s) DO UPDATE SET %s;\n", on_conflict_target_columns, on_conflict_update_clause); else archputs(";\n", fout); /* Reset the row counter */ @@ -2701,6 +2723,8 @@ dumpTableData_insert(Archive *fout, const void *dcontext) { if (dopt->do_nothing) archputs(" ON CONFLICT DO NOTHING;\n", fout); + else if (on_conflict_target_columns != NULL && on_conflict_update_clause != NULL) + archprintf(fout, " ON CONFLICT (%s) DO UPDATE SET %s;\n", on_conflict_target_columns, on_conflict_update_clause); else archputs(";\n", fout); } -- 2.39.5 (Apple Git-154)